#!/usr/bin/env bash # Run on the deployment host: release.sh /home/workspace/veyra set -euo pipefail root="${1:?deployment directory required}" sha="${2:?commit SHA required}" [[ "$root" == /* && "$root" != / && "$root" != *[!a-zA-Z0-9_/-]* ]] || exit 2 [[ "$sha" =~ ^[0-9a-f]{40}$ ]] || exit 2 release="$root/releases/$sha" image="sundynix/veyra:$sha" cd "$root" # Serialize releases even when several master commits queue up. exec 9> .deploy.lock flock -w 600 9 if [[ ! -s configs/.env ]]; then echo 'Missing server configs/.env (or VEYRA_ENV_FILE bootstrap secret)' >&2; exit 1; fi (cd "$release" && sha256sum -c image.tar.gz.sha256) gunzip -c "$release/image.tar.gz" | docker load mkdir -p logs docker run --rm --user 0:0 --entrypoint sh -v "$root/logs:/app/logs" "$image" -c 'chown 10001:10001 /app/logs' previous='' if [[ -s .current-image ]]; then previous="$(cat .current-image)" [[ "$previous" =~ ^sundynix/veyra:[0-9a-f]{40}$ ]] || exit 2 fi # Keep the previous Compose file as well as the previously healthy image. if [[ -f docker-compose.yml ]]; then cp docker-compose.yml "$release/previous-compose.yml"; fi cp "$release/docker-compose.yml" docker-compose.yml export VEYRA_IMAGE="$image" # Use an empty interpolation file: application secrets are only read via raw env_file. compose() { docker compose --env-file /dev/null -f "$root/docker-compose.yml" "$@"; } if ! compose run --rm --no-deps app -command db-create || ! compose run --rm --no-deps app -command db-migrate; then if [[ -f "$release/previous-compose.yml" ]]; then cp "$release/previous-compose.yml" docker-compose.yml; fi echo 'Database preparation failed; existing application was not replaced' >&2 exit 1 fi if compose up -d --no-build --wait --wait-timeout 120; then printf '%s\n' "$image" > .current-image.tmp mv .current-image.tmp .current-image rm -f "$release/image.tar.gz" echo "Veyra deployed: $sha" else echo 'New application failed readiness; restoring previous application' >&2 if [[ -n "$previous" && -f "$release/previous-compose.yml" ]]; then cp "$release/previous-compose.yml" docker-compose.yml export VEYRA_IMAGE="$previous" compose up -d --no-build --wait --wait-timeout 120 else compose stop app fi # Schema migrations are never automatically undone. exit 1 fi