Skip to content

supabase db start kills healthy Postgres container on Windows/WSL2 after startup #6136

Description

@dandy693

Issue Draft: Supabase CLI local DB startup race on Windows/WSL2

Title

supabase db start kills healthy Postgres container on Windows/WSL2 after startup

Summary

On Windows 11 with Docker Desktop and WSL2, supabase db start --debug can start the local Postgres container successfully, wait long enough for Docker to mark it healthy, and then kill/prune that healthy DB container after reporting a host connection failure.

The important point is that Postgres itself reaches healthy state. The Docker event timeline confirms that the failure happens after the DB container becomes healthy.

This reproduces in a fresh minimal Supabase project with no custom migration, so it does not appear to be caused by an application schema.

Observed behavior:

  1. The CLI creates and starts the local DB container.
  2. Internal container pg_isready initially fails while Postgres is still starting.
  3. Internal pg_isready later succeeds and Docker marks the container healthy.
  4. A few seconds later, the CLI reports a host connection failure to 127.0.0.1:<published db port>.
  5. The CLI kills the healthy DB container and prunes the project DB volume/network.

This appears to be a timing-sensitive readiness/host-connect race.

Environment

  • OS: Windows 11
  • Shell: PowerShell 7.6.3
  • WSL: 2.6.3.0
  • WSL kernel: 6.6.87.2-1
  • WSL default version: 2
  • Docker Desktop: 4.85.0
  • Docker CLI: 29.6.2
  • Docker Engine: 29.6.2
  • Docker backend: WSL2 / Linux containers
  • Docker context: desktop-linux
  • Docker resources: 8 CPUs, approximately 7.6 GiB memory
  • Node.js: v24.14.1
  • npm: 11.11.0
  • Supabase CLI stable: 2.113.0
  • Supabase CLI beta: 2.113.0-beta.6

npm dist-tags observed:

  • latest: 2.113.0
  • beta: 2.113.0-beta.6
  • hotfix: 1.142.2 (not tested because it is a much older 1.x line)

Existing issue search

I searched open and closed supabase/cli issues for combinations of:

  • "db start" "127.0.0.1" ECONNREFUSED
  • Windows WSL2 "db start"
  • "healthy" "prune" "db start"
  • "connection timed out" "db start"
  • "container" "killed" "db start"
  • "Postgres" "healthy" "supabase db"
  • "127.0.0.1:54322"

No exact duplicate was found.

Related but not identical:

Minimal reproduction

This is the minimal reproduction that does not involve any application schema:

  1. Create a fresh temporary directory.

  2. Initialize a local Supabase project:

    npx supabase init
  3. In supabase/config.toml, choose an unused local DB published port that is not in the Windows excluded port range.

  4. Confirm the port is not already in use.

  5. Run:

    npx supabase db start --debug
  6. Observe the DB container lifecycle with Docker events or docker ps -a.

Observed sequence:

  1. DB container is created.
  2. DB container starts.
  3. Internal pg_isready initially fails.
  4. Internal pg_isready later succeeds.
  5. Docker marks the DB container healthy.
  6. A few seconds later, the CLI kills/removes the container and prunes the project DB volume/network.
  7. The command exits with a local host connection failure or timeout.

Expected behavior

Once the local Postgres container becomes healthy, supabase db start should keep it running, apply local migrations when present, record migration history, and return success.

Actual behavior

Postgres becomes healthy, then the CLI kills/prunes the DB container, DB volume, and project network. The command exits with a local host connection error or timeout.

Typical stable-channel error:

ECONNREFUSED 127.0.0.1:<db published port>

Beta 2.113.0-beta.6 produced:

failed to connect to postgres: failed to connect to `host=127.0.0.1 user=postgres database=postgres`: Connection timed out

Docker event timeline

Times are local time, JST / UTC+9.

Stable 2.113.0:

15:09:52 DB container created
15:09:55 DB container started
15:10:05 internal pg_isready failed
15:10:15 internal pg_isready succeeded
15:10:15 container became healthy
15:10:18 CLI killed the DB container
15:10:30 DB container destroyed
15:10:32 DB volume destroyed

Beta 2.113.0-beta.6:

15:39:58 DB container created
15:40:01 DB container started
15:40:11 internal pg_isready failed
15:40:22 container became healthy
15:40:25 CLI killed the DB container
15:40:37 DB container destroyed
15:40:39 project network destroyed

CLI versions tested

Stable versions:

  • 2.110.0: failed
  • 2.111.0: failed
  • 2.112.0: failed
  • 2.113.0: failed

Beta:

  • 2.113.0-beta.6: failed

Because nearby stable versions and the current beta all failed, I do not think this can be classified as a single-version regression from the data I have.

Schema independence

The problem reproduces in a fresh minimal Supabase project with no custom migration, so it is not caused by the application's schema.

In the application project, the schema SQL was separately validated for diagnostic purposes. That validation is not part of the reproduction and is not required to reproduce the CLI startup behavior.

Control tests

The following control tests passed on the same machine:

  • Docker-published nginx:alpine container reachable from the Windows host.
  • Docker-published postgres:17-alpine container reachable from the Windows host.
  • Container-internal pg_isready passed for the temporary Postgres container.
  • Another existing local Supabase project's DB, API, and Studio ports were reachable.
  • HNS service was running.
  • vmcompute service was running.
  • Reproduction ports were not Windows excluded ports.
  • Reproduction ports were not already in use.

Therefore, general Docker published-port networking appears functional.

--create-ticket anomaly

I also ran:

npx supabase db start --debug --create-ticket

On that specific run, the command unexpectedly succeeded. The migration was applied and recorded, and the expected tables existed.

However, a subsequent:

npx supabase migration list --local

still failed with ECONNREFUSED to the local DB, despite the DB container being healthy and the host TCP port being reachable.

No ticket ID was generated because the --create-ticket run exited successfully.

Interestingly, one run with --create-ticket succeeded, suggesting the issue may be timing-sensitive. I am not claiming that --create-ticket fixes the issue.

Questions

  • Is there a known readiness timeout or host-connect race for local DB startup on Windows/WSL2?
  • Is there a supported way to increase the local DB startup wait timeout before the CLI reports host connection failure?
  • Is the CLI expected to prune a DB container after Docker has already marked it healthy?

Additional context

  • The project uses custom local ports so it can run beside another existing local Supabase project.
  • The main reproduced DB published port was 54322.
  • The tested custom DB port did not conflict with the other local Supabase project.
  • No remote Supabase project was targeted.
  • No production database was involved.
  • No Docker Desktop, WSL, firewall, HNS, or portproxy settings were changed during diagnosis.
  • I can provide full debug logs if needed.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions