summaryrefslogtreecommitdiff
path: root/scripts/start-debug.sh
blob: bf18de522df3d8482eb113884701f40b4a17aa03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env bash

set -euo pipefail

script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_dir="$(cd -- "$script_dir/.." && pwd)"
env_file="${AIGW_DEBUG_ENV_FILE:-$repo_dir/.env.debug}"

log() {
  printf '[aigw-debug] %s\n' "$*"
}

fail() {
  printf '[aigw-debug] error: %s\n' "$*" >&2
  exit 1
}

command -v docker >/dev/null 2>&1 || fail "docker is not installed"
docker info >/dev/null 2>&1 || fail "cannot access Docker; check that the daemon is running and your user belongs to the docker group"

if [[ ! -f "$env_file" ]]; then
  command -v openssl >/dev/null 2>&1 || fail "openssl is required to generate local credentials"
  credential_key="$(openssl rand -base64 32 | tr -d '\n')"
  admin_token="aigw-admin-$(openssl rand -hex 24)"
  postgres_password="$(openssl rand -hex 24)"
  umask 077
  {
    printf 'AIGW_SERVER_ADDRESS=:8080\n'
    printf 'AIGW_PUBLIC_ADDRESS=:8080\n'
    printf 'AIGW_ADMIN_ADDRESS=:8081\n'
    printf 'AIGW_WEBHOOK_ADDRESS=:8082\n'
    printf 'AIGW_OPERATIONS_ADDRESS=:9090\n'
    printf 'AIGW_TRUSTED_PROXY_CIDRS=\n'
    printf 'AIGW_REQUIRE_HTTPS=false\n'
    printf 'AIGW_DEPLOYMENT_REGION=\n'
    printf 'AIGW_POSTGRES_USER=aigw\n'
    printf 'AIGW_POSTGRES_PASSWORD=%s\n' "$postgres_password"
    printf 'AIGW_POSTGRES_DB=aigw\n'
    printf 'AIGW_DATABASE_URL=postgres://aigw:%s@127.0.0.1:5432/aigw?sslmode=disable\n' "$postgres_password"
    printf 'AIGW_DATABASE_URL_DOCKER=postgres://aigw:%s@postgres:5432/aigw?sslmode=disable\n' "$postgres_password"
    printf 'AIGW_REDIS_URL=redis://127.0.0.1:6379/0\n'
    printf 'AIGW_REDIS_URL_DOCKER=redis://redis:6379/0\n'
    printf 'AIGW_CREDENTIAL_KEY=%s\n' "$credential_key"
    printf 'AIGW_CREDENTIAL_PREVIOUS_KEYS=\n'
    printf 'AIGW_ADMIN_TOKEN=%s\n' "$admin_token"
    printf 'AIGW_PUBLIC_URL=http://localhost:8081/admin/\n'
    printf 'AIGW_WEBAUTHN_RP_ID=localhost\n'
    printf 'AIGW_WEBAUTHN_ORIGINS=http://localhost:8081\n'
    printf 'AIGW_SMTP_FROM_ADDRESS=no-reply@aigw.local\n'
    printf 'AIGW_SMTP_ADDRESS=127.0.0.1:1025\n'
    printf 'AIGW_SMTP_ADDRESS_DOCKER=mailpit:1025\n'
    printf 'AIGW_SMTP_USERNAME=\n'
    printf 'AIGW_SMTP_PASSWORD=\n'
    printf 'AIGW_STRIPE_API_KEY=rk_test_replace_me\n'
    printf 'AIGW_STRIPE_CLI_API_KEY=rk_test_replace_me\n'
    printf 'AIGW_STRIPE_WEBHOOK_SECRET=whsec_replace_me\n'
    printf 'AIGW_STRIPE_SUCCESS_URL=http://localhost:8081/admin/?topup=success\n'
    printf 'AIGW_STRIPE_CANCEL_URL=http://localhost:8081/admin/?topup=cancel\n'
    printf 'AIGW_STRIPE_PORTAL_RETURN_URL=http://localhost:8081/admin/?billing=portal\n'
    printf 'AIGW_STRIPE_AUTOMATIC_TAX_ENABLED=false\n'
    printf 'AIGW_STRIPE_TAX_REGISTRATION_CONFIRMED=false\n'
    printf 'AIGW_STRIPE_PRODUCT_TAX_CODE=\n'
    printf 'AIGW_SETTLEMENT_SPOOL_PATH=/var/lib/aigw/settlements.jsonl\n'
  } >"$env_file"
  chmod 600 "$env_file"
  log "created $env_file"
fi

# Backfill non-secret deployment settings when an older local environment file
# is reused. Exact legacy localhost values are moved to the split admin port.
sed -i \
  -e 's|^AIGW_PUBLIC_URL=http://localhost:8080/admin/$|AIGW_PUBLIC_URL=http://localhost:8081/admin/|' \
  -e 's|^AIGW_WEBAUTHN_ORIGINS=http://localhost:8080$|AIGW_WEBAUTHN_ORIGINS=http://localhost:8081|' \
  -e 's|^AIGW_STRIPE_SUCCESS_URL=http://localhost:8080/admin/?topup=success$|AIGW_STRIPE_SUCCESS_URL=http://localhost:8081/admin/?topup=success|' \
  -e 's|^AIGW_STRIPE_CANCEL_URL=http://localhost:8080/admin/?topup=cancel$|AIGW_STRIPE_CANCEL_URL=http://localhost:8081/admin/?topup=cancel|' \
  "$env_file"
for setting in \
  'AIGW_PUBLIC_ADDRESS=:8080' \
  'AIGW_ADMIN_ADDRESS=:8081' \
  'AIGW_WEBHOOK_ADDRESS=:8082' \
  'AIGW_OPERATIONS_ADDRESS=:9090' \
  'AIGW_STRIPE_PORTAL_RETURN_URL=http://localhost:8081/admin/?billing=portal' \
  'AIGW_SETTLEMENT_SPOOL_PATH=/var/lib/aigw/settlements.jsonl'; do
  name="${setting%%=*}"
  grep -q "^${name}=" "$env_file" || printf '%s\n' "$setting" >>"$env_file"
done

admin_token="$(sed -n 's/^AIGW_ADMIN_TOKEN=//p' "$env_file" | head -n 1)"
[[ -n "$admin_token" ]] || fail "AIGW_ADMIN_TOKEN is missing from $env_file"
for required_name in AIGW_SERVER_ADDRESS AIGW_POSTGRES_USER AIGW_POSTGRES_PASSWORD AIGW_POSTGRES_DB AIGW_DATABASE_URL_DOCKER AIGW_CREDENTIAL_KEY AIGW_PUBLIC_URL AIGW_WEBAUTHN_RP_ID AIGW_WEBAUTHN_ORIGINS AIGW_SMTP_FROM_ADDRESS AIGW_SMTP_ADDRESS_DOCKER AIGW_STRIPE_API_KEY AIGW_STRIPE_WEBHOOK_SECRET AIGW_STRIPE_SUCCESS_URL AIGW_STRIPE_CANCEL_URL; do
  grep -q "^${required_name}=." "$env_file" || fail "$required_name is missing from $env_file; compare it with .env.control.example"
done

cd "$repo_dir"
if [[ "${AIGW_DEBUG_SKIP_BUILD:-0}" == "1" ]]; then
  log "skipping image build (AIGW_DEBUG_SKIP_BUILD=1)"
else
  build_network="${AIGW_DOCKER_BUILD_NETWORK:-host}"
  log "building gateway image (network: $build_network)"
  docker build --network="$build_network" -t aigw-debug:local .
fi

log "starting PostgreSQL, Redis, Mailpit, and gateway"
if ! docker compose --env-file "$env_file" up -d --no-build --wait --wait-timeout 120; then
  docker compose --env-file "$env_file" ps >&2 || true
  gateway_logs="$(docker compose --env-file "$env_file" logs --no-color --tail=120 aigw 2>&1 || true)"
  printf '%s\n' "$gateway_logs" >&2
  if [[ "$gateway_logs" == *"decrypt credential"* ]]; then
    printf '[aigw-debug] the AIGW_CREDENTIAL_KEY in %s does not match credentials already stored in the PostgreSQL volume\n' "$env_file" >&2
    printf '[aigw-debug] restore the previous key, or explicitly remove the debug volumes if the stored control-plane data is disposable\n' >&2
  fi
  fail "services did not become healthy"
fi

log "services are ready"
printf '\nAdmin UI:    http://localhost:8081/admin/\n'
printf 'Mail inbox:  http://127.0.0.1:8025/\n'
printf 'Health:      http://127.0.0.1:9090/readyz\n'
printf 'Secrets:     %s (mode 0600)\n' "$env_file"
printf '\nLogs:        docker compose --env-file %q logs -f aigw\n' "$env_file"
printf 'Stop:        ./scripts/stop-debug.sh\n'

if grep -q '^AIGW_STRIPE_API_KEY=rk_test_replace_me$' "$env_file" 2>/dev/null; then
  printf '\nStripe uses placeholders. Replace the two Stripe values in %s before testing Checkout.\n' "$env_file"
fi