ghcr-coolify-pipeline
Skill5 starsChanged 4 months agoMITView on GitHub
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.
- Reads credentials
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 12
Only
mainpublishes and deploys: Every push condition reads github.ref == 'refs/heads/main' && github.event_name != 'pull_request'.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
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-progressonly on pull requests; the deploy job holds its own concurrency group. - Only
mainpublishes and deploys. Every push condition readsgithub.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;mainonly tracks the newest build. shell: bashwith pipefail on every job that pipes curl into jq. Otherwise an empty body reaches jq silently. And never pipe curl intogrep -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_UUIDandCOOLIFY_TOKENbefore touching anything. - No secret is ever printed. Tokens only appear as
Authorizationheaders; 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 | healthy, non-root, both locales, auth redirect, headers, image optimizer, stop within 10 s |
| Express and Prisma | 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.
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
docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:1.7.7 # includes shellcheck of every run blockOpen 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:
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.
In this repository89 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- site/llms-full.txtllms.txt
- site/llms.txtllms.txt
- improveSkill
- academic-writingSkill
- benchmark-reportingSkill
- bibtex-managerSkill
- citation-graphSkill
- citation-verifierSkill
- design-science-methodologySkill
- docx-thesisSkill
- experiment-reproducibilitySkill
- latex-toolkitSkill
- literature-searchSkill
- lit-review-synthesisSkill
- paper-readerSkill
- proofread-academicSkill
- research-figuresSkill
- research-methodologySkill
- research-questionSkill
- statistics-advisorSkill
- supervisor-updateSkill
- systematic-reviewSkill
- thesis-proposalSkill
- coolify-image-appSkill
- coolify-vps-baselineSkill
- deploy-verificationSkill
- express-prisma-coolify-imageSkill
- live-domain-cutoverSkill
- nextjs-coolify-imageSkill
- proxy-client-addressSkill
- vps-ops-toolkitSkill
- adr-writingSkill
- openapi-specSkill
- readme-writingSkill
- technical-writingSkill
- adversarial-reviewerSkill
- api-design-reviewSkill
- code-review-responseSkill
- create-agentSkill
- create-commandSkill
- create-hookSkill
- create-skillSkill
- db-migration-safetySkill
- dependency-upgradeSkill
- dockerfile-best-practicesSkill
- error-handling-patternsSkill
- executing-plansSkill
- explain-codebaseSkill
- fix-ciSkill
- github-actions-pipelineSkill
- grill-with-docsSkill
- incident-postmortemSkill
- logging-and-observabilitySkill
- parallel-agentsSkill
- performance-optimizationSkill
- refactoring-recipesSkill
- solid-principlesSkill
- systematic-debuggingSkill
- test-driven-developmentSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

