What happened?
While building an E2E harness for a Bun-based TypeScript server, PostgreSqlContainer(...).start() could hang on macOS/Docker Desktop when using the default PostgreSQL wait strategy. The container was already healthy, but the start() promise did not resolve.
Switching to an explicit log wait strategy made startup deterministic:
new PostgreSqlContainer("pgvector/pgvector:pg16")
.withDatabase("draftly_test")
.withUsername("postgres")
.withPassword("postgres")
.withWaitStrategy(Wait.forLogMessage(/database system is ready to accept connections/, 2))
.start();
The observed behavior suggests the default Wait.forAll([forHealthCheck, forListeningPorts]) path may be waiting on a dockerode demuxed log stream close event that does not arrive under Bun on macOS, even though PostgreSQL is ready.
Repro outline
Environment seen:
- Runtime: Bun 1.3.x
- OS: macOS with Docker Desktop
- Package:
testcontainers / @testcontainers/postgresql 11.14.0
- Image:
pgvector/pgvector:pg16
Minimal shape:
import { PostgreSqlContainer } from "@testcontainers/postgresql";
await new PostgreSqlContainer("pgvector/pgvector:pg16")
.withDatabase("draftly_test")
.withUsername("postgres")
.withPassword("postgres")
.start(); // can hang under Bun on macOS
Expected behavior
If the container is healthy and the mapped PostgreSQL port is listening, start() should resolve under Bun the same way it does under Node.
Workaround
Using Wait.forLogMessage(/database system is ready to accept connections/, 2) avoids the hang because PostgreSQL emits that readiness line twice during init. This is workable but less ideal than the built-in default strategy.
Notes
I am filing this from a downstream test harness where the workaround is now documented. Happy to help test a patch or provide a smaller standalone repro if useful.
What happened?
While building an E2E harness for a Bun-based TypeScript server,
PostgreSqlContainer(...).start()could hang on macOS/Docker Desktop when using the default PostgreSQL wait strategy. The container was already healthy, but thestart()promise did not resolve.Switching to an explicit log wait strategy made startup deterministic:
The observed behavior suggests the default
Wait.forAll([forHealthCheck, forListeningPorts])path may be waiting on a dockerode demuxed log stream close event that does not arrive under Bun on macOS, even though PostgreSQL is ready.Repro outline
Environment seen:
testcontainers/@testcontainers/postgresql11.14.0pgvector/pgvector:pg16Minimal shape:
Expected behavior
If the container is healthy and the mapped PostgreSQL port is listening,
start()should resolve under Bun the same way it does under Node.Workaround
Using
Wait.forLogMessage(/database system is ready to accept connections/, 2)avoids the hang because PostgreSQL emits that readiness line twice during init. This is workable but less ideal than the built-in default strategy.Notes
I am filing this from a downstream test harness where the workaround is now documented. Happy to help test a patch or provide a smaller standalone repro if useful.