Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion LIVE_DEPLOYMENT_RUNBOOK.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# YGIT Controlled Live Deployment Runbook

Version: 1.3
Version: 1.4
Status: Ready for Controlled Live Validation
Owner: YGIT Operations

Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down
22 changes: 9 additions & 13 deletions backend/tests/test_coolify_production_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading