Skip to main content

GitHub Container Registry → Coolify Deploy Setup

Switches from Coolify/Nixpacks on-droplet builds to GitHub Actions → ghcr.io → Coolify pull. The droplet no longer builds the image; it only runs the pre-built container.


Overview

Push to master
└─► GitHub Actions (ubuntu-latest)
└─► docker build (multi-stage, Node 22 Alpine)
└─► push ghcr.io/ioncernenchii/itinera:latest + :sha-<short>
└─► curl webhook → Coolify redeploys

Step 1 — Add GitHub Repository Secrets

GitHub → ioncernenchii/itinera → Settings → Secrets and variables → Actions → New repository secret

Secret nameValue
NEXT_PUBLIC_GOOGLE_MAPS_API_KEYGoogle Maps API key (baked in at build time)
COOLIFY_WEBHOOK_URLCoolify deploy webhook URL (see Step 3a)
COOLIFY_WEBHOOK_TOKENCoolify API token with deploy permission (see Step 3a)

GITHUB_TOKEN is automatically provided — no manual secret needed for ghcr.io push.


Step 2 — Verify ghcr.io Package Visibility

After the first successful workflow run, a package named itinera will appear at https://github.com/ioncernenchii?tab=packages.

  1. Click the package → Package settings
  2. Under Danger Zone, set visibility to Private
  3. Under Manage Actions access, add the ioncernenchii/itinera repository with Write access

Step 3 — Configure Coolify Application

3a. Get the Coolify deploy webhook and API token

  1. Open Coolify UI → select the Itinera application → Webhooks tab
  2. Copy the Deploy Webhook URLCOOLIFY_WEBHOOK_URL GitHub secret
  3. Coolify left sidebar → Keys & TokensAPI Tokens → create token:
    • Description: github-actions-deploy
    • Permission: deploy only
    • Copy token → COOLIFY_WEBHOOK_TOKEN GitHub secret

3b. Confirm Coolify build pack and Docker Registry

In Coolify → Itinera application → General tab:

  • Build Pack: Dockerfile (leave as-is — Coolify uses the Docker Registry image below)
  • Docker Registry → Docker Image: ghcr.io/ioncernenchii/itinera:latest
  • Docker Image Tag: leave empty (Coolify uses the commit SHA tag automatically)

There is no registry credentials UI in Coolify v4 for private ghcr.io images. Authentication is handled directly on the host (see Step 4).

3c. Environment variables

Verify these are set in Coolify → Environment Variables tab (not baked into the image):

DATABASE_URL=...
NEXTAUTH_SECRET=...
NEXTAUTH_URL=https://app.getitinera.com
SENTRY_DSN=...
TELEGRAM_BOT_TOKEN=...
TELEGRAM_CHAT_ID=...

NEXT_PUBLIC_GOOGLE_MAPS_API_KEY is baked in at build time via the GitHub Actions secret — do not add it here.


Step 4 — Authenticate Docker on the Droplet

Coolify v4 has no UI for private registry credentials — it uses the host Docker daemon's stored credentials.

SSH into the droplet and run:

echo <YOUR_CLASSIC_PAT> | docker login ghcr.io -u ioncernenchii --password-stdin

Create the classic PAT:

  1. GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token (classic)

    Fine-grained tokens do not support GitHub Packages — use classic.

  2. Note: coolify-ghcr-pull
  3. Expiration: 1 year (set a calendar reminder to rotate)
  4. Scope: read:packages only

Credentials are saved to /root/.docker/config.json and persist across reboots. Rotate annually — when the PAT expires, re-run the docker login command with the new token.


Step 5 — First Deploy

  1. Push to master (or re-run the last workflow manually in GitHub → Actions)
  2. Watch GitHub → Actions → Build & Push Docker Image
  3. After it succeeds, Coolify receives the webhook and redeploys automatically
  4. Verify at https://app.getitinera.com

Cleanup Notes

Nixpacks config

No nixpacks.toml exists in this repo — no action needed.

/swapfile

The droplet no longer builds Docker images (7GB GitHub Actions runners handle that now). Keep /swapfile — the running Node.js process and PostgreSQL still benefit from swap headroom.

To check current swap:

swapon --show
free -h

Old build cache on droplet

If Coolify left stale build layers:

docker builder prune --filter until=24h

Rollback

To roll back to a previous image:

  1. In Coolify → General tab → Docker Image Tag → enter sha-<previous-short-sha>
  2. Click Redeploy
  3. After confirming the rollback, clear the tag field to resume tracking latest

SHA tags are retained in ghcr.io for every push. Find them at: https://github.com/ioncernenchii/itinera/pkgs/container/itinera