install-durable-prod-env.sh79 lines · main
| 1 | #!/usr/bin/env bash |
| 2 | # One-time (or after secret rotation): write durable env for safe-redeploy-service.sh |
| 3 | # |
| 4 | # Prefer dumping from a *healthy* API container so Dokploy-injected secrets |
| 5 | # (Mittera, Polar, OAuth, …) are kept — not only the short bootstrap .env. |
| 6 | # |
| 7 | # On France: |
| 8 | # bash scripts/install-durable-prod-env.sh |
| 9 | # # or with an explicit container: |
| 10 | # bash scripts/install-durable-prod-env.sh briven-brivenfrance-uilsk6-api-1 |
| 11 | |
| 12 | set -euo pipefail |
| 13 | |
| 14 | OUT="${BRIVEN_DURABLE_ENV:-/etc/dokploy/compose/briven-brivenfrance-uilsk6/.env.prod}" |
| 15 | CONTAINER="${1:-briven-brivenfrance-uilsk6-api-1}" |
| 16 | BOOTSTRAP="${BRIVEN_BOOTSTRAP_ENV:-/opt/briven_deploy/infra/dokploy/.env}" |
| 17 | mkdir -p "$(dirname "$OUT")" |
| 18 | |
| 19 | TMP="$(mktemp)" |
| 20 | trap 'rm -f "$TMP"' EXIT |
| 21 | |
| 22 | if docker ps --format '{{.Names}}' | grep -qx "$CONTAINER"; then |
| 23 | echo "dumping env from healthy container: $CONTAINER" |
| 24 | docker inspect "$CONTAINER" --format '{{range .Config.Env}}{{println .}}{{end}}' >"$TMP" |
| 25 | else |
| 26 | echo "container $CONTAINER not running — using bootstrap only: $BOOTSTRAP" |
| 27 | if [[ ! -f "$BOOTSTRAP" ]]; then |
| 28 | echo "error: no container and no bootstrap env" |
| 29 | exit 1 |
| 30 | fi |
| 31 | # strip comments for env-file compatibility |
| 32 | grep -v '^\s*#' "$BOOTSTRAP" | grep -v '^\s*$' >"$TMP" || true |
| 33 | fi |
| 34 | |
| 35 | # Force domain origins |
| 36 | { |
| 37 | grep -vE '^(BRIVEN_WEB_ORIGIN|BRIVEN_API_ORIGIN|BRIVEN_DOMAIN)=' "$TMP" || true |
| 38 | echo "BRIVEN_DOMAIN=briven.tech" |
| 39 | echo "BRIVEN_WEB_ORIGIN=https://briven.tech" |
| 40 | echo "BRIVEN_API_ORIGIN=https://api.briven.tech" |
| 41 | } >"${TMP}.2" |
| 42 | mv "${TMP}.2" "$TMP" |
| 43 | |
| 44 | # Overlay live doltgres password into DATABASE URLs if present |
| 45 | if docker ps --format '{{.Names}}' | grep -qx 'briven-brivenfrance-uilsk6-doltgres-1'; then |
| 46 | PW="$( |
| 47 | docker inspect briven-brivenfrance-uilsk6-doltgres-1 \ |
| 48 | --format '{{range .Config.Env}}{{println .}}{{end}}' \ |
| 49 | | sed -n 's/^DOLTGRES_PASSWORD=//p' |
| 50 | )" |
| 51 | if [[ -n "$PW" ]]; then |
| 52 | python3 - "$TMP" "$PW" <<'PY' |
| 53 | import sys, re |
| 54 | path, pw = sys.argv[1], sys.argv[2] |
| 55 | lines = open(path).read().splitlines() |
| 56 | out = [] |
| 57 | have = set() |
| 58 | for line in lines: |
| 59 | if "=" not in line or line.strip().startswith("#"): |
| 60 | out.append(line) |
| 61 | continue |
| 62 | k, v = line.split("=", 1) |
| 63 | have.add(k) |
| 64 | if k == "BRIVEN_DOLTGRES_PASSWORD": |
| 65 | v = pw |
| 66 | if k in ("BRIVEN_DATABASE_URL", "BRIVEN_ENGINE_DATABASE_URL", "BRIVEN_DATA_PLANE_URL"): |
| 67 | db = "briven_engine" if "ENGINE" in k else "briven_control" |
| 68 | v = f"postgres://postgres:{pw}@doltgres:5432/{db}?sslmode=disable" |
| 69 | out.append(f"{k}={v}") |
| 70 | if "BRIVEN_DOLTGRES_PASSWORD" not in have: |
| 71 | out.append(f"BRIVEN_DOLTGRES_PASSWORD={pw}") |
| 72 | open(path, "w").write("\n".join(out) + "\n") |
| 73 | PY |
| 74 | fi |
| 75 | fi |
| 76 | |
| 77 | install -m 600 "$TMP" "$OUT" |
| 78 | echo "wrote $OUT (mode 600, $(wc -l <"$OUT") lines)" |
| 79 | echo "use: scripts/safe-redeploy-service.sh api web docs" |