agentsclimarketplace

Coolify cicd

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

Marketplace of plugins and skills for Claude Code

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.

What its author says it does

Copied from the file, not written here

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".

SKILL.md

12.1 KB, 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

Keep looking

Skills are one crate of 328,083. 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.