Skip to content

Comments

Optimize PostgreSQL startup with pre-initialized Docker image#4309

Open
kyleconroy wants to merge 2 commits intomainfrom
claude/postgres-docker-fast-startup-Y5I32
Open

Optimize PostgreSQL startup with pre-initialized Docker image#4309
kyleconroy wants to merge 2 commits intomainfrom
claude/postgres-docker-fast-startup-Y5I32

Conversation

@kyleconroy
Copy link
Collaborator

Summary

This PR optimizes PostgreSQL test database startup by pre-initializing the database at Docker image build time and applying performance-tuned settings. This eliminates the ~1-2 second initdb cost on every container start and ensures consistent, fast test execution.

Key Changes

  • New Dockerfile.postgres: Creates a fast-startup PostgreSQL image with:

    • Pre-initialized database at build time
    • Pre-applied performance settings (fsync=off, synchronous_commit=off, etc.)
    • Pre-configured pg_hba.conf for network access
    • Uses SIGINT for fast shutdown without crash recovery
  • Docker integration improvements:

    • internal/sqltest/docker/postgres.go: Added logic to build and use the custom sqlc-postgres image instead of pulling postgres:16
    • Implements buildPostgresImage() to build from Dockerfile.postgres on first use
    • Implements postgresImageExists() to check if image is already built
    • Implements findRepoRoot() to locate the Dockerfile relative to the repository
  • Native PostgreSQL setup enhancements:

    • internal/sqltest/native/postgres.go: Added pgFastSettings configuration and applyFastSettings() function to apply performance tuning to existing PostgreSQL installations
    • Implements restartPostgres() with fallback logic for different init systems (systemctl, service, pg_ctlcluster)
    • Includes idempotency check to avoid re-applying settings
  • Test setup tool updates:

    • cmd/sqlc-test-setup/main.go: Added applyFastSettings() function to apply performance tuning during manual PostgreSQL setup
    • Implements detectPgConfigPath() to query the running server for postgresql.conf location
  • Docker Compose update:

    • docker-compose.yml: Updated to build the custom Dockerfile.postgres instead of pulling the standard postgres:16 image

Implementation Details

  • Performance settings applied across all PostgreSQL setup methods are consistent: fsync=off, synchronous_commit=off, full_page_writes=off, wal_level=minimal, etc.
  • All implementations include idempotency checks using a marker comment ("# sqlc test optimizations") to prevent duplicate settings
  • The Docker image uses gosu for proper privilege handling and pipes the Dockerfile to docker build - to avoid sending the entire repository as build context
  • Native setup includes fallback logic for PostgreSQL restart across different Linux distributions

https://claude.ai/code/session_018Godbm3DFdWJf5jc7NU8Uq

Pre-initialize the database at Docker build time so container startup
only needs to launch the postgres process — no initdb, no entrypoint
scripts. Combined with aggressive durability-off settings (fsync=off,
synchronous_commit=off, wal_level=minimal), this cuts container startup
from ~1-2s to near-instant.

Key changes:
- Dockerfile.postgres: pre-initialized PG 18 image with test-tuned config
- docker-compose.yml: build from Dockerfile.postgres instead of pulling
- internal/sqltest/docker/postgres.go: auto-build the fast image on first
  test run, pipe Dockerfile via stdin to avoid sending build context

https://claude.ai/code/session_018Godbm3DFdWJf5jc7NU8Uq
Both the sqlc-test-setup CLI tool and the native test helper now detect
postgresql.conf at runtime and append the same speed-optimized settings
used in Dockerfile.postgres: fsync=off, synchronous_commit=off,
full_page_writes=off, wal_level=minimal, etc.

Settings are applied idempotently (a marker comment prevents duplicate
entries) and trigger a full restart since wal_level and max_connections
require it. This brings CI and non-Docker test environments to parity
with the Docker fast-startup image.

https://claude.ai/code/session_018Godbm3DFdWJf5jc7NU8Uq
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. 🔧 golang labels Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files. 🔧 golang

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants