Deploy instructions#80
Conversation
WalkthroughAdds a single-host deployment reference with environment templates, fail-closed proxy policy, local PostgreSQL, Caddy configuration, an idempotent installer, systemd services, and operational documentation. ChangesReference deployment stack
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (2)
deploy/install.sh (1)
71-73: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winPass build paths as arguments, not interpolated shell code.
REPO_DIRis embedded insidebash -c; a path containing'can append commands executed asficta. This is not root-level injection becausesudo -u fictadrops privileges, but it is still avoidable. Userunuseror an argument-safe command after changing directory in the parent shell.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/install.sh` around lines 71 - 73, Update the install commands around the dependency installation and package builds to avoid interpolating REPO_DIR into bash -c shell code. Change the execution flow to pass the repository and build paths as arguments using runuser or by changing directory in the parent shell before invoking pnpm, while preserving execution as FICTA_USER and the existing install/build commands.Source: Linters/SAST tools
deploy/README.md (1)
3-6: 🔒 Security & Privacy | 🔵 TrivialDo not present the egress allow-list as enforced by this stack.
Loopback bindings limit inbound exposure; they do not restrict outbound traffic from the host or Docker containers. Provide the firewall/network policy and a verification step, or clearly label this as an operator responsibility.
Also applies to: 126-131
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/README.md` around lines 3 - 6, Clarify the deployment README’s egress statement so the stack does not claim to enforce the approved model-provider allow-list. Label outbound firewall/network policy as an operator responsibility and add the required policy and verification guidance if available; preserve the existing description of loopback bindings as inbound exposure control.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@deploy/env/gateway.env.example`:
- Around line 32-40: Update the authentication defaults in the gateway
environment example and the provider selection used by provider.server.ts so
deployments cannot silently run unauthenticated. Require an explicit
isolated-demo opt-in for AUTH_PROVIDER=none, or make WorkOS the default and fail
closed when its required configuration is absent; preserve unauthenticated mode
only when deliberately selected.
In `@deploy/install.sh`:
- Around line 7-8: Update the installer flow around REPO_URL and REPO_DIR to
accept a trusted branch, tag, or commit revision instead of implicitly using the
mutable default branch. Check out that requested revision, resolve and verify
its exact commit SHA, and record the resolved SHA before the build and
deployment steps so repeated installs are reproducible.
- Around line 80-92: Update the managed PostgreSQL branch in the install flow to
stop and remove the existing ficta-postgres container before logging that the
local container is skipped. Make the cleanup safe when the container does not
exist, while preserving the current local-container startup behavior in the else
branch.
- Around line 80-91: The local PostgreSQL setup block must not regenerate
credentials when an existing local database configuration is detected. Update
the `postgres.env` handling under the local-container branch: allow generated
credentials only for a first install, but if `gateway.env` already references
local PostgreSQL and `postgres.env` is missing, log an actionable error and
abort before starting Docker Compose; preserve the existing-file path.
- Around line 122-128: Update the startup gate around the CHANGE_ME grep in the
install flow to match only active assignment lines, ignoring commented examples
in gateway.env while still blocking startup for uncommented placeholders.
Preserve the existing logging and service-restart behavior in the surrounding
conditional.
- Line 68: Update the installation flow around the chown of REPO_DIR so the
built code under /opt/ficta remains root-owned and non-writable by runtime
services. Build before applying ownership and permissions, and place any
required mutable runtime state under /var/lib/ficta instead of making the
repository writable.
- Around line 42-45: Update the Node.js installation block around the node
version check to stop piping the remote NodeSource bootstrap directly into root
Bash. Vendor the bootstrap script or download it first, verify its pinned
checksum or signature, and execute it only after validation before installing
nodejs.
In `@deploy/README.md`:
- Line 8: Update the architecture fenced code block in the deployment README to
include an appropriate language identifier, such as text, immediately after the
opening fence so it satisfies markdownlint MD040.
- Around line 31-34: Correct the alternate install command in the deployment
README to invoke the existing deploy/install.sh script when run from the
repository root, while preserving the REPO_URL environment assignment and sudo
usage.
- Around line 89-116: Update the Restart / reboot, Backup, and Restore sections
to distinguish local PostgreSQL from managed DATABASE_URL deployments. Mark the
existing ficta-postgres docker commands as local-only, and provide equivalent
managed-database operational guidance or explicitly instruct operators to use
their provider’s backup and restore procedures.
---
Nitpick comments:
In `@deploy/install.sh`:
- Around line 71-73: Update the install commands around the dependency
installation and package builds to avoid interpolating REPO_DIR into bash -c
shell code. Change the execution flow to pass the repository and build paths as
arguments using runuser or by changing directory in the parent shell before
invoking pnpm, while preserving execution as FICTA_USER and the existing
install/build commands.
In `@deploy/README.md`:
- Around line 3-6: Clarify the deployment README’s egress statement so the stack
does not claim to enforce the approved model-provider allow-list. Label outbound
firewall/network policy as an operator responsibility and add the required
policy and verification guidance if available; preserve the existing description
of loopback bindings as inbound exposure control.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f749a64e-4da9-47df-9f19-d779cfa4e5c2
📒 Files selected for processing (9)
deploy/Caddyfile.exampledeploy/README.mddeploy/docker-compose.postgres.ymldeploy/env/gateway.env.exampledeploy/env/proxy.env.exampledeploy/ficta-config.tomldeploy/install.shdeploy/systemd/ficta-gateway.servicedeploy/systemd/ficta-proxy.service
| # --- Authentication: keep AUTH_PROVIDER=none ONLY on an isolated demo network. | ||
| # --- Production-like deployments use WorkOS AuthKit (Entra ID federation). | ||
| AUTH_PROVIDER=none | ||
| # AUTH_PROVIDER=workos | ||
| # FICTA_GATEWAY_ORG_ID=org_CHANGE_ME | ||
| # WORKOS_CLIENT_ID=CHANGE_ME | ||
| # WORKOS_API_KEY=CHANGE_ME | ||
| # WORKOS_REDIRECT_URI=https://gateway.example.internal/api/auth/callback | ||
| # WORKOS_COOKIE_PASSWORD=CHANGE_ME |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Do not ship an unauthenticated default for an exposed gateway.
AUTH_PROVIDER=none is the effective default; apps/gateway/src/lib/auth/provider.server.ts Lines 42-55 selects WorkOS only when the value is exactly workos. The warning comment is not an enforcement boundary, so a copy-paste deployment can expose the Gateway without authentication. Require an explicit isolated-demo opt-in, or default to WorkOS and fail closed when its configuration is missing.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/env/gateway.env.example` around lines 32 - 40, Update the
authentication defaults in the gateway environment example and the provider
selection used by provider.server.ts so deployments cannot silently run
unauthenticated. Require an explicit isolated-demo opt-in for
AUTH_PROVIDER=none, or make WorkOS the default and fail closed when its required
configuration is absent; preserve unauthenticated mode only when deliberately
selected.
| REPO_URL="${REPO_URL:-https://github.com/SerovaAI/ficta.git}" | ||
| REPO_DIR="${REPO_DIR:-/opt/ficta}" |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Pin the revision that this installer builds.
Fresh installs clone the mutable default branch from REPO_URL, then build and deploy that result. This makes deployments non-reproducible and means the documented checkout invocation can deploy a different remote state than the checkout containing the installer. Accept a trusted branch/tag or commit, verify the resolved SHA, and record it before building.
Also applies to: 62-64
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/install.sh` around lines 7 - 8, Update the installer flow around
REPO_URL and REPO_DIR to accept a trusted branch, tag, or commit revision
instead of implicitly using the mutable default branch. Check out that requested
revision, resolve and verify its exact commit SHA, and record the resolved SHA
before the build and deployment steps so repeated installs are reproducible.
| if ! command -v node >/dev/null || [ "$(node -p 'process.versions.node.split(".")[0]')" -lt 20 ]; then | ||
| log "Node ${NODE_MAJOR}.x (NodeSource)" | ||
| curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash - | ||
| apt-get install -y -q nodejs |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -e
printf '--- deploy/install.sh ---\n'
cat -n deploy/install.sh | sed -n '1,140p'
printf '\n--- NodeSource references ---\n'
rg -n "nodesource|setup_\$\{NODE_MAJOR\}|setup_[0-9]+\.x|NODE_MAJOR" deploy . -g '!**/node_modules/**'Repository: SerovaAI/ficta
Length of output: 243
🏁 Script executed:
#!/bin/bash
set -e
echo '--- deploy/install.sh ---'
cat -n deploy/install.sh | sed -n '1,140p'
echo
echo '--- NodeSource references ---'
rg -n "nodesource|setup_\$\{NODE_MAJOR\}|setup_[0-9]+\.x|NODE_MAJOR" deploy . -g '!**/node_modules/**'Repository: SerovaAI/ficta
Length of output: 7430
🌐 Web query:
NodeSource Debian Ubuntu setup script signed repository installation documentation setup_22.x curl bash
💡 Result:
To install Node.js 22.x on Debian or Ubuntu systems using the official NodeSource repository, use the following procedure. This method configures the signed NodeSource repository automatically on your system [1][2]. 1. Ensure required dependencies are installed: sudo apt update sudo apt install -y curl gnupg [2] 2. Run the NodeSource setup script: This script downloads, adds the NodeSource GPG signing key to your keyring, and configures the APT repository [1][2]. For Ubuntu: curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - [3][2] For Debian (as root): curl -fsSL https://deb.nodesource.com/setup_22.x | bash - [4][5] 3. Install Node.js: After the script completes, install the Node.js package: sudo apt install -y nodejs [4][2] 4. Verify the installation: node -v npm -v [4][2] The NodeSource setup script (setup_22.x) is designed to handle repository configuration, including the installation of the GPG key to /usr/share/keyrings/nodesource.gpg to ensure signed package verification [1]. It is recommended to use the -E flag with sudo when executing the script to preserve environment variables, ensuring the script runs correctly under the user's shell environment [3][4].
Citations:
- 1: https://github.com/nodesource/distributions/blob/master/scripts/deb/setup_22.x
- 2: https://computingforgeeks.com/install-nodejs-ubuntu-debian/
- 3: https://downloads.nodesource.com/
- 4: https://github.com/nodesource/distributions/blob/master/DEV_README.md
- 5: https://raw.githubusercontent.com/nodesource/distributions/master/DEV_README.md
Avoid piping the NodeSource bootstrap script into root Bash. It still runs mutable remote code as root before any package verification; vendor the bootstrap script or pin and checksum/signature-check it before execution.
🧰 Tools
🪛 ast-grep (0.44.1)
[error] 43-43: Remote content fetched with curl/wget is piped directly into a shell interpreter, so any server compromise, MITM, or tampered mirror results in arbitrary code execution on this host. Download the script to a file first, verify its integrity (checksum/signature) and inspect it, then run the verified local copy.
Context: curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash -
Note: [CWE-494] Download of Code Without Integrity Check.
(curl-pipe-to-shell-bash)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/install.sh` around lines 42 - 45, Update the Node.js installation
block around the node version check to stop piping the remote NodeSource
bootstrap directly into root Bash. Vendor the bootstrap script or download it
first, verify its pinned checksum or signature, and execute it only after
validation before installing nodejs.
Source: Linters/SAST tools
| else | ||
| log "Checkout exists at ${REPO_DIR} (not pulling automatically — run git pull to upgrade)" | ||
| fi | ||
| chown -R "$FICTA_USER:$FICTA_USER" "$REPO_DIR" |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the file and surrounding lines first
wc -l deploy/install.sh
sed -n '1,140p' deploy/install.sh
# Search for related ownership/runtime paths and systemd service definitions
rg -n --hidden --glob '!**/.git/**' 'FICTA_USER|REPO_DIR|/opt/ficta|/var/lib/ficta|chown -R|systemd|User=' deployRepository: SerovaAI/ficta
Length of output: 10490
🏁 Script executed:
#!/bin/bash
set -euo pipefail
wc -l deploy/systemd/ficta-proxy.service deploy/systemd/ficta-gateway.service
sed -n '1,120p' deploy/systemd/ficta-proxy.service
printf '\n---\n'
sed -n '1,120p' deploy/systemd/ficta-gateway.service
printf '\n---\n'
# Show any additional sandboxing/write controls in all systemd unit files
rg -n --hidden --glob '!**/.git/**' '^(ProtectSystem|ProtectHome|ReadOnlyPaths|ReadWritePaths|InaccessiblePaths|NoNewPrivileges|PrivateTmp|User=|Group=|WorkingDirectory=|ExecStart=)' deploy/systemdRepository: SerovaAI/ficta
Length of output: 2586
🌐 Web query:
systemd ProtectSystem=full semantics /opt writable working directory
💡 Result:
When ProtectSystem=full is enabled in a systemd unit, it mounts /usr/, /boot/, /efi/, and /etc/ as read-only for the service [1][2]. Because /opt/ is not included in the list of directories protected by ProtectSystem=full, it remains accessible according to the default filesystem permissions [1][3]. If you need a service to write to a specific directory within /opt/ while using ProtectSystem=full, you have two primary methods to ensure write access: 1. ReadWritePaths=: You can explicitly allow-list the specific directory in /opt/ by adding it to the ReadWritePaths= directive in your unit file [1][2]. For example: ReadWritePaths=/opt/your-app/data 2. Directory-specific directives: If you are configuring a service to manage its own state or logs, you should ideally use the dedicated systemd directory directives, such as StateDirectory=, LogsDirectory=, or CacheDirectory= [1][3]. When these are used, systemd automatically creates the necessary directories in /var/lib/, /var/log/, or /var/cache/ (respectively) and ensures they are writable by the service, even if ProtectSystem= is active [1]. If your application strictly requires files to reside within /opt/ and you prefer not to use ReadWritePaths=, you must ensure the filesystem permissions outside of the systemd namespace already permit the service user to write to that location [4]. However, using ReadWritePaths= is the recommended approach for maintaining the security benefits of systemd sandboxing while selectively permitting necessary write access [1][2].
Citations:
- 1: https://freedesktop.org/software/systemd/man/latest/systemd.exec.html
- 2: https://man.archlinux.org/man/systemd.exec.5.en
- 3: https://manpages.debian.org/unstable/systemd/systemd.exec.5.en.html
- 4: https://manpages.ubuntu.com/manpages/jammy/man5/systemd.exec.5.html
Keep /opt/ficta out of the runtime write path.
chown -R "$FICTA_USER:$FICTA_USER" "$REPO_DIR" makes the code tree writable by the ficta services, so a runtime compromise can persist changes across restarts and bypass the intended ReadWritePaths=/var/lib/ficta boundary. Build first, then make /opt/ficta root-owned/read-only and keep mutable state under /var/lib/ficta.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/install.sh` at line 68, Update the installation flow around the chown
of REPO_DIR so the built code under /opt/ficta remains root-owned and
non-writable by runtime services. Build before applying ownership and
permissions, and place any required mutable runtime state under /var/lib/ficta
instead of making the repository writable.
| if grep -qs '^DATABASE_URL=postgres' "$ENV_DIR/gateway.env" 2>/dev/null && | ||
| ! grep -qs '^DATABASE_URL=postgres://ficta:.*@127.0.0.1' "$ENV_DIR/gateway.env" 2>/dev/null; then | ||
| log "External DATABASE_URL configured — skipping local Postgres container" | ||
| else | ||
| log "Local Postgres container (loopback, persistent volume)" | ||
| if [ ! -f "$ENV_DIR/postgres.env" ]; then | ||
| install -d -m 0750 "$ENV_DIR" | ||
| printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 24)" > "$ENV_DIR/postgres.env" | ||
| chmod 600 "$ENV_DIR/postgres.env" | ||
| fi | ||
| docker compose -f "$REPO_DIR/deploy/docker-compose.postgres.yml" \ | ||
| --env-file "$ENV_DIR/postgres.env" up -d --wait |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Fail instead of regenerating credentials for an existing local database.
If an existing gateway.env points to local PostgreSQL but postgres.env is missing, Lines 85-88 generate a new password. Existing gateway.env is not rewritten, and an existing database volume retains its original password, so the Gateway cannot connect. Only generate credentials on first install; otherwise abort and require credential recovery or explicit rotation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/install.sh` around lines 80 - 91, The local PostgreSQL setup block
must not regenerate credentials when an existing local database configuration is
detected. Update the `postgres.env` handling under the local-container branch:
allow generated credentials only for a first install, but if `gateway.env`
already references local PostgreSQL and `postgres.env` is missing, log an
actionable error and abort before starting Docker Compose; preserve the
existing-file path.
| if grep -qs '^DATABASE_URL=postgres' "$ENV_DIR/gateway.env" 2>/dev/null && | ||
| ! grep -qs '^DATABASE_URL=postgres://ficta:.*@127.0.0.1' "$ENV_DIR/gateway.env" 2>/dev/null; then | ||
| log "External DATABASE_URL configured — skipping local Postgres container" | ||
| else | ||
| log "Local Postgres container (loopback, persistent volume)" | ||
| if [ ! -f "$ENV_DIR/postgres.env" ]; then | ||
| install -d -m 0750 "$ENV_DIR" | ||
| printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 24)" > "$ENV_DIR/postgres.env" | ||
| chmod 600 "$ENV_DIR/postgres.env" | ||
| fi | ||
| docker compose -f "$REPO_DIR/deploy/docker-compose.postgres.yml" \ | ||
| --env-file "$ENV_DIR/postgres.env" up -d --wait | ||
| fi |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Remove the local container when switching to managed PostgreSQL.
The managed-database branch only skips starting PostgreSQL; it never stops or removes an existing ficta-postgres container. After an operator changes DATABASE_URL to a managed instance, the old local database continues running with restart: unless-stopped, retaining unnecessary sensitive state.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/install.sh` around lines 80 - 92, Update the managed PostgreSQL branch
in the install flow to stop and remove the existing ficta-postgres container
before logging that the local container is skipped. Make the cleanup safe when
the container does not exist, while preserving the current local-container
startup behavior in the else branch.
| if grep -q 'CHANGE_ME' "$ENV_DIR/gateway.env"; then | ||
| log "NOT starting services: $ENV_DIR/gateway.env still contains CHANGE_ME placeholders." | ||
| echo " Edit it, then: systemctl restart ficta-proxy ficta-gateway" | ||
| else | ||
| systemctl restart ficta-proxy ficta-gateway | ||
| log "Services started." | ||
| fi |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Ignore commented CHANGE_ME examples when gating startup.
The gateway template contains commented WorkOS placeholders at Lines 36-40, so grep -q 'CHANGE_ME' remains true even when AUTH_PROVIDER=none and all active required values are configured. Services will therefore never start without manually deleting commented examples. Match only active assignments.
Proposed fix
-if grep -q 'CHANGE_ME' "$ENV_DIR/gateway.env"; then
+if grep -Eq '^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*=.*CHANGE_ME' "$ENV_DIR/gateway.env"; then📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if grep -q 'CHANGE_ME' "$ENV_DIR/gateway.env"; then | |
| log "NOT starting services: $ENV_DIR/gateway.env still contains CHANGE_ME placeholders." | |
| echo " Edit it, then: systemctl restart ficta-proxy ficta-gateway" | |
| else | |
| systemctl restart ficta-proxy ficta-gateway | |
| log "Services started." | |
| fi | |
| if grep -Eq '^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*=.*CHANGE_ME' "$ENV_DIR/gateway.env"; then | |
| log "NOT starting services: $ENV_DIR/gateway.env still contains CHANGE_ME placeholders." | |
| echo " Edit it, then: systemctl restart ficta-proxy ficta-gateway" | |
| else | |
| systemctl restart ficta-proxy ficta-gateway | |
| log "Services started." | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/install.sh` around lines 122 - 128, Update the startup gate around the
CHANGE_ME grep in the install flow to match only active assignment lines,
ignoring commented examples in gateway.env while still blocking startup for
uncommented placeholders. Preserve the existing logging and service-restart
behavior in the surrounding conditional.
| [`apps/gateway/docs/poc-configuration.md`](../apps/gateway/docs/poc-configuration.md). One Linux | ||
| host runs the whole stack; the only external egress is the approved model-provider endpoint. | ||
|
|
||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Specify the fenced block language.
The architecture block triggers markdownlint MD040. Use text or another appropriate language identifier.
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 8-8: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/README.md` at line 8, Update the architecture fenced code block in the
deployment README to include an appropriate language identifier, such as text,
immediately after the opening fence so it satisfies markdownlint MD040.
Source: Linters/SAST tools
| ```sh | ||
| sudo ./deploy/install.sh # from a checkout, or: | ||
| sudo REPO_URL=https://github.com/SerovaAI/ficta.git ./install.sh | ||
| ``` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Fix the alternate install command path.
From the repository root, ./install.sh does not exist; the script is ./deploy/install.sh, so the documented alternative command fails.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/README.md` around lines 31 - 34, Correct the alternate install command
in the deployment README to invoke the existing deploy/install.sh script when
run from the repository root, while preserving the REPO_URL environment
assignment and sudo usage.
| **Restart / reboot** | ||
|
|
||
| ```sh | ||
| sudo systemctl restart ficta-proxy ficta-gateway # services | ||
| sudo reboot # full host: everything must come back on its own | ||
| systemctl status ficta-proxy ficta-gateway # after reboot | ||
| docker ps # sidecars + postgres running | ||
| ``` | ||
|
|
||
| **Backup** (contains sensitive data — restored transcripts and the surrogate mapping; store per | ||
| the firm's policy) | ||
|
|
||
| ```sh | ||
| docker exec ficta-postgres pg_dump -U ficta ficta | gzip > ficta-db-$(date +%F).sql.gz | ||
| sudo tar czf ficta-config-$(date +%F).tgz /etc/ficta /var/lib/ficta/.ficta \ | ||
| /var/lib/ficta/protected-registry.json | ||
| ``` | ||
|
|
||
| `FICTA_GATEWAY_KEY_ENCRYPTION_SECRET` must be escrowed separately from the database backup — | ||
| backups contain encrypted workspace provider keys and are useless without it. | ||
|
|
||
| **Restore** (onto a host prepared by `install.sh`) | ||
|
|
||
| ```sh | ||
| sudo systemctl stop ficta-gateway ficta-proxy | ||
| gunzip -c ficta-db-<date>.sql.gz | docker exec -i ficta-postgres psql -U ficta ficta | ||
| sudo tar xzf ficta-config-<date>.tgz -C / | ||
| sudo systemctl start ficta-proxy ficta-gateway |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Make database runbook steps conditional on managed PostgreSQL.
The deployment supports managed DATABASE_URL, but the restart status, backup, and restore examples hard-code ficta-postgres. In managed mode that container is intentionally absent, so these operational instructions fail. Provide managed-database commands or clearly mark these steps as local-PostgreSQL-only.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/README.md` around lines 89 - 116, Update the Restart / reboot, Backup,
and Restore sections to distinguish local PostgreSQL from managed DATABASE_URL
deployments. Mark the existing ficta-postgres docker commands as local-only, and
provide equivalent managed-database operational guidance or explicitly instruct
operators to use their provider’s backup and restore procedures.
Summary by CodeRabbit