Skip to content

Upgrades, backups and scaling

View as Markdown

All commands on this page run from the installation directory (/opt/infraward in the installation guide).

  1. Read the release notes of the new version and back up first.

  2. Update the deployment files from the new release (compose.yml, compose.openbao.yml, init.sh, openbao/config.hcl). Keep your .env, data/ and secrets/. Compare .env.example with your .env and add any new variables.

  3. Set the new version in .env:

    .env
    INFRAWARD_VERSION=v0.6.0
  4. Run init.sh again. It creates any key, secret, AppRole or directory that the new version needs and leaves everything else as it is. With OpenBao it needs secrets/openbao/init.json: if you moved it off the server, put it back for this step and remove it afterwards.

    Terminal window
    ./init.sh
  5. Pull the images and recreate the containers:

    Terminal window
    docker compose pull
    docker compose up -d

    The API applies database migrations when it starts. The worker and the gateway wait until the API is healthy.

  6. Check docker compose ps and sign in.

Rolling back to an earlier version after its migrations have run is not supported. Restore the backup taken before the upgrade instead.

What Where How often Notes
Database data/postgres Daily Use a logical dump (below) rather than copying files of a running database.
OpenBao storage data/openbao Daily Secrets, SSH CA and AppRoles. Stop OpenBao or take a filesystem snapshot for a consistent copy.
Keys and secrets secrets/ After init.sh and after each rotation Separately from the database backup.
Configuration .env, compose*.yml, openbao/config.hcl After each change
Redis data/redis Optional Only queues and locks. Pending jobs are rescheduled.
Trivy cache data/worker Never Downloaded again on start.

Dump the database:

Terminal window
docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' > infraward-$(date +%F).dump
  1. Install the same InfraWard version on the new host following the installation guide, but do not run init.sh or start the stack yet.

  2. Copy .env, secrets/ and data/openbao from the backup.

  3. Run ./init.sh. It creates data/postgres, data/redis and data/worker and fixes ownership of everything.

  4. Start PostgreSQL alone and load the dump:

    Terminal window
    docker compose up -d postgres
    docker compose exec -T postgres sh -c 'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists' < infraward-2026-10-27.dump
  5. Start everything with docker compose up -d.

Run several worker replicas to scan more images in parallel:

Terminal window
docker compose up -d --scale worker=3

Or set WORKER_REPLICAS=3 in .env so the number survives the next up. Replicas:

  • share the queues without duplicating jobs;
  • respect per-server limits across all replicas: HOST_MAX_JOBS (2) jobs at a time against one server, of which HOST_MAX_SCAN_JOBS (1) scans; a CT counts against its Proxmox node;
  • share data/worker, so the Trivy database is downloaded once;
  • elect one leader through Redis to run scheduled tasks. Actividad shows the connected replicas and which one runs each job.

When a replica stops, it waits up to 90 seconds (WORKER_SHUTDOWN_GRACE) for running jobs and returns the rest to the queue. Another replica picks them up.

Per-replica concurrency is set with WORKER_CONCURRENCY, COLLECT_CONCURRENCY, DISCOVERY_CONCURRENCY, IMAGE_SCAN_CONCURRENCY and the other variables in Configuration variables. Scanning is memory-hungry: add memory before raising IMAGE_SCAN_CONCURRENCY.

Credential How to rotate
OpenBao AppRole secret_id (app, vault and terminal) ./init.sh --rotate-secret-id, then docker compose restart api worker gateway.
Administrator password Ajustes → Perfil → Seguridad. Closes your other sessions.
SSH CA keys After changing the CA issuer in OpenBao (infraward-ssh/), InfraWard flags every server whose installed CA keys are out of date. Use Regenerar el comando on each one and run the new command.
Cloudflare token Ajustes → Conectores → Reemplazar token.
API tokens Revoke and create new ones in Ajustes → Tokens de API.

The example deployment unseals OpenBao automatically with secrets/openbao/unseal.key, which lives on the same host as the data. Anyone who can read the disk can read the secrets. For stronger guarantees, edit openbao/config.hcl:

  • Manual unseal: remove the seal "static" block. After every restart, run docker compose exec openbao bao operator unseal with the unseal key.
  • External auto-unseal: replace the block with a cloud KMS or the transit engine of another OpenBao or Vault.

OpenBao listens without TLS on the internal network only. To use an external OpenBao instead, remove compose.openbao.yml from COMPOSE_FILE, configure the AppRoles and the SSH engine as init.sh does, and set OPENBAO_ADDR and the AppRole variables for api and worker in an override file.

Early deployments stored data in named volumes (postgres-data, redis-data, worker-data, openbao-data). To move to data/:

Terminal window
docker compose down
./init.sh
for v in postgres redis openbao; do
docker run --rm -v infraward-stack_$v-data:/from:ro -v "$PWD/data/$v:/to" \
docker.io/library/alpine sh -c 'cp -a /from/. /to/'
done
./init.sh
docker compose up -d

The second init.sh fixes ownership after the copy. Check that everything works before deleting the old volumes with docker volume rm. The Trivy cache does not need copying.