Skip to main content

Deploying

diagram

Prerequisites

The following tools must be installed on the VPS:

ToolWhy needed
gitRepo clone/pull
docker + Docker Compose pluginContainer runtime and orchestration
ansibleEnvironment variable generation via playbook.yml

These are installed automatically by the Ansible provision playbook.

Automatic deploy (CI/CD)

Every push to main triggers the Deploy workflow. It:

  1. SSHes into the VPS as root.
  2. Runs git pull --rebase.
  3. Checks for unhealthy containers and restarts them if necessary.
  4. Identifies changed directories to perform targeted upgrades.
  5. Deploys services in dependency order using the Zero-Downtime HA orchestrator:
    • For all stateless applications, it runs bash scripts/deploy-app.sh <appname>.
    • Stateful infrastructure (postgres and traefik) is deployed using standard in-place upgrades.

Manual deploy

To deploy an app manually on the VPS, use the HA deployment scripts or Ansible tags. Never run raw docker compose up directly on the VPS for stateless apps, as it will break the zero-downtime routing aliases.

cd /opt/vps-apps

# Pull latest code
git pull --rebase

# Option A: Run the Ansible playbook locally (Best practice)
# Sourced from vault, this regenerates all .env files and triggers the HA wrapper deploys
ansible-playbook ansible/playbook.yml --tags deploy,<appname> --vault-id @prompt

# Option B: Run the HA Orchestrator directly on the VPS
# For generic stateless apps:
bash scripts/deploy-app.sh /opt/vps-apps/<appname>

# For custom apps (admin or devex):
cd admin && bash deploy.sh
cd devex && bash deploy.sh

[!TIP] Raw docker compose up -d --build is reserved strictly for local testing during development, not production. For full architectural details of the zero-downtime mechanism, see the High Availability Guide.

Syncing secrets from VPS back to Repo

If a service generates a secret at runtime (e.g. an API token), the provision.yml workflow automatically syncs it back to ansible/secrets.yml.

To do this manually:

  1. Update the .env file on the VPS.
  2. Run the Sync secrets logic from provision.yml or use scripts/sync-vault.py.

Adding/Updating secrets from Local

Use scripts/vault-set.sh to safely update secrets in ansible/secrets.yml from a local .env file:

export ANSIBLE_VAULT_PASSWORD=your_password
./scripts/vault-set.sh path/to/.env

Checking logs

docker compose -f <appname>/docker-compose.yml logs -f