#!/bin/sh set -eu bundle_path=${1:-} deployment_directory=${2:-/opt/shd-build-production} if [ -z "$bundle_path" ] || [ ! -f "$bundle_path" ]; then echo "Usage: bootstrap-production.sh [deployment-directory]" >&2 exit 2 fi bundle_path=$(readlink -f "$bundle_path") compose_file="$deployment_directory/compose.production.yml" deploy_environment="$deployment_directory/.env.deploy" volume_bundle_path=/app/data/.production-bootstrap-import.json remove_volume_bundle=false compose() { docker compose --env-file "$deploy_environment" -f "$compose_file" "$@" } cleanup() { status=$? trap - EXIT HUP INT TERM set +e if [ "$remove_volume_bundle" = true ]; then compose run --rm --no-deps --entrypoint rm --user root app -f "$volume_bundle_path" fi if ! compose up -d --no-build app scheduler; then status=1; fi exit "$status" } trap cleanup EXIT trap 'exit 129' HUP trap 'exit 130' INT trap 'exit 143' TERM echo "Stopping production before the one-time database bootstrap." compose stop scheduler app compose create app >/dev/null app_container=$(compose ps --all --quiet app) if [ -z "$app_container" ]; then echo "The stopped production app container could not be found." >&2 exit 1 fi docker cp "$bundle_path" "$app_container:$volume_bundle_path" remove_volume_bundle=true compose run --rm --no-deps --entrypoint sh --user root app -c \ 'chown shd-runtime:node "$1" && chmod 600 "$1"' sh "$volume_bundle_path" compose run --rm --no-deps \ -e ALLOW_PRODUCTION_BOOTSTRAP=true \ app node scripts/environment-bootstrap-import.mjs \ "$volume_bundle_path" --target production --confirm-empty-target-replace echo "Production bootstrap completed."