testcontainers / testcontainers-node

Testcontainers is a NodeJS library that supports tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
https://testcontainers.com
MIT License
1.92k stars 192 forks source link

health check never resolves for postgres container #154

Closed rathboma closed 4 years ago

rathboma commented 4 years ago

I'm creating a postgres container

    container = await new GenericContainer("postgres")
      .withEnv("POSTGRES_PASSWORD", "example")
      .withEnv("POSTGRES_DB", "banana")
      .withWaitStrategy(Wait.forHealthCheck())
      .withExposedPorts(5432)
      .withStartupTimeout(new Duration(dbtimeout, TemporalUnit.MILLISECONDS))
      .start()

But the health check never resolves and I cannot connect to it:

 testcontainers TRACE Pulling postgres:latest - Status: Downloaded newer image for postgres:latest +8ms
  testcontainers DEBUG Creating new Reaper for session: b08532c1add53c0cfd8d3365da0990d9 +7ms
  testcontainers INFO Creating container for image: testcontainers/ryuk:0.3.0 +42ms
  testcontainers INFO Starting container testcontainers/ryuk:0.3.0 with ID: 16720f5bb90c299b302ad3c01a275bd0d4b7a2d7f5ae3ca6550ebab7f43d06a7 +200ms
  testcontainers DEBUG Waiting for container to be ready: 16720f5bb90c299b302ad3c01a275bd0d4b7a2d7f5ae3ca6550ebab7f43d06a7 +466ms
  testcontainers DEBUG Waiting for log message "Started!" +1ms
  testcontainers INFO Container is ready +5ms
  testcontainers DEBUG Connecting to Reaper on localhost:38167 +0ms
  testcontainers DEBUG Connected to Reaper +3ms
  testcontainers INFO Creating container for image: postgres:latest +1ms
  testcontainers INFO Starting container postgres:latest with ID: 46983de08297320cde6518ba6133cd550f92b0a4a3d640c7e2be242972f3f381 +77ms
  testcontainers DEBUG Waiting for container to be ready: 46983de08297320cde6518ba6133cd550f92b0a4a3d640c7e2be242972f3f381 +473ms
  testcontainers DEBUG Waiting for health check +1ms
  testcontainers ERROR Container failed to be ready +11m

If I start a postgres container manually, it works and I can connect to it with my DB client:

docker run -p 9999:5432 -e POSTGRES_PASSWORD=example -e POSTGRES_DB=banana postgres

Any thoughts?

I've tried:

I have a mysql test that works totally fine, so maybe this is something specific with how it runs the docker image?

rathboma commented 4 years ago

This is the command it runs according to 'runlike':

docker run --name=stoic_ishizaka --hostname=727861e2332f --mac-address=02:42:ac:11:00:03 --env=POSTGRES_PASSWORD=example --env=POSTGRES_DB=banana --env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/13/bin --env=GOSU_VERSION=1.12 --env=LANG=en_US.utf8 --env=PG_MAJOR=13 --env=PG_VERSION=13.0-1.pgdg100+1 --env=PGDATA=/var/lib/postgresql/data --volume=/var/lib/postgresql/data -p 0.0.0.0:33031:5432 -p 33031:5432 --label='org.testcontainers.session-id=ea1e07e55a3ca9878118f6c4ff33857a' --detach=true postgres:latest postgres
rathboma commented 4 years ago

Thinking it may be because the container starts postgres twice - once to create the database, once to actually run it, and it gets hung up during that process somewhere?

Matthew

cristianrgreco commented 4 years ago

Hi @rathboma, does the Postgres image define a healthcheck? The wait strategies work like this:

  1. HostPortWaitStrategy (default): if we define an exposed port of 8000, testcontainers will wait until that port is bound
  2. LogWaitStrategy: wait until the container outputs a given log
  3. HealthCheckWaitStrategy: wait for the container's health check to succeed. If the image doesn't provide a health check, one can be provided with withHealthCheck({...})

Why not use the default wait strategy for postgres?

rathboma commented 4 years ago

I tried that and still ran into problems. Let me do some double checking and double make sure I've not got a problem at my end.

(I also forgot to paste my custom wait strategy).

Hang tight I'll report back tomorrow (I'm probably doing something wrong)

cristianrgreco commented 4 years ago

Cool let me know, just FYI this works for me:

const { GenericContainer } = require("testcontainers");

(async () => {
    const container = await new GenericContainer("postgres")
        .withEnv("POSTGRES_USER", "test")
        .withEnv("POSTGRES_PASSWORD", "test")
        .withEnv("POSTGRES_DB", "postgres")
        .withExposedPorts(5432)
        .start();

    await container.stop();
})();
rathboma commented 4 years ago

Yeah I figured it out. I was using an old version of the pg library, but using the config syntax of the new version. It failed silently.

rathboma commented 4 years ago

Sorry for the false bug report, but I very much appreciate the fast response. You helped a lot actually.