#!/usr/bin/env bash set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" compose_template="$repo_root/deploy/templates/docker-compose.yaml" env_template="$repo_root/deploy/templates/.env.template" create_script="$repo_root/deploy/create-instance.sh" fail() { echo "$1" >&2 exit 1 } [[ -f "$compose_template" ]] || fail "deploy/templates/docker-compose.yaml must exist." [[ -f "$env_template" ]] || fail "deploy/templates/.env.template must exist." [[ -f "$create_script" ]] || fail "deploy/create-instance.sh must exist." grep -Fq "TRAEFIK_PUBLIC_NETWORK=traefik-public" "$env_template" \ || fail ".env template must define TRAEFIK_PUBLIC_NETWORK=traefik-public." grep -Fq "TRAEFIK_ENTRYPOINT=websecure" "$env_template" \ || fail ".env template must define TRAEFIK_ENTRYPOINT=websecure." grep -Fq "TRAEFIK_CERT_RESOLVER=myresolver" "$env_template" \ || fail ".env template must define TRAEFIK_CERT_RESOLVER=myresolver." grep -Fq "SOURCE_ROOT=../.." "$env_template" \ || fail ".env template must define SOURCE_ROOT for compose build context." grep -Fq "traefik.enable=true" "$compose_template" \ || fail "gateway must enable Traefik docker provider labels." grep -Fq 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-gateway.rule=Host(`${PUBLIC_HOST}`)' "$compose_template" \ || fail "gateway must route the public host through Traefik." grep -Fq 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-gateway.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}' "$compose_template" \ || fail "gateway router must use the configured Traefik entrypoint." grep -Fq 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-gateway.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-myresolver}' "$compose_template" \ || fail "gateway router must configure the TLS cert resolver." grep -Fq 'traefik.http.services.${COMPOSE_PROJECT_NAME}-gateway.loadbalancer.server.port=80' "$compose_template" \ || fail "gateway service must expose internal port 80 to Traefik." grep -Fq 'traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK:-traefik-public}' "$compose_template" \ || fail "gateway must pin Traefik to the public network." grep -Fq 'context: ${SOURCE_ROOT:-../..}' "$compose_template" \ || fail "public front builds must use SOURCE_ROOT so TARGET_DIR can live outside the repo." grep -Fq '${SOURCE_ROOT:-../..}/adminfront/seed-tenant.csv:/app/seed-tenant.csv:ro' "$compose_template" \ || fail "backend seed volume must use SOURCE_ROOT so TARGET_DIR can live outside the repo." grep -Eq 'gateway:[[:space:]]*$' "$compose_template" \ || fail "gateway service must exist." grep -Fq -- "- traefik_public" "$compose_template" \ || fail "public-facing services must join the external Traefik public network." grep -Fq 'external: true' "$compose_template" \ || fail "Traefik public network must be declared as external." grep -Fq 'name: ${TRAEFIK_PUBLIC_NETWORK:-traefik-public}' "$compose_template" \ || fail "Traefik public network name must be configurable." for service in adminfront devfront orgfront; do grep -Fq "traefik.http.routers.\${COMPOSE_PROJECT_NAME}-${service}.rule=Host(" "$compose_template" \ || fail "$service must expose a Traefik host router." grep -Fq "traefik.http.services.\${COMPOSE_PROJECT_NAME}-${service}.loadbalancer.server.port=" "$compose_template" \ || fail "$service must declare its internal Traefik service port." done grep -Fq 'TRAEFIK_PUBLIC_NETWORK' "$create_script" \ || fail "create-instance must know about the Traefik public network." grep -Fq 'docker network create "$TRAEFIK_PUBLIC_NETWORK"' "$create_script" \ || fail "create-instance must create the Traefik public network when missing." tmp_dir="$(mktemp -d)" trap 'rm -rf "$tmp_dir"' EXIT cp "$compose_template" "$tmp_dir/docker-compose.yaml" cp "$env_template" "$tmp_dir/.env" sed -i 's/{{INSTANCE_NAME}}/policy/g; s/{{PORT_PREFIX}}/26/g' "$tmp_dir/.env" docker compose --env-file "$tmp_dir/.env" -f "$tmp_dir/docker-compose.yaml" config >/dev/null