agentsclimarketplace

Coolify cicd

Skill RadOrigin-LLC/RAD-Claude-Skills/plugins/rad-coolify-orchestrator/skills/coolify-cicd

This skill should be used when setting up CI/CD pipelines for Coolify, using the Coolify REST API, triggering deployments from GitHub Actions, configuring webhooks, deploying from GHCR or other registries, setting up PR preview environments, configuring branch-specific deployments, using the Coolify deploy webhook, integrating GitLab CI with Coolify, or managing API tokens. Trigger when: "Coolify CI/CD", "Coolify API", "deploy to Coolify from GitHub Actions", "Coolify webhook", "Coolify deploy trigger", "Coolify API token", "GHCR deploy Coolify", "Coolify PR preview", "Coolify branch deploy", "action-coolify", "GitLab CI Coolify", "Coolify REST API", "automate Coolify deployment".From its SKILL.md

Install
npx -y skills add RadOrigin-LLC/RAD-Claude-Skills --skill coolify-cicd

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

12.1 KB, ~2.9k tokens by cl100k_base, as published. Nobody here has run it

Coolify CI/CD

Covers the Coolify REST API, GitHub Actions integration, GHCR workflows, webhooks, and PR preview environments for Coolify v4 self-hosted.

Self-Hosted Only: All content assumes self-hosted Coolify v4.x. API endpoints and webhook behavior may differ on Coolify Cloud.

Deployment Trigger Methods

MethodBest ForComplexity
Git Push (Auto-deploy)Simple projects, Coolify builds from sourceLowest
Deploy Webhook URLQuick integration, no API token neededLow
REST APIFull control, multi-step pipelinesMedium
GitHub Actions + APIEnterprise CI/CD with tests before deployMedium
GHCR + APIBuild externally, deploy pre-built imagesHigher

Choose based on your build pipeline: if Coolify builds from source, use Git Push or Webhook. If CI builds the image, use GHCR + API. If neither fits, use the REST API directly for full control.

REST API

Authentication

All API requests require a Bearer token:

curl -H "Authorization: Bearer <YOUR_API_TOKEN>" \
     "https://<COOLIFY_FQDN>/api/v1/..."

Generate tokens in Coolify UI → Security → API Tokens. Tokens are team-scoped — they grant access to all resources within the team.

Core Endpoints

MethodEndpointPurpose
GET/api/v1/applicationsList all applications
GET/api/v1/applications/{uuid}Get application details
PATCH/api/v1/applications/{uuid}Update application settings
POST/api/v1/applications/{uuid}/deployTrigger deployment
POST/api/v1/applications/{uuid}/restartRestart application
POST/api/v1/applications/{uuid}/stopStop application
GET/api/v1/applications/{uuid}/deploymentsList deployments
GET/api/v1/serversList servers
GET/api/v1/teamsList teams
GET/api/v1/projectsList projects

Trigger a Deployment

# Basic deploy (note: GET method, not POST)
curl "https://<COOLIFY_FQDN>/api/v1/deploy?uuid=<APP_UUID>" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"

# With optional parameters
curl "https://<COOLIFY_FQDN>/api/v1/deploy?uuid=<APP_UUID>&force=true" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"

# Response (async — returns deployment job)
{
  "deployments": [
    {
      "message": "Deployment request queued.",
      "resource_uuid": "app-xxxx",
      "deployment_uuid": "dep-xxxx-xxxx"
    }
  ]
}

Parameters: uuid (resource UUID, comma-separated for batch), tag (tag name), force (boolean, skip cache), pr (PR number for preview deploys).

Check Deployment Status

curl -s "https://<COOLIFY_FQDN>/api/v1/deployments/<DEPLOYMENT_UUID>" \
  -H "Authorization: Bearer <TOKEN>" | jq '.status'

# Status values: queued, in_progress, finished, failed, cancelled

Get Application Logs

curl -s "https://<COOLIFY_FQDN>/api/v1/applications/<APP_UUID>/logs?lines=100" \
  -H "Authorization: Bearer <TOKEN>"

Update Application Settings

# Update image tag for pre-built image deployments
curl -X PATCH "https://<COOLIFY_FQDN>/api/v1/applications/<APP_UUID>" \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "docker_registry_image_tag": "v1.2.3"
  }'

Deploy Webhook URL

Each application has a unique webhook URL (found in Application → Webhooks tab):

https://<COOLIFY_FQDN>/api/v1/deploy?uuid=<APP_UUID>

Method: GET is the canonical method in Coolify's own docs and GitHub Actions examples. POST also works (with the uuid/tag in the JSON body).

# Canonical (GET)
curl --fail --show-error \
  "https://<COOLIFY_FQDN>/api/v1/deploy?uuid=<APP_UUID>" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"

# Also accepted (POST)
curl --fail --show-error -X POST \
  "https://<COOLIFY_FQDN>/api/v1/deploy" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"uuid": "<APP_UUID>"}'

Always use --fail (or --fail-with-body for visibility) — without it, curl returns exit 0 even when the deploy endpoint errors, and CI passes despite a failed trigger. This is exactly what scripts/audit-cicd.py checks for.

HMAC signature verification (new in beta.474, April 2026): Manual webhook secrets are now encrypted at rest and HMAC signature verification was strengthened. If you generate inbound webhooks pointing AT Coolify (e.g., GitHub→Coolify), the secret stored in Coolify is encrypted; if your CI sends FROM Coolify (e.g., notification webhooks), the outbound HMAC signing was hardened.

Webhook vs API: The webhook URL is simpler (single curl call), but offers less control. Use the full API for updating settings before deploy, checking status afterward, or complex multi-step workflows. The bundled @radoriginllc/coolify-mcp server wraps the full API and is preferable for any non-trivial CI/CD flow.

GitHub Actions Integration

Basic Deploy on Push

name: Deploy to Coolify
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger Coolify Deployment
        run: |
          curl --request GET \
            "${{ secrets.COOLIFY_WEBHOOK }}" \
            -H "Authorization: Bearer ${{ secrets.COOLIFY_API_TOKEN }}" \
            --fail --silent --show-error

Required GitHub Secrets

SecretValueExample
COOLIFY_WEBHOOKDeploy webhook URL from app's Webhook pagehttps://coolify.example.com/api/v1/deploy?uuid=app-xxxx
COOLIFY_API_TOKENAPI token from Keys & Tokens → API Tokenstoken with "Deploy" permission
COOLIFY_URLCoolify instance URL (for API calls)https://coolify.example.com

Deploy After Tests Pass

name: Test and Deploy
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci
      - run: npm test

  deploy:
    needs: test    # Only runs if tests pass
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to Coolify
        run: |
          curl -X POST \
            "${{ secrets.COOLIFY_URL }}/api/v1/applications/${{ secrets.COOLIFY_APP_UUID }}/deploy" \
            -H "Authorization: Bearer ${{ secrets.COOLIFY_API_TOKEN }}" \
            --fail --silent --show-error

Multi-Environment (Staging + Production)

name: Deploy Pipeline
on:
  push:
    branches: [main, develop]

jobs:
  deploy-staging:
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to Staging
        run: |
          curl -X POST \
            "${{ secrets.COOLIFY_URL }}/api/v1/applications/${{ secrets.COOLIFY_STAGING_UUID }}/deploy" \
            -H "Authorization: Bearer ${{ secrets.COOLIFY_API_TOKEN }}" --fail

  deploy-production:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production    # Requires approval if configured
    steps:
      - name: Deploy to Production
        run: |
          curl -X POST \
            "${{ secrets.COOLIFY_URL }}/api/v1/applications/${{ secrets.COOLIFY_PROD_UUID }}/deploy" \
            -H "Authorization: Bearer ${{ secrets.COOLIFY_API_TOKEN }}" --fail

GHCR Pattern (Full Pipeline)

Build in GitHub Actions → push to GHCR → trigger Coolify to deploy the image:

name: Build, Push, Deploy
on:
  push:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-push-deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4

      - uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

      - name: Update image tag in Coolify
        run: |
          curl -X PATCH \
            "${{ secrets.COOLIFY_URL }}/api/v1/applications/${{ secrets.COOLIFY_APP_UUID }}" \
            -H "Authorization: Bearer ${{ secrets.COOLIFY_API_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{"docker_registry_image_tag": "${{ github.sha }}"}'

      - name: Trigger deployment
        run: |
          curl -X POST \
            "${{ secrets.COOLIFY_URL }}/api/v1/applications/${{ secrets.COOLIFY_APP_UUID }}/deploy" \
            -H "Authorization: Bearer ${{ secrets.COOLIFY_API_TOKEN }}" --fail

Webhooks and Auto-Deploy

Git Provider Webhooks

Coolify can auto-deploy when it detects a push to the configured branch:

  1. Application → General → Git Repository — configure the repo and branch
  2. Enable Auto Deploy — Coolify registers a webhook with the git provider
  3. On push to the configured branch, Coolify triggers a build and deploy automatically

Branch-Specific Rules

  • Each Coolify application is configured for one branch
  • For multiple branches (staging, production), create separate Coolify applications pointing to different branches
  • Use the same repo, different branch configuration per application

PR Preview Environments

Coolify supports preview deployments for pull requests:

  1. Enable Preview Deployments in the application settings
  2. When a PR is opened against the configured branch, Coolify creates a temporary deployment
  3. The preview gets its own subdomain (e.g., pr-123.preview.example.com)
  4. When the PR is merged or closed, the preview environment is automatically destroyed

Limitations:

  • Preview environments share the server resources with production
  • Each preview creates a new container (resource-heavy for many concurrent PRs)
  • Database-dependent apps need a strategy for preview databases
  • Environment variables are inherited from the main application

Anti-Patterns

Anti-PatternConsequence
Using the same API token for all environmentsStaging pipeline can accidentally deploy to production
Not using --fail flag in curl deploy commandsCI/CD pipeline reports success even when deploy fails
Hardcoding Coolify URL or UUID in workflow filesBreaks when migrating Coolify or recreating apps
Polling deployment status in a tight loopWastes API rate limits; use reasonable intervals (10-15s)
Deploying without running tests firstBroken code reaches production
Using webhook URL in public reposAnyone can trigger your deployments
Not pinning image tags in productionlatest tag means non-deterministic deployments
Skipping the PATCH step in GHCR workflowsCoolify deploys the old image tag, not the new one

Related Skills

  • coolify-deploy — Build pack selection, deployment configuration, rollbacks
  • coolify-security — API token management, webhook security
  • coolify-troubleshoot — Debugging failed deployments

Additional Resources

Reference Files

  • references/api-reference.md — Full Coolify API v1 endpoint reference with request/response shapes
  • references/gitlab-ci-pattern.md — GitLab CI integration pattern for Coolify

What ships with it: 2 files

11.7 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.