#!/usr/bin/env bash set -euo pipefail usage() { cat <<'EOF' Deploy a pre-built APP_IMAGE to one or more AndyTranscribe directories. Environment: APP_IMAGE Required. e.g. gitea.z00.nu/ben/andytranscribe:abc1234 DEPLOY_PATHS Comma-separated instance directories (default: current directory) DEPLOY_SHA Optional git SHA to hard-reset each directory to (CI sets this) GIT_PULL When 1 (default) and DEPLOY_SHA is empty, run git pull --ff-only Usage: APP_IMAGE=gitea.z00.nu/ben/andytranscribe:tag DEPLOY_PATHS=$HOME/andyTranscibe ./scripts/deploy-production.sh EOF } IMAGE="${APP_IMAGE:-${1:-}}" if [[ -z "${IMAGE}" ]]; then usage >&2 exit 1 fi PATHS_CSV="${DEPLOY_PATHS:-${2:-.}}" GIT_PULL="${GIT_PULL:-1}" DEPLOY_SHA="${DEPLOY_SHA:-}" IFS=',' read -r -a DIRS <<< "${PATHS_CSV}" for dir in "${DIRS[@]}"; do dir="${dir#"${dir%%[![:space:]]*}"}" dir="${dir%"${dir##*[![:space:]]}"}" if [[ ! -d "${dir}" ]]; then echo "Missing instance directory: ${dir}" >&2 exit 1 fi name="$(basename "${dir}")" echo "==> Deploying ${IMAGE} in ${dir}" ( cd "${dir}" if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then if [[ -n "${DEPLOY_SHA}" ]]; then git fetch --force origin "${DEPLOY_SHA}" git checkout --force --detach "${DEPLOY_SHA}" git reset --hard "${DEPLOY_SHA}" # Drop local edits/hot-patches; keep runtime data and secrets. git clean -fd \ --exclude=database/ \ --exclude=storage/ \ --exclude=.env \ --exclude=.env.* elif [[ "${GIT_PULL}" == "1" ]]; then git pull --ff-only fi fi export APP_IMAGE="${IMAGE}" export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-${name,,}}" compose_files=(-f docker-compose.yml) if [[ -f compose.z00.yaml ]]; then compose_files+=(-f compose.z00.yaml) fi if grep -q '^APP_IMAGE=' .env 2>/dev/null; then sed -i "s|^APP_IMAGE=.*|APP_IMAGE=${IMAGE}|" .env else printf '\nAPP_IMAGE=%s\n' "${IMAGE}" >> .env fi docker compose "${compose_files[@]}" pull app queue reverb docker compose "${compose_files[@]}" up -d --remove-orphans docker compose "${compose_files[@]}" ps app_port="$(awk -F= '/^APP_HOST_PORT=/ {print $2; exit}' .env 2>/dev/null || true)" app_port="${app_port:-18080}" health_url="http://127.0.0.1:${app_port}/up" echo "waiting for ${health_url}" ok=0 for _ in $(seq 1 45); do if curl -fsS "${health_url}" >/dev/null 2>&1; then echo "healthy" ok=1 break fi sleep 2 done if [[ "${ok}" -ne 1 ]]; then echo "ERROR: health check failed for ${name}" >&2 exit 1 fi # Hit /login as the public HTTPS edge would (trustProxies needs forwarded proto). app_url="$(awk -F= '/^APP_URL=/ {print $2; exit}' .env 2>/dev/null || true)" app_url="${app_url:-https://transcribe.z00.nu}" public_host="$(python3 - <&2 exit 1 fi echo "asset check ok: ${asset_scheme:-no absolute css url (relative/ok)}" ) done echo "Deploy complete: ${IMAGE}"