Site ↗
Documentation sections
Operations · 0.8.1

Deploying a Docker image archive from a Mac

Build the application on a Mac and send prepared images to the VPS over SSH, without a registry.

On this page

Docker builds the application on your Mac. The controller sends prepared images to the VPS over SSH and starts them. No source code is needed on the VPS. This guide uses one VPS, local images, and disabled backups.

1. Create a profile in Generator UI

Enable Docker and Production deployment in Deployment, and choose CI provider → None. In Deployment environments, create profile production with Single server preset. Select Image delivery → Transfer image archives over SSH, and enter your domains, TLS contact email, and Runtime directory. Choose None for Backup destination; working images use the project's Local files setting.

For field details, see profile preparation. Click Save deployment settings, then Generate. Settings appear in deploy/generated/environments/production.json; leave the empty adjacent custom file in deploy/custom/environments/ unchanged for now. Do not copy JSON into deploy/environments/.

2. Prepare VPS and Mac

Complete server and domain preparation. Then open a Mac terminal in the generated example-project root and follow all environment and SSH preparation steps.

Set Backend SSH target in production to deploy@203.0.113.10 with your IP. Runtime directory is on the VPS, rather than the Mac. Save and run Generate. Local media and disabled backup need no separate secrets file.

For two VPS machines, create a Separate frontend / backend preset profile. Prepare both machines, fill both SSH targets, and create the same Runtime directory on each. Point admin DNS at frontend and API at backend. Release commands below are unchanged.

3. Perform first startup

On the Mac, from the example-project root, with Docker Desktop running. For a new terminal, first set paths to prepared SSH files:

export DEPLOY_SSH_KEY_FILE="$HOME/.config/admingen/production/id_ed25519"
export DEPLOY_KNOWN_HOSTS_FILE="$HOME/.config/admingen/production/known_hosts"
bash ./deploy/control build --env production --output release-001.json
bash ./deploy/control provision --env production --release release-001.json --confirm production
bash ./deploy/control deploy --env production --release release-001.json --confirm production
bash ./deploy/control status --env production --json

Run commands individually, proceeding only after success. Build builds the version; provision checks the environment and prepares secrets, PostgreSQL, and HTTPS; deploy applies migrations and starts the application. After provision, a maintenance page may still appear. Successful deploy ends with status=complete; status must show a recorded current release and successful readiness.

Build creates release-001.json with an adjacent *.images.tar containing backend, admin, and service component images. Do not rename the archive; keep it beside JSON. The controller checks the archive and transfers it over SSH. The verified VPS copy is preserved in <root>/image-archives/.

This is an application archive, rather than a database or user-image backup. A separate registry is unnecessary, but the Mac downloads base images and dependencies during build.

For the next section, open a separate VPS terminal using configured SSH:

ssh -i "$DEPLOY_SSH_KEY_FILE" -o IdentitiesOnly=yes \
  -o "UserKnownHostsFile=$DEPLOY_KNOWN_HOSTS_FILE" deploy@203.0.113.10

Use the backend VPS IP.

Create the first administrator

For a new project without data, run on the VPS as deploy or root:

docker ps --filter label=com.docker.compose.service=backend

Take the name from NAMES and replace ИМЯ_BACKEND_КОНТЕЙНЕРА:

docker exec -it ИМЯ_BACKEND_КОНТЕЙНЕРА \
  admin bootstrap-superadmin --if-needed --login owner

Enter and confirm a password of 12–128 UTF-8 bytes; input is hidden. Open https://admin.example.com with your domain and sign in as owner. If a superadministrator exists, this does not replace it or reset its password.

To transfer a populated development database, after successful first deploy follow data transfer into a Docker environment. Import replaces the new database, including the created account; afterward use accounts from the transferred database.

Update the application

Return to the Mac terminal in the example-project root. Prepare new source: run git pull --ff-only for Git changes. Export the two SSH paths above in a new terminal. Then:

bash ./deploy/control build --env production --output release-002.json
bash ./deploy/control deploy --env production --release release-002.json --confirm production
bash ./deploy/control status --env production --json

Each build uses new output; do not overwrite a previous release. No repeat provision is needed. Wait for status=complete and the new current release in status. Preserve JSON and archives of versions you may need to return to.

Backup is disabled in this guide. Configure backups separately for data; use S3 to keep working images outside the VPS.

If release stops

From the same place where you ran control:

bash ./deploy/control status --env production --json
bash ./deploy/control logs --env production --service backend

Preserve the error message and operation ID. Continue with operation recovery. Do not delete data or state to retry. First deploy failure after migrations also requires operation investigation, even without a recorded current release.