Reusable JavaScript GitHub Action for deploying to Coolify with optional Cloudflare Bot Fight Mode bypass, post-action cleanup, GitHub Deployments, and automatic app URL resolution.
ilhmlnaa/coolify-deploy turns repeated Coolify deployment workflow patterns into a single reusable action. It can temporarily disable Cloudflare Bot Fight Mode before triggering Coolify deploy webhooks, then automatically restore it in a post: step that runs even when the job fails or is cancelled.
- Features
- Quick Start
- Inputs
- Outputs
- Usage Examples
- Auto App URL
- Cloudflare Bot Fight Mode Bypass
- GitHub Deployments
- Permissions Required
- Development
- License
- π Coolify Webhook Deploys
- Trigger one or many Coolify deploy webhooks from a single workflow step.
- Supports comma-separated and newline-separated webhook URL input.
- π‘οΈ Cloudflare Bot Fight Mode Bypass
- Optionally disables Bot Fight Mode before deploy.
- Uses a JavaScript action
post:step to restore Bot Fight Mode after the job.
- π§Ή Reliable Cleanup
- Cleanup uses
post-if: always()so restoration runs on success, failure, or cancellation.
- Cleanup uses
- π¦ GitHub Deployment API
- Optionally creates GitHub Deployment records and deployment statuses.
- π Auto App URL Resolution
- Resolves
environment_urlfrom Coolify applicationfqdnvia deployment UUID.
- Resolves
- π§© Reusable Workflow Primitive
- Designed to replace repeated deploy snippets across projects like
zenime-next,askpdf-ai, andcrawlix-next.
- Designed to replace repeated deploy snippets across projects like
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: ilhmlnaa/coolify-deploy@v1
with:
coolify_webhook_url: ${{ secrets.COOLIFY_WEBHOOK_URL }}
coolify_token: ${{ secrets.COOLIFY_TOKEN }}| Input | Required | Default | Description |
|---|---|---|---|
coolify_webhook_url |
β | β | Coolify webhook URL(s). Supports comma-separated or newline-separated values for multi-service deploys. |
coolify_token |
β | β | Coolify API Bearer token used for deploy webhook calls and optional app URL resolution. |
cloudflare_api_token |
β | '' |
Cloudflare API token. When provided with cloudflare_zone_id, enables Bot Fight Mode bypass in auto mode. |
cloudflare_zone_id |
β | '' |
Cloudflare Zone ID. Required when cloudflare_api_token is set. |
bypass_cloudflare_bot |
β | auto |
true, false, or auto. auto enables bypass only when Cloudflare credentials are provided. |
propagation_delay |
β | 15 |
Seconds to wait after disabling Bot Fight Mode before triggering Coolify deploys. |
create_github_deployment |
β | false |
Set to true to create GitHub Deployment records. |
deployment_environment |
β | production |
Environment name for GitHub Deployment API. |
app_url |
β | '' |
Deployment environment URL. Use auto to resolve from Coolify API fqdn, pass an explicit URL, or leave empty. |
github_token |
β | ${{ github.token }} |
GitHub token for Deployment API. Usually the default is enough. |
| Output | Description |
|---|---|
deployment_status |
success or failure, based on Coolify webhook results. |
deployed_services |
Number of services successfully deployed. |
bot_mode_restored |
true, false, skipped, or pending. The final value is emitted by the post step when available. |
github_deployment_id |
GitHub Deployment ID if deployment creation is enabled. |
resolved_app_url |
Resolved app URL when app_url: auto succeeds, or explicit app_url value. |
- uses: ilhmlnaa/coolify-deploy@v1
with:
coolify_webhook_url: ${{ secrets.COOLIFY_WEBHOOK_URL }}
coolify_token: ${{ secrets.COOLIFY_TOKEN }}- uses: ilhmlnaa/coolify-deploy@v1
with:
coolify_webhook_url: ${{ secrets.COOLIFY_WEBHOOK_URL }}
coolify_token: ${{ secrets.COOLIFY_TOKEN }}
cloudflare_api_token: ${{ secrets.CF_API_TOKEN }}
cloudflare_zone_id: ${{ secrets.CF_ZONE_ID }}- uses: ilhmlnaa/coolify-deploy@v1
with:
coolify_webhook_url: |
${{ secrets.API_WEBHOOK }},
${{ secrets.WORKER_WEBHOOK }},
${{ secrets.WEB_WEBHOOK }}
coolify_token: ${{ secrets.COOLIFY_TOKEN }}permissions:
contents: read
deployments: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: ilhmlnaa/coolify-deploy@v1
with:
coolify_webhook_url: |
${{ secrets.API_WEBHOOK }},
${{ secrets.WORKER_WEBHOOK }},
${{ secrets.WEB_WEBHOOK }}
coolify_token: ${{ secrets.COOLIFY_TOKEN }}
cloudflare_api_token: ${{ secrets.CF_API_TOKEN }}
cloudflare_zone_id: ${{ secrets.CF_ZONE_ID }}
create_github_deployment: 'true'
deployment_environment: 'production'
app_url: 'auto'More complete workflow examples are available in examples/.
When app_url is set to auto, the action extracts the Coolify instance base URL and app UUID from the first webhook URL:
https://coolify.example.com/api/v1/deploy?uuid=abc123
It then calls:
GET https://coolify.example.com/api/v1/applications/abc123
If Coolify returns:
{ "fqdn": "https://myapp.com,https://www.myapp.com" }The action uses the first URL:
https://myapp.com
Note: Auto app URL resolution requires a Coolify token with permission to read applications. If the lookup fails, deployment still continues and the GitHub Deployment status is created without
environment_url.
Some Coolify deploy webhooks can be blocked when Cloudflare Bot Fight Mode is enabled in front of the Coolify instance. This action can temporarily disable Bot Fight Mode before deployment and restore it afterwards.
The lifecycle is:
- Read current Cloudflare Bot Fight Mode state.
- Disable Bot Fight Mode.
- Save the original state via
core.saveState(). - Wait for
propagation_delayseconds. - Trigger Coolify deploy webhook(s).
- Run
post:cleanup withpost-if: always(). - Re-enable Bot Fight Mode only if it was originally enabled.
This means the action does not blindly enable Bot Fight Mode. It restores the original state.
Set create_github_deployment to true to create a GitHub Deployment record and status.
permissions:
contents: read
deployments: write
steps:
- uses: ilhmlnaa/coolify-deploy@v1
with:
coolify_webhook_url: ${{ secrets.COOLIFY_WEBHOOK_URL }}
coolify_token: ${{ secrets.COOLIFY_TOKEN }}
create_github_deployment: 'true'
deployment_environment: 'production'
app_url: 'auto'Deployment status is set to:
successwhen all Coolify webhook calls return2xxfailurewhen one or more webhook calls fail
For normal deploy-only usage:
permissions:
contents: readFor GitHub Deployment API usage:
permissions:
contents: read
deployments: writeThe Coolify token should be able to:
- Trigger deploy webhooks.
- Read application details if
app_url: autois used.
For Bot Fight Mode bypass, the Cloudflare token needs permission to read and edit zone bot management settings for the target zone.
Recommended scope:
- Zone: Read
- Bot Management: Edit, if available for your account/plan
Cloudflare API permission names can vary by account features and plan. Use the minimum permissions that allow access to:
GET /client/v4/zones/{zone_id}/bot_management
PUT /client/v4/zones/{zone_id}/bot_management
npm installnpm run buildThis creates:
dist/main/index.js
dist/post/index.js
dist/ must be committed because JavaScript GitHub Actions run from the bundled files.
npm run lintgit tag v1.0.0
git push origin v1.0.0coolify-deploy/
βββ action.yml
βββ package.json
βββ src/
β βββ main.js
β βββ post.js
β βββ cloudflare.js
β βββ coolify.js
β βββ deployment.js
β βββ utils.js
βββ dist/
β βββ main/index.js
β βββ post/index.js
βββ .github/workflows/test.yml
βββ examples/
β βββ basic.yml
β βββ with-cloudflare.yml
β βββ multi-service.yml
β βββ full-featured.yml
βββ README.md
βββ LICENSE
βββ .gitignore
This project is licensed under the MIT License. See the LICENSE file for details.
