Skip to content

PostgreSQL default wait strategy can hang under Bun on macOS #1335

@xlogix

Description

@xlogix

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions