Skip to content

release: DB-only stacks always 'degraded' (No *_PORT warning) → auto-rollback makes every release report failure #489

Description

@gfargo

What happened

First release of a new DB-only stack (beacon: single postgres:16 service, DB_POSTGRES=true, no HTTP services). Deploy fully succeeded on the VPS — container running, RUN_DB_SCHEMA_ON_DEPLOY applied the schema, PostgreSQL: Ready — then:

⚠ Services: No *_PORT entries found in services.conf
Overall Status: degraded
Passed:  9 / Warning: 1 / Failed:  0
⚠  Health check failed — rolling back to the previous release...
✗  Release failed health checks after deploy

The "rollback" restored a snapshot taken seconds earlier (0 services) and restarted the same healthy container — harmless here, but the release is reported as failed and every future release of this stack will do the same dance.

Root cause chain

  1. lib/health.sh marks the run "degraded" on any warning, and health exits 1 for degraded (degraded) return 1).
  2. release treats any non-zero health exit as failure → auto-rollback.
  3. A DB-only stack structurally cannot have *_PORT health entries — there is no HTTP service. And per validate: DB_PORT rejected — DB_* boolean rule collides with *_PORT numeric rule #487, even the documentary DB_PORT=<num> is rejected by validation, so there is no way to silence the warning.

Net: for DB-only stacks, release --env prod can never report success.

Suggested fixes (any of)

  1. In the services check: if services.conf has zero *_PORT entries but a DB_*=true flag, treat the DB readiness check as the service-health signal and skip the warning (log info instead).
  2. In release: only rollback on unhealthy (exit 2), not degraded (exit 1) — warnings shouldn't undo a deploy.
  3. A HEALTH_ALLOW_NO_SERVICES=true (or similar) opt-out in services.conf for headless/DB-only stacks.

Fix 2 seems right regardless of the others: a warning-triggered rollback of a passing deploy is a worse outcome than surfacing the warning.

Environment

strut v0.43.3 (VPS side updated same run), stack: postgres:16 only, DB_POSTGRES=true, no service ports. Related: #487 (DB_PORT validation), #488 (silent local fallback).

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions