Skip to content

feat: add wait-for-db init container for bundled PostgreSQL#12

Open
o6uoq wants to merge 1 commit intosequinstream:mainfrom
o6uoq:feat/wait-for-db-init-container
Open

feat: add wait-for-db init container for bundled PostgreSQL#12
o6uoq wants to merge 1 commit intosequinstream:mainfrom
o6uoq:feat/wait-for-db-init-container

Conversation

@o6uoq
Copy link
Copy Markdown

@o6uoq o6uoq commented Apr 23, 2026

Problem

When deploying with the bundled PostgreSQL subchart (postgresql.enabled: true), Sequin starts before PostgreSQL is ready to accept connections. The startup script (start_commands.sh) runs Ecto migrations immediately with no retry logic, causing 3+ crash-loop restarts on every fresh install:

Postgrex.Protocol failed to connect: tcp connect (sequin-postgresql:5432): connection refused - :econnrefused
Could not create schema migrations table.

Sequin eventually recovers via Kubernetes restart backoff, but this adds unnecessary delay and noise to every deployment.

Fix

Adds a built-in wait-for-db init container that polls pg_isready until PostgreSQL accepts connections. The init container:

  • Uses the PostgreSQL subchart image (which provides pg_isready)
  • Reuses existing chart helpers (sequin.database.host, sequin.database.port, sequin.database.username) for connection details
  • Inherits the chart's containerSecurityContext settings
  • Runs before any user-defined initContainers
  • Is gated on postgresql.enabled — does not run when using an external database

New value: waitForDB.enabled (default: true)

Changes

File Change
values.yaml Add waitForDB.enabled parameter
templates/_helpers.tpl Add sequin.waitForDB.image helper
templates/deployment.yaml Add conditional init container block

Note: PostgreSQL subchart image tag

The current postgresql subchart dependency (16.x.x) references image tag 17.6.0-debian-12-r4 which may not yet be available on Docker Hub depending on Bitnami's release pipeline timing. During testing we used --set postgresql.image.tag=latest as a workaround. This is a pre-existing issue unrelated to this PR.

Testing

  • helm lint . — passes
  • helm template dry-runs:
    • Default values: init container renders with correct host/port/user
    • postgresql.enabled=false: no init container rendered
    • waitForDB.enabled=false: no init container rendered
    • User-defined initContainers: both render, wait-for-db runs first
  • helm template | kubectl apply --dry-run=server — all manifests valid
  • Kind cluster end-to-end: helm install --wait --timeout 10m succeeds, 0 restarts, init container logs:
    Waiting for PostgreSQL at sequin-test-postgresql:5432...
    PostgreSQL is accepting connections
    

When deploying with the bundled PostgreSQL subchart, Sequin starts
before PostgreSQL accepts connections, causing crash-loop restarts
on every fresh install. The startup script (start_commands.sh) runs
Ecto migrations immediately with no retry logic.

Adds a built-in init container that polls pg_isready until the
database is reachable. Uses the PostgreSQL subchart image which
provides pg_isready. Gated on postgresql.enabled so it does not
run when using an external database.

New value: waitForDB.enabled (default: true)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@o6uoq o6uoq marked this pull request as ready for review April 23, 2026 10:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant