Deploy script builds and pushes images to Gitea registry, then triggers Portainer stack redeployment via API. Includes preflight checks for branch and uncommitted changes. Also renames prod DB volume to avoid conflicts with dev and changes frontend port to 9080. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
82 lines
3.2 KiB
Bash
Executable File
82 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# ── Configuration ──────────────────────────────────────────────
|
|
REGISTRY="gitea.nerdboden.de"
|
|
OWNER="thefurya"
|
|
IMAGES=("nuzlocke-tracker-api" "nuzlocke-tracker-frontend")
|
|
DOCKERFILES=("backend/Dockerfile.prod" "frontend/Dockerfile.prod")
|
|
CONTEXTS=("./backend" "./frontend")
|
|
|
|
PORTAINER_URL="${PORTAINER_URL:-https://portainer.nerdboden.de}"
|
|
PORTAINER_API_KEY="${PORTAINER_API_KEY:-}"
|
|
PORTAINER_STACK_ID="${PORTAINER_STACK_ID:-}"
|
|
PORTAINER_ENDPOINT_ID="${PORTAINER_ENDPOINT_ID:-1}"
|
|
|
|
# ── Helpers ────────────────────────────────────────────────────
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
info() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
|
error() { echo -e "${RED}[✗]${NC} $1"; exit 1; }
|
|
|
|
# ── Preflight checks ──────────────────────────────────────────
|
|
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
if [[ "$BRANCH" != "main" ]]; then
|
|
warn "You are on branch '$BRANCH', not 'main'."
|
|
read -rp "Continue anyway? [y/N] " confirm
|
|
[[ "$confirm" =~ ^[Yy]$ ]] || exit 0
|
|
fi
|
|
|
|
if ! git diff --quiet || ! git diff --cached --quiet; then
|
|
warn "You have uncommitted changes."
|
|
read -rp "Continue anyway? [y/N] " confirm
|
|
[[ "$confirm" =~ ^[Yy]$ ]] || exit 0
|
|
fi
|
|
|
|
# ── Build and push images ─────────────────────────────────────
|
|
for i in "${!IMAGES[@]}"; do
|
|
IMAGE="${REGISTRY}/${OWNER}/${IMAGES[$i]}:latest"
|
|
info "Building ${IMAGES[$i]}..."
|
|
docker build -t "$IMAGE" -f "${DOCKERFILES[$i]}" "${CONTEXTS[$i]}"
|
|
info "Pushing ${IMAGES[$i]}..."
|
|
docker push "$IMAGE"
|
|
done
|
|
|
|
info "All images built and pushed."
|
|
|
|
# ── Trigger Portainer redeployment ─────────────────────────────
|
|
if [[ -z "$PORTAINER_API_KEY" ]]; then
|
|
warn "PORTAINER_API_KEY not set — skipping Portainer redeployment."
|
|
warn "Set it in your environment or .env.deploy file to enable auto-redeploy."
|
|
exit 0
|
|
fi
|
|
|
|
if [[ -z "$PORTAINER_STACK_ID" ]]; then
|
|
warn "PORTAINER_STACK_ID not set — skipping Portainer redeployment."
|
|
warn "Find your stack ID in Portainer and set it in your environment."
|
|
exit 0
|
|
fi
|
|
|
|
info "Fetching stack file from Portainer..."
|
|
STACK_FILE=$(curl -sf \
|
|
-H "X-API-Key: ${PORTAINER_API_KEY}" \
|
|
"${PORTAINER_URL}/api/stacks/${PORTAINER_STACK_ID}/file") \
|
|
|| error "Failed to fetch stack file from Portainer."
|
|
|
|
STACK_CONTENT=$(echo "$STACK_FILE" | jq -r '.StackFileContent')
|
|
|
|
info "Triggering stack redeployment..."
|
|
curl -sf -X PUT \
|
|
-H "X-API-Key: ${PORTAINER_API_KEY}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$(jq -n --arg content "$STACK_CONTENT" '{"pullImage": true, "stackFileContent": $content}')" \
|
|
"${PORTAINER_URL}/api/stacks/${PORTAINER_STACK_ID}?endpointId=${PORTAINER_ENDPOINT_ID}" \
|
|
> /dev/null \
|
|
|| error "Failed to trigger Portainer redeployment."
|
|
|
|
info "Stack redeployment triggered successfully!"
|