#!/usr/bin/env bash set -euo pipefail # Coolify CLI - Pure bash implementation # Manages Coolify deployments, applications, databases, and services via the Coolify API # Configuration COOLIFY_API_URL="${COOLIFY_API_URL:-https://app.coolify.io/api/v1}" COOLIFY_TOKEN="${COOLIFY_TOKEN:-}" # Colors for output (optional, falls back to plain) if [[ -t 1 ]]; then RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' else RED='' GREEN='' YELLOW='' NC='' fi # ============================================================================ # Helper Functions # ============================================================================ check_requirements() { local missing=() command -v curl >/dev/null 2>&1 || missing+=("curl") command -v jq >/dev/null 2>&1 || missing+=("jq") if [[ ${#missing[@]} -gt 0 ]]; then error_response "MissingDependency" \ "Missing required tools: ${missing[*]}" \ "Install with: apt-get install ${missing[*]} (Debian/Ubuntu) or brew install ${missing[*]} (macOS)" exit 1 fi if [[ -z "$COOLIFY_TOKEN" ]]; then error_response "MissingToken" \ "COOLIFY_TOKEN environment variable not set" \ "Set your API token: export COOLIFY_TOKEN='your-token-here'" exit 1 fi } api_call() { local method="$1" local endpoint="$2" local data="${3:-}" local url="${COOLIFY_API_URL}${endpoint}" local response local http_code local temp_file temp_file=$(mktemp) if [[ -n "$data" ]]; then http_code=$(curl -s -w "%{http_code}" -o "$temp_file" \ -X "$method" \ -H "Authorization: Bearer ${COOLIFY_TOKEN}" \ -H "Content-Type: application/json" \ -d "$data" \ "$url") else http_code=$(curl -s -w "%{http_code}" -o "$temp_file" \ -X "$method" \ -H "Authorization: Bearer ${COOLIFY_TOKEN}" \ "$url") fi response=$(cat "$temp_file") rm -f "$temp_file" # Handle HTTP errors if [[ "$http_code" -ge 400 ]]; then local error_msg error_msg=$(echo "$response" | jq -r '.message // .error // "Unknown error"' 2>/dev/null || echo "HTTP $http_code error") error_response "APIError" \ "API request failed (HTTP $http_code): $error_msg" \ "Check your API token and parameters" return 1 fi echo "$response" } success_response() { local data="$1" local count="${2:-}" if [[ -n "$count" ]]; then echo "$data" | jq --argjson cnt "$count" '{success: true, data: ., count: $cnt}' else echo "$data" | jq '{success: true, data: .}' fi } error_response() { local type="$1" local message="$2" local hint="${3:-}" jq -n \ --arg type "$type" \ --arg msg "$message" \ --arg hint "$hint" \ '{success: false, error: {type: $type, message: $msg, hint: $hint}}' } # ============================================================================ # Applications Commands # ============================================================================ cmd_applications_list() { local tag="" while [[ $# -gt 0 ]]; do case $1 in --tag) tag="$2" shift 2 ;; *) error_response "UnknownOption" "Unknown option: $1" "Run: coolify applications list --help" return 1 ;; esac done local endpoint="/applications" [[ -n "$tag" ]] && endpoint="${endpoint}?tag=${tag}" local response response=$(api_call GET "$endpoint") local count count=$(echo "$response" | jq 'length') success_response "$response" "$count" } cmd_applications_get() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2" shift 2 ;; *) error_response "UnknownOption" "Unknown option: $1" "Run: coolify applications get --uuid " return 1 ;; esac done if [[ -z "$uuid" ]]; then error_response "MissingParameter" "Missing required parameter: --uuid" "Usage: coolify applications get --uuid " return 1 fi local response response=$(api_call GET "/applications/${uuid}") success_response "$response" } cmd_applications_start() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2" shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call POST "/applications/${uuid}/start") success_response "$response" } cmd_applications_stop() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2" shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call POST "/applications/${uuid}/stop") success_response "$response" } cmd_applications_restart() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2" shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call POST "/applications/${uuid}/restart") success_response "$response" } cmd_applications_logs() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2" shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call GET "/applications/${uuid}/logs") success_response "$response" } cmd_applications_envs() { local subcommand="${1:-}" shift || true case "$subcommand" in list) cmd_applications_envs_list "$@" ;; create) cmd_applications_envs_create "$@" ;; update) cmd_applications_envs_update "$@" ;; delete) cmd_applications_envs_delete "$@" ;; bulk-update) cmd_applications_envs_bulk_update "$@" ;; *) error_response "UnknownSubcommand" "Unknown envs subcommand: $subcommand" \ "Available: list, create, update, delete, bulk-update" return 1 ;; esac } cmd_applications_envs_list() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2" shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call GET "/applications/${uuid}/envs") success_response "$response" } cmd_applications_envs_create() { local uuid="" key="" value="" is_runtime="true" is_buildtime="false" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; --key) key="$2"; shift 2 ;; --value) value="$2"; shift 2 ;; --is-runtime) is_runtime="$2"; shift 2 ;; --is-buildtime) is_buildtime="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } [[ -z "$key" ]] && { error_response "MissingParameter" "Missing --key" ""; return 1; } [[ -z "$value" ]] && { error_response "MissingParameter" "Missing --value" ""; return 1; } local data data=$(jq -n \ --arg key "$key" \ --arg value "$value" \ --argjson runtime "$is_runtime" \ --argjson buildtime "$is_buildtime" \ '{key: $key, value: $value, is_runtime: $runtime, is_buildtime: $buildtime}') local response response=$(api_call POST "/applications/${uuid}/envs" "$data") success_response "$response" } cmd_applications_envs_update() { local uuid="" env_uuid="" value="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; --env-uuid) env_uuid="$2"; shift 2 ;; --value) value="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } [[ -z "$env_uuid" ]] && { error_response "MissingParameter" "Missing --env-uuid" ""; return 1; } [[ -z "$value" ]] && { error_response "MissingParameter" "Missing --value" ""; return 1; } local data data=$(jq -n --arg value "$value" '{value: $value}') local response response=$(api_call PATCH "/applications/${uuid}/envs/${env_uuid}" "$data") success_response "$response" } cmd_applications_envs_delete() { local uuid="" env_uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; --env-uuid) env_uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } [[ -z "$env_uuid" ]] && { error_response "MissingParameter" "Missing --env-uuid" ""; return 1; } local response response=$(api_call DELETE "/applications/${uuid}/envs/${env_uuid}") success_response "$response" } cmd_applications_envs_bulk_update() { local uuid="" json="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; --json) json="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } [[ -z "$json" ]] && { error_response "MissingParameter" "Missing --json" ""; return 1; } local response response=$(api_call POST "/applications/${uuid}/envs/bulk" "$json") success_response "$response" } cmd_applications_create_public() { local project_uuid="" server_uuid="" git_repository="" git_branch="" name="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --git-repository) git_repository="$2"; shift 2 ;; --git-branch) git_branch="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$git_repository" ]] && { error_response "MissingParameter" "Missing --git-repository" ""; return 1; } [[ -z "$git_branch" ]] && { error_response "MissingParameter" "Missing --git-branch" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg repo "$git_repository" \ --arg branch "$git_branch" \ --arg name "$name" \ '{project_uuid: $project, server_uuid: $server, git_repository: $repo, git_branch: $branch, name: $name, build_pack: "nixpacks", ports_exposes: "3000"}') local response response=$(api_call POST "/applications/public" "$data") success_response "$response" } # ============================================================================ # Databases Commands # ============================================================================ cmd_databases_list() { local response response=$(api_call GET "/databases") local count count=$(echo "$response" | jq 'length') success_response "$response" "$count" } cmd_databases_get() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call GET "/databases/${uuid}") success_response "$response" } cmd_databases_start() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call POST "/databases/${uuid}/start") success_response "$response" } cmd_databases_stop() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call POST "/databases/${uuid}/stop") success_response "$response" } cmd_databases_restart() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call POST "/databases/${uuid}/restart") success_response "$response" } cmd_databases_delete() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call DELETE "/databases/${uuid}") success_response "$response" } cmd_databases_create_postgresql() { local project_uuid="" server_uuid="" name="" postgres_user="postgres" postgres_password="" postgres_db="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; --postgres-user) postgres_user="$2"; shift 2 ;; --postgres-password) postgres_password="$2"; shift 2 ;; --postgres-db) postgres_db="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$name" ]] && { error_response "MissingParameter" "Missing --name" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg name "$name" \ --arg user "$postgres_user" \ --arg password "$postgres_password" \ --arg db "$postgres_db" \ '{project_uuid: $project, server_uuid: $server, name: $name, type: "postgresql", postgres_user: $user, postgres_password: $password, postgres_db: $db}') local response response=$(api_call POST "/databases" "$data") success_response "$response" } cmd_databases_create_mysql() { local project_uuid="" server_uuid="" name="" mysql_root_password="" mysql_database="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; --mysql-root-password) mysql_root_password="$2"; shift 2 ;; --mysql-database) mysql_database="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$name" ]] && { error_response "MissingParameter" "Missing --name" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg name "$name" \ --arg password "$mysql_root_password" \ --arg database "$mysql_database" \ '{project_uuid: $project, server_uuid: $server, name: $name, type: "mysql", mysql_root_password: $password, mysql_database: $database}') local response response=$(api_call POST "/databases" "$data") success_response "$response" } cmd_databases_create_mariadb() { local project_uuid="" server_uuid="" name="" mariadb_root_password="" mariadb_database="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; --mariadb-root-password) mariadb_root_password="$2"; shift 2 ;; --mariadb-database) mariadb_database="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$name" ]] && { error_response "MissingParameter" "Missing --name" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg name "$name" \ --arg password "$mariadb_root_password" \ --arg database "$mariadb_database" \ '{project_uuid: $project, server_uuid: $server, name: $name, type: "mariadb", mariadb_root_password: $password, mariadb_database: $database}') local response response=$(api_call POST "/databases" "$data") success_response "$response" } cmd_databases_create_mongodb() { local project_uuid="" server_uuid="" name="" mongo_initdb_root_username="" mongo_initdb_root_password="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; --mongo-initdb-root-username) mongo_initdb_root_username="$2"; shift 2 ;; --mongo-initdb-root-password) mongo_initdb_root_password="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$name" ]] && { error_response "MissingParameter" "Missing --name" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg name "$name" \ --arg username "$mongo_initdb_root_username" \ --arg password "$mongo_initdb_root_password" \ '{project_uuid: $project, server_uuid: $server, name: $name, type: "mongodb", mongo_initdb_root_username: $username, mongo_initdb_root_password: $password}') local response response=$(api_call POST "/databases" "$data") success_response "$response" } cmd_databases_create_redis() { local project_uuid="" server_uuid="" name="" redis_password="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; --redis-password) redis_password="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$name" ]] && { error_response "MissingParameter" "Missing --name" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg name "$name" \ --arg password "$redis_password" \ '{project_uuid: $project, server_uuid: $server, name: $name, type: "redis", redis_password: $password}') local response response=$(api_call POST "/databases" "$data") success_response "$response" } cmd_databases_create_keydb() { local project_uuid="" server_uuid="" name="" keydb_password="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; --keydb-password) keydb_password="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$name" ]] && { error_response "MissingParameter" "Missing --name" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg name "$name" \ --arg password "$keydb_password" \ '{project_uuid: $project, server_uuid: $server, name: $name, type: "keydb", keydb_password: $password}') local response response=$(api_call POST "/databases" "$data") success_response "$response" } cmd_databases_create_clickhouse() { local project_uuid="" server_uuid="" name="" clickhouse_admin_user="" clickhouse_admin_password="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; --clickhouse-admin-user) clickhouse_admin_user="$2"; shift 2 ;; --clickhouse-admin-password) clickhouse_admin_password="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$name" ]] && { error_response "MissingParameter" "Missing --name" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg name "$name" \ --arg user "$clickhouse_admin_user" \ --arg password "$clickhouse_admin_password" \ '{project_uuid: $project, server_uuid: $server, name: $name, type: "clickhouse", clickhouse_admin_user: $user, clickhouse_admin_password: $password}') local response response=$(api_call POST "/databases" "$data") success_response "$response" } cmd_databases_create_dragonfly() { local project_uuid="" server_uuid="" name="" dragonfly_password="" while [[ $# -gt 0 ]]; do case $1 in --project-uuid) project_uuid="$2"; shift 2 ;; --server-uuid) server_uuid="$2"; shift 2 ;; --name) name="$2"; shift 2 ;; --dragonfly-password) dragonfly_password="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$project_uuid" ]] && { error_response "MissingParameter" "Missing --project-uuid" ""; return 1; } [[ -z "$server_uuid" ]] && { error_response "MissingParameter" "Missing --server-uuid" ""; return 1; } [[ -z "$name" ]] && { error_response "MissingParameter" "Missing --name" ""; return 1; } local data data=$(jq -n \ --arg project "$project_uuid" \ --arg server "$server_uuid" \ --arg name "$name" \ --arg password "$dragonfly_password" \ '{project_uuid: $project, server_uuid: $server, name: $name, type: "dragonfly", dragonfly_password: $password}') local response response=$(api_call POST "/databases" "$data") success_response "$response" } # ============================================================================ # Deployment Commands # ============================================================================ cmd_deploy() { local uuid="" force="false" tag="" instant_deploy="false" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; --tag) tag="$2"; shift 2 ;; --force) force="true"; shift ;; --instant-deploy) instant_deploy="true"; shift ;; *) shift ;; esac done if [[ -z "$uuid" && -z "$tag" ]]; then error_response "MissingParameter" "Missing --uuid or --tag" "Provide either --uuid or --tag" return 1 fi local data data=$(jq -n \ --argjson force "$force" \ --argjson instant "$instant_deploy" \ '{force: $force, instant_deploy: $instant}') local endpoint if [[ -n "$uuid" ]]; then endpoint="/applications/${uuid}/deploy" else endpoint="/deploy?tag=${tag}" fi local response response=$(api_call POST "$endpoint" "$data") success_response "$response" } cmd_deployments_list() { local response response=$(api_call GET "/deployments") success_response "$response" } cmd_deployments_get() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call GET "/deployments/${uuid}") success_response "$response" } # ============================================================================ # Servers Commands # ============================================================================ cmd_servers_list() { local response response=$(api_call GET "/servers") local count count=$(echo "$response" | jq 'length') success_response "$response" "$count" } cmd_servers_get() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call GET "/servers/${uuid}") success_response "$response" } # ============================================================================ # Projects Commands # ============================================================================ cmd_projects_list() { local response response=$(api_call GET "/projects") local count count=$(echo "$response" | jq 'length') success_response "$response" "$count" } cmd_projects_get() { local uuid="" while [[ $# -gt 0 ]]; do case $1 in --uuid) uuid="$2"; shift 2 ;; *) shift ;; esac done [[ -z "$uuid" ]] && { error_response "MissingParameter" "Missing --uuid" ""; return 1; } local response response=$(api_call GET "/projects/${uuid}") success_response "$response" } # ============================================================================ # Teams Commands # ============================================================================ cmd_teams_list() { local response response=$(api_call GET "/teams") success_response "$response" } cmd_teams_current() { local response response=$(api_call GET "/teams/current") success_response "$response" } # ============================================================================ # Main Command Router # ============================================================================ cmd_applications() { local subcommand="${1:-}" shift || true case "$subcommand" in list) cmd_applications_list "$@" ;; get) cmd_applications_get "$@" ;; start) cmd_applications_start "$@" ;; stop) cmd_applications_stop "$@" ;; restart) cmd_applications_restart "$@" ;; logs) cmd_applications_logs "$@" ;; envs) cmd_applications_envs "$@" ;; create-public) cmd_applications_create_public "$@" ;; *) error_response "UnknownSubcommand" "Unknown applications subcommand: $subcommand" \ "Available: list, get, start, stop, restart, logs, envs, create-public" return 1 ;; esac } cmd_databases() { local subcommand="${1:-}" shift || true case "$subcommand" in list) cmd_databases_list "$@" ;; get) cmd_databases_get "$@" ;; start) cmd_databases_start "$@" ;; stop) cmd_databases_stop "$@" ;; restart) cmd_databases_restart "$@" ;; delete) cmd_databases_delete "$@" ;; create-postgresql) cmd_databases_create_postgresql "$@" ;; create-mysql) cmd_databases_create_mysql "$@" ;; create-mariadb) cmd_databases_create_mariadb "$@" ;; create-mongodb) cmd_databases_create_mongodb "$@" ;; create-redis) cmd_databases_create_redis "$@" ;; create-keydb) cmd_databases_create_keydb "$@" ;; create-clickhouse) cmd_databases_create_clickhouse "$@" ;; create-dragonfly) cmd_databases_create_dragonfly "$@" ;; *) error_response "UnknownSubcommand" "Unknown databases subcommand: $subcommand" \ "Available: list, get, start, stop, restart, delete, create-postgresql, create-mysql, create-mariadb, create-mongodb, create-redis, create-keydb, create-clickhouse, create-dragonfly" return 1 ;; esac } cmd_deployments() { local subcommand="${1:-}" shift || true case "$subcommand" in list) cmd_deployments_list "$@" ;; get) cmd_deployments_get "$@" ;; *) error_response "UnknownSubcommand" "Unknown deployments subcommand: $subcommand" \ "Available: list, get" return 1 ;; esac } cmd_servers() { local subcommand="${1:-}" shift || true case "$subcommand" in list) cmd_servers_list "$@" ;; get) cmd_servers_get "$@" ;; *) error_response "UnknownSubcommand" "Unknown servers subcommand: $subcommand" \ "Available: list, get" return 1 ;; esac } cmd_projects() { local subcommand="${1:-}" shift || true case "$subcommand" in list) cmd_projects_list "$@" ;; get) cmd_projects_get "$@" ;; *) error_response "UnknownSubcommand" "Unknown projects subcommand: $subcommand" \ "Available: list, get" return 1 ;; esac } cmd_teams() { local subcommand="${1:-}" shift || true case "$subcommand" in list) cmd_teams_list "$@" ;; current) cmd_teams_current "$@" ;; *) error_response "UnknownSubcommand" "Unknown teams subcommand: $subcommand" \ "Available: list, current" return 1 ;; esac } show_help() { cat < [options] Commands: applications Manage applications databases Manage databases deploy Deploy an application deployments View deployments servers Manage servers projects Manage projects teams Manage teams Examples: coolify applications list coolify applications get --uuid abc-123 coolify deploy --uuid abc-123 --force coolify databases create-postgresql --project-uuid proj-123 --server-uuid srv-456 --name mydb Environment Variables: COOLIFY_TOKEN API token (required) COOLIFY_API_URL API base URL (default: https://app.coolify.io/api/v1) For more information, see SKILL.md EOF } # ============================================================================ # Main Entry Point # ============================================================================ main() { # Check requirements first check_requirements local command="${1:-}" if [[ -z "$command" || "$command" == "--help" || "$command" == "-h" ]]; then show_help exit 0 fi shift case "$command" in applications) cmd_applications "$@" ;; databases) cmd_databases "$@" ;; deploy) cmd_deploy "$@" ;; deployments) cmd_deployments "$@" ;; servers) cmd_servers "$@" ;; projects) cmd_projects "$@" ;; teams) cmd_teams "$@" ;; *) error_response "UnknownCommand" "Unknown command: $command" "Run: coolify --help" exit 1 ;; esac } main "$@"