Origin e deploy passam a documentar git.hellomanoel.com; GitHub/GHCR ficam como legado/backup. Co-authored-by: Cursor <cursoragent@cursor.com>
115 lines
3.5 KiB
Bash
Executable File
115 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Trigger a Dokploy Compose deploy and wait until it finishes.
|
|
# Required env:
|
|
# DOKPLOY_URL e.g. https://panel.example.com (panel origin, no /api)
|
|
# DOKPLOY_API_KEY x-api-key value
|
|
# DOKPLOY_COMPOSE_ID target compose id
|
|
# Optional env:
|
|
# DEPLOY_TITLE deployment title (default: Gitea deploy)
|
|
# DEPLOY_TIMEOUT_SEC total wait seconds (default: 900)
|
|
# DEPLOY_POLL_SEC poll interval (default: 10)
|
|
|
|
set -euo pipefail
|
|
|
|
: "${DOKPLOY_URL:?DOKPLOY_URL is required}"
|
|
: "${DOKPLOY_API_KEY:?DOKPLOY_API_KEY is required}"
|
|
: "${DOKPLOY_COMPOSE_ID:?DOKPLOY_COMPOSE_ID is required}"
|
|
|
|
# Panel origin only: strip trailing slash and accidental OpenAPI /api suffix.
|
|
DOKPLOY_URL="${DOKPLOY_URL%/}"
|
|
DOKPLOY_URL="${DOKPLOY_URL%/api}"
|
|
DOKPLOY_URL="${DOKPLOY_URL%/}"
|
|
|
|
DEPLOY_TITLE="${DEPLOY_TITLE:-Gitea deploy}"
|
|
DEPLOY_TIMEOUT_SEC="${DEPLOY_TIMEOUT_SEC:-900}"
|
|
DEPLOY_POLL_SEC="${DEPLOY_POLL_SEC:-10}"
|
|
|
|
echo "Dokploy API base: ${DOKPLOY_URL}/api"
|
|
|
|
api() {
|
|
local method="$1"
|
|
local path="$2"
|
|
shift 2
|
|
local url="${DOKPLOY_URL}/api${path}"
|
|
local response http_code body
|
|
|
|
# Body then HTTP status on the last line (no -f so 4xx/5xx still return a body).
|
|
response="$(
|
|
curl -sS -w $'\n%{http_code}' -X "$method" \
|
|
-H "accept: application/json" \
|
|
-H "content-type: application/json" \
|
|
-H "x-api-key: ${DOKPLOY_API_KEY}" \
|
|
"$url" \
|
|
"$@"
|
|
)" || {
|
|
echo "Dokploy API request failed (curl transport error)." >&2
|
|
echo " method: ${method}" >&2
|
|
echo " url: ${url}" >&2
|
|
exit 1
|
|
}
|
|
|
|
http_code="$(printf '%s' "$response" | tail -n1)"
|
|
body="$(printf '%s' "$response" | sed '$d')"
|
|
|
|
if [[ ! "$http_code" =~ ^2[0-9][0-9]$ ]]; then
|
|
echo "Dokploy API error." >&2
|
|
echo " method: ${method}" >&2
|
|
echo " url: ${url}" >&2
|
|
echo " status: ${http_code}" >&2
|
|
echo " body:" >&2
|
|
printf '%s\n' "$body" >&2
|
|
exit 1
|
|
fi
|
|
|
|
printf '%s' "$body"
|
|
}
|
|
|
|
echo "Triggering Dokploy compose.deploy for ${DOKPLOY_COMPOSE_ID}..."
|
|
api POST "/compose.deploy" \
|
|
-d "$(jq -n \
|
|
--arg composeId "$DOKPLOY_COMPOSE_ID" \
|
|
--arg title "$DEPLOY_TITLE" \
|
|
'{composeId: $composeId, title: $title}')" >/dev/null
|
|
|
|
echo "Waiting for deployment to finish (timeout ${DEPLOY_TIMEOUT_SEC}s)..."
|
|
deadline=$((SECONDS + DEPLOY_TIMEOUT_SEC))
|
|
last_status=""
|
|
|
|
while (( SECONDS < deadline )); do
|
|
payload="$(api GET "/deployment.allByCompose?composeId=${DOKPLOY_COMPOSE_ID}")"
|
|
latest="$(echo "$payload" | jq -c 'if type=="array" then .[0] else . end')"
|
|
|
|
if [[ -z "$latest" || "$latest" == "null" ]]; then
|
|
echo "No deployment records yet; retrying..."
|
|
sleep "$DEPLOY_POLL_SEC"
|
|
continue
|
|
fi
|
|
|
|
status="$(echo "$latest" | jq -r '.status // .deploymentStatus // empty')"
|
|
created_at="$(echo "$latest" | jq -r '.createdAt // .created_at // empty')"
|
|
title="$(echo "$latest" | jq -r '.title // .titleLog // empty')"
|
|
|
|
if [[ "$status" != "$last_status" ]]; then
|
|
echo "Deployment status=${status:-unknown} title=${title:-n/a} createdAt=${created_at:-n/a}"
|
|
last_status="$status"
|
|
fi
|
|
|
|
case "${status,,}" in
|
|
done|success|successful|finished)
|
|
echo "Dokploy deployment succeeded."
|
|
exit 0
|
|
;;
|
|
error|failed|failure)
|
|
echo "Dokploy deployment failed." >&2
|
|
echo "$latest" | jq . >&2 || true
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
sleep "$DEPLOY_POLL_SEC"
|
|
done
|
|
|
|
echo "Timed out waiting for Dokploy deployment after ${DEPLOY_TIMEOUT_SEC}s." >&2
|
|
api GET "/deployment.allByCompose?composeId=${DOKPLOY_COMPOSE_ID}" | jq . >&2 || true
|
|
exit 1
|