diff --git a/LIVE_DEPLOYMENT_RUNBOOK.md b/LIVE_DEPLOYMENT_RUNBOOK.md index 838a594..7113b00 100644 --- a/LIVE_DEPLOYMENT_RUNBOOK.md +++ b/LIVE_DEPLOYMENT_RUNBOOK.md @@ -1,6 +1,6 @@ # YGIT Controlled Live Deployment Runbook -Version: 1.3 +Version: 1.4 Status: Ready for Controlled Live Validation Owner: YGIT Operations @@ -27,6 +27,7 @@ It does not declare production readiness before real PostgreSQL, Redis, GitHub, - Set `YGIT_DEPLOYMENT_CONFIG_VERSION=1.0.0`. - Set `KEYCLOAK_POST_LOGOUT_REDIRECT_URI=https://ygit.net`. - Store `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB` only in Coolify secret storage. +- Use the Coolify-compatible required-variable form `${POSTGRES_USER:?}`, `${POSTGRES_PASSWORD:?}`, and `${POSTGRES_DB:?}`; do not append explanatory fallback text after `:?`. - Remove any user-defined `COOLIFY_BRANCH` override and allow Coolify to provide plain `main`. - Revert provider mode to `disabled` immediately when provider behavior is uncertain. - Do not integrate AG-001 during this validation. AG-001 remains reserved for future App Engine work. @@ -80,6 +81,8 @@ KEYCLOAK_POST_LOGOUT_REDIRECT_URI=https://ygit.net Coolify must provide `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB` as secrets. The `DATABASE_URL` value must use the same database identity. +Before redeploy, verify both Production and Preview values of `WORKER_PROVIDER_EXECUTION_MODE` are `disabled`. + Confirm the API and worker use the same Git commit and production environment. ## Phase 3 — Post-Redeploy Disabled-Mode Smoke diff --git a/backend/tests/test_coolify_production_configuration.py b/backend/tests/test_coolify_production_configuration.py index 76c34c8..4bd6060 100644 --- a/backend/tests/test_coolify_production_configuration.py +++ b/backend/tests/test_coolify_production_configuration.py @@ -29,21 +29,16 @@ def test_hard_coded_postgres_credentials_are_removed() -> None: assert "POSTGRES_DB: ygit" not in source -def test_postgres_compose_variables_are_required() -> None: +def test_postgres_required_variables_have_no_literal_fallback() -> None: source = compose_text() - assert ( - '${POSTGRES_USER:?POSTGRES_USER is required}' - in source - ) - assert ( - '${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}' - in source - ) - assert ( - '${POSTGRES_DB:?POSTGRES_DB is required}' - in source - ) + for name in ( + "POSTGRES_USER", + "POSTGRES_PASSWORD", + "POSTGRES_DB", + ): + assert f"${{{name}:?}}" in source + assert f"${{{name}:?{name} is required}}" not in source def test_postgres_healthcheck_uses_runtime_database_identity() -> None: @@ -203,3 +198,4 @@ def test_runbook_locks_controlled_redeploy_identity() -> None: ) assert "WORKER_PROVIDER_EXECUTION_MODE=disabled" in source assert "Coolify secret storage" in source + assert "Coolify-compatible required-variable form" in source diff --git a/docker-compose.yml b/docker-compose.yml index 36015d0..1345beb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,9 +43,9 @@ services: image: postgres:16-alpine container_name: ygit-postgres environment: - POSTGRES_USER: "${POSTGRES_USER:?POSTGRES_USER is required}" - POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}" - POSTGRES_DB: "${POSTGRES_DB:?POSTGRES_DB is required}" + POSTGRES_USER: "${POSTGRES_USER:?}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?}" + POSTGRES_DB: "${POSTGRES_DB:?}" volumes: - ygit_postgres_data:/var/lib/postgresql/data healthcheck: