Skip to content
Back to skills

Ghcr Coolify Pipeline

ASecurity

Write the single GitHub Actions workflow that takes a repository from pull request to production through GHCR and Coolify. Use when adding deployment to a repo, replacing a CI-only workflow, or debugging a deploy job.

  • 5 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 5, 2026
ai-agentsshellbashnextjsnodeexpressdockerdebugginggitapidatabase

Works with

  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned October 5, 2026

npx -y skills add KhaledSaeed18/dotclaude --skill ghcr-coolify-pipeline --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ghcr Coolify Pipeline?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ghcr Coolify Pipeline
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/khaledsaeed18-ghcr-coolify-pipeline/badge)](https://www.skillsdirectory.com/skills/khaledsaeed18-ghcr-coolify-pipeline)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ghcr-coolify-pipeline
description: Write the single GitHub Actions workflow that takes a repository from pull request to production through GHCR and Coolify. Use when adding deployment to a repo, replacing a CI-only workflow, or debugging a deploy job.
argument-hint: "(optional) the stack (next or express), the production URL, and the existing workflow file"
---

One workflow, five jobs: classify what changed, lint the ops layer, run the quality gates, build and smoke-test the runtime image, deploy through the Coolify API and prune the registry. Pull requests prove the image without publishing it; a push to `main` that changes something shipped publishes and deploys; "Run workflow" on `main` redeploys. Nothing in it needs a long-lived cloud key beyond one Coolify token.

## Hard rules: never break these

- **A main run is never cancelled mid-flight and deploys never overlap.** `cancel-in-progress` only on pull requests; the deploy job holds its own concurrency group.
- **Only `main` publishes and deploys.** Every push condition reads `github.ref == 'refs/heads/main' && github.event_name != 'pull_request'`.
- **The image is proven before it is pushed.** The smoke test runs the image the way production will: own user, own probe, both locales or a real database, and a timed stop.
- **Immutable tags.** `sha-<12>` is what deploys and rollbacks pin; `main` only tracks the newest build.
- **`shell: bash` with pipefail on every job that pipes curl into jq.** Otherwise an empty body reaches jq silently. And never pipe curl into `grep -q`: it closes the pipe early and fails curl; write to a file first.
- **Fail fast when configuration is missing.** The deploy job checks `COOLIFY_URL`, `COOLIFY_APP_UUID` and `COOLIFY_TOKEN` before touching anything.
- **No secret is ever printed.** Tokens only appear as `Authorization` headers; the token value is pasted into GitHub by the owner.

## Step 1: Choose the template and read the repo

| Stack | Template | Smoke test proves |
| --- | --- | --- |
| Next.js | [pipeline.nextjs.yml](./templates/pipeline.nextjs.yml) | healthy, non-root, both locales, auth redirect, headers, image optimizer, stop within 10 s |
| Express and Prisma | [pipeline.express.yml](./templates/pipeline.express.yml) | migrations against a fresh Postgres, readiness probe, non-root, stop within 10 s, plus a schema and migration guard in the quality job |

Read the existing workflow for the gates it already runs (lint, typecheck, tests, coverage, unused-code checks, build) and keep every one of them in the quality job. Check `package.json` for `packageManager` and `.nvmrc` for the Node version; the setup actions read both, so pin them if missing. Decide which Playwright or end-to-end suites stay local: anything that provisions its own database and sibling services usually does, because a free plan shares a small minutes budget across repositories.

## Step 2: Adapt the change classifier

The `changes` job decides `code` (anything the gates can judge) and `runtime` (anything that ends up in the image). Edit the two regexes to the repo's layout: source folders, config files, lockfiles, Dockerfile, entrypoint, probe and shutdown scripts count as runtime; tests and docs do not. A docs-only push then stops after one job. The anatomy of every job and the reason for each line is in [reference/pipeline-anatomy.md](./reference/pipeline-anatomy.md).

## Step 3: Fill the variables and secrets

| Name | Kind | Set by | Value |
| --- | --- | --- | --- |
| `SITE_URL` | variable | you, `gh variable set` | the URL the deploy job probes; the rehearsal domain first, the real one after cutover |
| `API_ORIGIN` or `API_BASE_URL` | variable | you | the build-time backend origin baked into the image |
| `COOLIFY_URL` | variable | you | the Coolify instance |
| `COOLIFY_APP_UUID` | variable | you | from the application's URL |
| `COOLIFY_TOKEN` | secret | owner | API token with deploy, read, write |
| `VPS_SSH_KEY`, `VPS_HOST_KEY`, `VPS_HOST` | secrets | owner | only for the Express template's pre-deploy backup over SSH |

`GITHUB_TOKEN` with `packages: write` pushes to GHCR; nothing else is needed for the registry.

## Step 4: Lint and run it

```bash
docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:1.7.7   # includes shellcheck of every run block
```

Open a pull request; the run must be green with the deploy job skipped. After the merge, watch the main run to completion and read the `conclusion` field of each job rather than the overall badge:

```bash
gh run watch <id> --exit-status; gh run view <id> --json conclusion,jobs --jq '.jobs[] | "\(.name): \(.conclusion)"'
```

The first main run's live probe fails if the domain has no DNS yet; that is expected and clears with the `live-domain-cutover` skill. The `fix-ci` skill covers a failing step; the `github-actions-pipeline` skill the general workflow rules.

Report the workflow path, the gates kept, the variables set, the secrets the owner must add, and the first run's per-job result.

Files in this skill

  • SKILL.md4.9 KB
  • reference/pipeline-anatomy.md3.7 KB
  • templates/pipeline.express.yml13.4 KB
  • templates/pipeline.nextjs.yml12.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.