who_need_help/scripts/compose.sh

94 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
env_file=${1:-"$ROOT/.env"}
shift || true
if [[ "$env_file" != /* ]]; then
env_file="$ROOT/$env_file"
fi
if [[ ! -f "$env_file" ]]; then
echo "Deployment environment does not exist: $env_file" >&2
exit 1
fi
read_env_value() {
local key=$1
if [[ -v "$key" ]]; then
printf '%s' "${!key}"
return
fi
awk -v key="$key" '
index($0, key "=") == 1 {
print substr($0, length(key) + 2)
found = 1
exit
}
END { if (!found) exit 1 }
' "$env_file"
}
deployment_target=$(read_env_value DEPLOYMENT_TARGET 2>/dev/null || printf compose)
deployment_environment=$(read_env_value DEPLOYMENT_ENV 2>/dev/null || printf development)
database_mode=$(read_env_value DATABASE_MODE 2>/dev/null || printf container)
app_topology=$(read_env_value APP_TOPOLOGY 2>/dev/null || printf split)
project=$(read_env_value COMPOSE_PROJECT_NAME 2>/dev/null || printf who_need_help)
[[ "$deployment_target" == compose ]] || {
echo "scripts/compose.sh requires DEPLOYMENT_TARGET=compose." >&2
exit 1
}
case "$deployment_environment" in
development | production) ;;
*) echo "DEPLOYMENT_ENV must be development or production." >&2; exit 1 ;;
esac
case "$database_mode" in
container | external) ;;
*) echo "DATABASE_MODE must be container or external." >&2; exit 1 ;;
esac
database_url=$(read_env_value DATABASE_URL 2>/dev/null || true)
: "${database_url:?Set DATABASE_URL in $env_file}"
if [[ "$database_mode" == container ]]; then
postgres_db=$(read_env_value POSTGRES_DB 2>/dev/null || true)
postgres_user=$(read_env_value POSTGRES_USER 2>/dev/null || true)
postgres_password=$(read_env_value POSTGRES_PASSWORD 2>/dev/null || true)
: "${postgres_db:?Set POSTGRES_DB for DATABASE_MODE=container}"
: "${postgres_user:?Set POSTGRES_USER for DATABASE_MODE=container}"
: "${postgres_password:?Set POSTGRES_PASSWORD for DATABASE_MODE=container}"
fi
case "$app_topology" in
compact | split) ;;
*) echo "APP_TOPOLOGY must be compact or split." >&2; exit 1 ;;
esac
compose=(
docker compose
--project-directory "$ROOT"
--project-name "$project"
--env-file "$env_file"
--file "$ROOT/compose.yaml"
)
if [[ "$database_mode" == external ]]; then
compose+=(--file "$ROOT/compose.external-db.yaml")
fi
if [[ "$app_topology" == compact ]]; then
compose+=(--file "$ROOT/compose.compact.yaml" --profile compact)
fi
if [[ "$deployment_environment" == production ]]; then
compose+=(--file "$ROOT/compose.production.yaml")
fi
exec "${compose[@]}" "$@"