From f36e237c84eafd66b8a9b19033a5ec41d2b7d5e8 Mon Sep 17 00:00:00 2001 From: Tyler Gillispie Date: Sun, 23 Aug 2026 18:50:55 -0700 Subject: [PATCH] fix(infra): adopt stack.env naming convention and align PostgreSQL 18 volume mount path --- .gitignore | 2 ++ COMPOSE_CONVENTIONS.md | 13 +++++++++++++ infra/setup.ts | 29 ++++++++++++++++++----------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 315ecbb..f71d5fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ spire_ffi/target/ .env* infra/.env* +stack.env* +infra/stack.env* infra/compose*.yml .DS_Store node_modules/ diff --git a/COMPOSE_CONVENTIONS.md b/COMPOSE_CONVENTIONS.md index 105b225..cf47203 100644 --- a/COMPOSE_CONVENTIONS.md +++ b/COMPOSE_CONVENTIONS.md @@ -25,6 +25,19 @@ across our infrastructure. device: ${_DATA_PATH} o: bind ``` +- **PostgreSQL 18+ Volume Mount Standard:** + - Starting in PostgreSQL 18+, official images expect the root volume mount at + `/var/lib/postgresql` (NOT `/var/lib/postgresql/data`). This allows + PostgreSQL to create versioned cluster directories + (`/var/lib/postgresql//...`) and execute `pg_upgrade --link` + cleanly without crossing mount point boundaries: + ```yaml + volumes: + - auth-db-data:/var/lib/postgresql + ``` +- **Environment File Naming (`stack.env`):** + - Application stacks use `stack.env` as the standard environment filename in + Compose declarations (`env_file: stack.env`). - **Zero-Trust Inter-Process Sockets:** - Sockets shared across stacks (e.g., the SPIFFE Workload API `agent.sock`) MUST use a **named volume** (`spire-socket`). diff --git a/infra/setup.ts b/infra/setup.ts index 81eed1e..bbb7a3a 100644 --- a/infra/setup.ts +++ b/infra/setup.ts @@ -3,7 +3,7 @@ import { Input, Secret, Select } from "jsr:@cliffy/prompt@1.0.0-rc.7"; import * as colors from "jsr:@std/fmt@0.225.2/colors"; import * as path from "jsr:@std/path@0.225.2"; -const ENV_PATH = path.join("infra", ".env"); +const ENV_PATH = path.join("infra", "stack.env"); const SPIRE_ENV_PATH = path.join("infra", ".env.spire"); const COMPOSE_PATH = path.join("infra", "compose.yml"); const SPIRE_COMPOSE_PATH = path.join("infra", "compose.spire.yml"); @@ -30,7 +30,14 @@ const DEFAULT_AUTH_CONFIG: AuthSetupConfig = { export async function readEnv(): Promise> { const config: Partial = {}; - for (const filePath of [ENV_PATH, SPIRE_ENV_PATH]) { + for ( + const filePath of [ + ENV_PATH, + path.join("infra", ".env"), + SPIRE_ENV_PATH, + path.join("infra", "stack.env.spire"), + ] + ) { try { const text = await Deno.readTextFile(filePath); for (const line of text.split("\n")) { @@ -96,7 +103,7 @@ export function generateDockerCompose(): string { services: auth-api: image: \${REG}/library/auth-yes-api:latest - env_file: .env + env_file: stack.env labels: - "traefik.enable=true" - "traefik.docker.network=traefik-net" @@ -122,7 +129,7 @@ services: - POSTGRES_PASSWORD=\${POSTGRES_PASSWORD} - POSTGRES_DB=\${POSTGRES_DB} volumes: - - auth-db-data:/var/lib/postgresql/data + - auth-db-data:/var/lib/postgresql networks: - default @@ -292,7 +299,7 @@ export async function generateAuthSetupFiles( "1. Deploy SPIRE Stack:\n" + " podman-compose --project-name spire --env-file infra/.env.spire -f infra/compose.spire.yml up -d\n\n" + "2. Deploy Auth-Yes Stack:\n" + - " podman-compose --project-name auth-yes --env-file infra/.env -f infra/compose.yml up -d\n", + " podman-compose --project-name auth-yes --env-file infra/stack.env -f infra/compose.yml up -d\n", ), ); } @@ -521,7 +528,7 @@ export async function runSetupWizard(): Promise { ); console.log( colors.cyan( - "podman-compose --project-name auth-yes --env-file infra/.env -f infra/compose.yml up -d\n", + "podman-compose --project-name auth-yes --env-file infra/stack.env -f infra/compose.yml up -d\n", ), ); } catch (error) { @@ -668,7 +675,7 @@ if (import.meta.main) { ); console.log( colors.cyan( - "podman-compose --project-name auth-yes --env-file infra/.env -f infra/compose.yml up -d\n", + "podman-compose --project-name auth-yes --env-file infra/stack.env -f infra/compose.yml up -d\n", ), ); } catch (error) { @@ -746,7 +753,7 @@ if (import.meta.main) { ); console.log( colors.bold( - colors.green(" STACK 1: Auth-Yes Environment (infra/.env)"), + colors.green(" STACK 1: Auth-Yes Environment (infra/stack.env)"), ), ); console.log( @@ -954,7 +961,7 @@ if (import.meta.main) { ); console.log( colors.cyan( - "podman-compose --project-name auth-yes --env-file infra/.env -f infra/compose.yml up -d", + "podman-compose --project-name auth-yes --env-file infra/stack.env -f infra/compose.yml up -d", ), ); @@ -996,12 +1003,12 @@ if (import.meta.main) { ); console.log( colors.cyan( - "podman-compose --project-name auth-yes --env-file infra/.env -f infra/compose.yml pull", + "podman-compose --project-name auth-yes --env-file infra/stack.env -f infra/compose.yml pull", ), ); console.log( colors.cyan( - "podman-compose --project-name auth-yes --env-file infra/.env -f infra/compose.yml up -d\n", + "podman-compose --project-name auth-yes --env-file infra/stack.env -f infra/compose.yml up -d\n", ), ); });