48 lines
2.4 KiB
Bash
48 lines
2.4 KiB
Bash
#!/bin/sh
|
|
# Run on the deployment host, or in the runner with /runtime bind-mounted.
|
|
set -eu
|
|
TAG=${1:?Usage: deploy.sh IMAGE_TAG}
|
|
case "$TAG" in *[!A-Za-z0-9_.-]*|'') echo "Invalid image tag" >&2; exit 2;; esac
|
|
RUNTIME=${MQTT5_RUNTIME:-/opt/test-mqtt-5/backend}
|
|
mkdir -p "$RUNTIME"
|
|
# Serialize manual and CI deployments on the shared mounted directory.
|
|
exec 9>"$RUNTIME/deploy.lock"
|
|
flock -w 120 9
|
|
[ -s "$RUNTIME/secrets/backend.json" ] && [ -s "$RUNTIME/ca.crt" ] || { echo "Server credentials/CA missing" >&2; exit 1; }
|
|
docker image inspect "mqtt5-test-backend:$TAG" >/dev/null
|
|
SOURCE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
HAD_PREVIOUS=false
|
|
if [ -s "$RUNTIME/.env" ] && [ -s "$RUNTIME/compose.yaml" ]; then
|
|
cp "$RUNTIME/.env" "$RUNTIME/.env.previous"
|
|
cp "$RUNTIME/compose.yaml" "$RUNTIME/compose.previous.yaml"
|
|
HAD_PREVIOUS=true
|
|
fi
|
|
rollback() {
|
|
if [ "$HAD_PREVIOUS" = true ]; then
|
|
cp "$RUNTIME/.env.previous" "$RUNTIME/.env"
|
|
cp "$RUNTIME/compose.previous.yaml" "$RUNTIME/compose.yaml"
|
|
docker compose --project-directory "$RUNTIME" --env-file "$RUNTIME/.env" -f "$RUNTIME/compose.yaml" up -d --force-recreate backend
|
|
echo "Previous backend release restored; inspect its health."
|
|
else
|
|
docker compose --project-directory "$RUNTIME" --env-file "$RUNTIME/.env" -f "$RUNTIME/compose.yaml" stop backend || true
|
|
echo "First deployment failed; backend stopped."
|
|
fi
|
|
}
|
|
cp "$SOURCE/compose.yaml" "$RUNTIME/compose.next.yaml"
|
|
printf 'IMAGE_TAG=%s\n' "$TAG" > "$RUNTIME/.env.next"
|
|
if ! docker compose --project-directory "$RUNTIME" --env-file "$RUNTIME/.env.next" -f "$RUNTIME/compose.next.yaml" config --quiet; then
|
|
echo "Compose validation failed; running backend untouched" >&2; exit 1
|
|
fi
|
|
mv "$RUNTIME/compose.next.yaml" "$RUNTIME/compose.yaml"
|
|
mv "$RUNTIME/.env.next" "$RUNTIME/.env"
|
|
if ! docker compose --project-directory "$RUNTIME" --env-file "$RUNTIME/.env" -f "$RUNTIME/compose.yaml" up -d --force-recreate backend; then rollback; exit 1; fi
|
|
CID=$(docker compose --project-directory "$RUNTIME" --env-file "$RUNTIME/.env" -f "$RUNTIME/compose.yaml" ps -q backend)
|
|
for attempt in $(seq 1 30); do
|
|
HEALTH=$(docker inspect --format '{{.State.Health.Status}}' "$CID" 2>/dev/null || true)
|
|
if [ "$HEALTH" = healthy ]; then echo "Backend healthy: $TAG"; exit 0; fi
|
|
sleep 2
|
|
done
|
|
echo "Backend health failed; rolling back" >&2
|
|
rollback
|
|
exit 1
|