coolify
npx skills add https://github.com/spqw/skill-coolify --skill coolify
Agent 安装分布
Skill 文档
Coolify Deployment Skill
Manage applications on a Coolify instance via its REST API.
Configuration
The skill requires two environment variables. Check for them before any operation:
COOLIFY_API_URL="${COOLIFY_API_URL:-http://localhost:8000}"
COOLIFY_API_TOKEN="${COOLIFY_API_TOKEN}"
If COOLIFY_API_TOKEN is not set, check ~/.config/coolify/token or /etc/coolify/token:
if [ -z "$COOLIFY_API_TOKEN" ]; then
for f in ~/.config/coolify/token /etc/coolify/token; do
[ -f "$f" ] && COOLIFY_API_TOKEN="$(cat "$f")" && break
done
fi
All API calls use:
curl -s "${COOLIFY_API_URL}/api/v1/<endpoint>" \
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" \
-H "Accept: application/json" \
-H "Content-Type: application/json"
Core API Operations
List Resources
| Resource | Endpoint | Method |
|---|---|---|
| Servers | /api/v1/servers |
GET |
| Projects | /api/v1/projects |
GET |
| Applications | /api/v1/applications |
GET |
| Databases | /api/v1/databases |
GET |
| Services | /api/v1/services |
GET |
| Deployments | /api/v1/deployments |
GET |
Application CRUD
Get application details:
GET /api/v1/applications/{uuid}
Create application from public git repo:
POST /api/v1/applications/public
Required body fields:
project_uuidâ target projectserver_uuidâ target serverenvironment_nameâ environment name (e.g. “production”)git_repositoryâ repo URLgit_branchâ branch namebuild_packâ “dockerfile”, “dockercompose”, “nixpacks”, “static”ports_exposesâ comma-separated ports (e.g. “3400”)
Optional fields:
nameâ app display namedescriptionâ app descriptiondomainsâ FQDN (e.g. “https://app.example.com“)dockerfile_locationâ path to Dockerfile (default: “/Dockerfile”)instant_deployâ boolean, deploy immediately after creationcustom_docker_run_optionsâ extra docker run flags (volumes, privileged, etc.)start_commandâ override container start commanddocker_compose_custom_start_commandâ override compose start command
Create from private repo (GitHub App):
POST /api/v1/applications/private-github-app
Additional required: github_app_uuid
Create from private repo (deploy key):
POST /api/v1/applications/private-deploy-key
Additional required: private_key_uuid
Update application:
PATCH /api/v1/applications/{uuid}
Send only the fields you want to change. Immutable fields: project_uuid, environment_name, server_uuid, build_pack.
Delete application:
DELETE /api/v1/applications/{uuid}
Deployment Actions
Deploy/start:
GET /api/v1/applications/{uuid}/start
Optional query: ?force=true to rebuild without cache.
Restart:
GET /api/v1/applications/{uuid}/restart
Stop:
GET /api/v1/applications/{uuid}/stop
Deploy multiple by UUID (comma-separated):
GET /api/v1/deploy?uuid={uuid1},{uuid2},{uuid3}
Deploy by tag:
GET /api/v1/deploy?tag={tag_name}
Deployment Status
List all running deployments:
GET /api/v1/deployments
Get deployment details:
GET /api/v1/deployments/{deployment_uuid}
Get deployment history for an app:
GET /api/v1/deployments/applications/{uuid}
Cancel a queued/in-progress deployment:
POST /api/v1/deployments/{deployment_uuid}/cancel
Application Logs
GET /api/v1/applications/{uuid}/logs?since=<timestamp>&tail=<lines>
Environment Variables
List:
GET /api/v1/applications/{uuid}/envs
Create:
POST /api/v1/applications/{uuid}/envs
Body: { "key": "NAME", "value": "val", "is_build_time": false, "is_preview": false }
Bulk create/update:
PATCH /api/v1/applications/{uuid}/envs/bulk
Body: { "variables": [{ "key": "K", "value": "V" }] }
Delete:
DELETE /api/v1/applications/{uuid}/envs/{env_uuid}
Projects & Environments
Create project:
POST /api/v1/projects
Body: { "name": "my-project", "description": "..." }
Create environment in project:
POST /api/v1/projects/{project_uuid}/environments
Body: { "name": "staging" }
List environments:
GET /api/v1/projects/{project_uuid}/environments
Get environment details (includes all resources):
GET /api/v1/projects/{project_uuid}/{env_name_or_uuid}
Docker Configuration
custom_docker_run_options
Pass additional flags to docker run via the custom_docker_run_options field on applications. This is a string of space-separated Docker flags.
Volume mounts:
--volume /host/path:/container/path
Host access for sudo/commands:
--privileged --pid=host --volume /var/run/docker.sock:/var/run/docker.sock --volume /usr/bin/docker:/usr/bin/docker
Full host access pattern (sudo from container):
--privileged --pid=host --volume /:/host --volume /var/run/docker.sock:/var/run/docker.sock
Then inside the container: nsenter -t 1 -m -u -i -n -p -- <command> runs as root on the host.
Specific capabilities instead of full privileged:
--cap-add=SYS_ADMIN --cap-add=SYS_PTRACE --security-opt=apparmor=unconfined
Docker Compose deployments
For compose-based apps, the compose file is the single source of truth. Set build_pack to dockercompose. Security options go directly in the compose file:
services:
app:
privileged: true
pid: "host"
cap_add:
- SYS_ADMIN
- SYS_PTRACE
- NET_ADMIN
security_opt:
- apparmor=unconfined
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/ubuntu:/home/ubuntu
Predefined Environment Variables
Coolify auto-injects these at runtime:
COOLIFY_FQDNâ the app’s domain(s)COOLIFY_URLâ the app’s URL(s)COOLIFY_BRANCHâ the git branchCOOLIFY_RESOURCE_UUIDâ the app UUIDSOURCE_COMMITâ the git commit hashPORTâ defaults to first exposed port or 3000HOSTâ defaults to 0.0.0.0
Shared Variables (cross-resource)
Reference variables from higher scopes:
{{team.VAR_NAME}}â team-level{{project.VAR_NAME}}â project-level{{environment.VAR_NAME}}â environment-level
Resource Limits
Set via PATCH on applications:
limits_memoryâ e.g. “512M”, “2G”limits_memory_swapâ swap limitlimits_cpusâ e.g. “0.5”, “2”limits_cpusetâ pin to specific CPUslimits_cpu_sharesâ relative CPU weight (default 1024)
Common Workflows
Deploy all apps with a tag
curl -s "${COOLIFY_API_URL}/api/v1/deploy?tag=staging" \
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}"
Deploy specific app and wait for completion
# Trigger deploy
RESULT=$(curl -s "${COOLIFY_API_URL}/api/v1/applications/${APP_UUID}/start?force=true" \
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" \
-H "Accept: application/json")
DEPLOY_UUID=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('deployment_uuid',''))" 2>/dev/null)
# Poll status
while true; do
STATUS=$(curl -s "${COOLIFY_API_URL}/api/v1/deployments/${DEPLOY_UUID}" \
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" \
-H "Accept: application/json" | python3 -c "import sys,json; print(json.load(sys.stdin).get('status',''))" 2>/dev/null)
case "$STATUS" in
finished) echo "Deploy succeeded"; break ;;
failed|cancelled) echo "Deploy $STATUS"; break ;;
*) sleep 5 ;;
esac
done
Multi-branch deployment from same repo
Create one application per branch, each pointing to the same git_repository but different git_branch, with unique domains and name.
Update docker run options and redeploy
curl -s -X PATCH "${COOLIFY_API_URL}/api/v1/applications/${UUID}" \
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"custom_docker_run_options": "--privileged --pid=host --volume /var/run/docker.sock:/var/run/docker.sock"}'
curl -s "${COOLIFY_API_URL}/api/v1/applications/${UUID}/start?force=true" \
-H "Authorization: Bearer ${COOLIFY_API_TOKEN}"
Error Handling
| Code | Meaning |
|---|---|
| 401 | Invalid or missing API token |
| 404 | Resource not found |
| 409 | Domain conflict (another app uses this domain) |
| 422 | Validation error (check errors field) |
| 429 | Too many concurrent deployments (retry after 60s) |
Checking Coolify Status
# Is Coolify running?
docker ps --filter "name=coolify" --format "{{.Names}} {{.Status}}"
# Restart Coolify if needed
cd /data/coolify/source && docker compose --env-file .env -f docker-compose.yml -f docker-compose.prod.yml up -d
Additional References
See references/api-endpoints.md for the complete API endpoint table.