4

I've created a Postgres instance using testcontainers. The container starts but I cannot access it.

I have tried connecting at the containerized DB using DBeaver. In the eclipse console everything seems fine:

01:29:34.662 [main] DEBUG com.github.dockerjava.core.command.AbstrDockerCmd - Cmd: com.github.dockerjava.core.command.CreateContainerCmdImpl@73386d72[name=,hostName=,domainName=,user=,attachStdin=,attachStdout=,attachStderr=,portSpecs=,tty=,stdinOpen=,stdInOnce=,env={POSTGRES_USER=test,POSTGRES_PASSWORD=test,POSTGRES_DB=ASIGDB_TEST}

Here is my code:

public class CustomPostgresContainer extends PostgreSQLContainer<CustomPostgresContainer>{
    private static final String IMAGE_VERSION = "postgres:9.6";
    private static CustomPostgresContainer customPostgresContainer;
    private static final int EXPOSED_PORT = 5555;
    private static final String DB_NAME = "ASIGDB_TEST";
    private static final String DB_USER= "test";
    private static final String DB_PASSWORD= "test";


    public CustomPostgresContainer() {
        super(IMAGE_VERSION);
    }

    public static CustomPostgresContainer getCustomPostgresContainerInstance() {
        if(customPostgresContainer == null) {
            return extracted().withExposedPorts(EXPOSED_PORT)
                                                .withDatabaseName(DB_NAME)
                                                .withUsername(DB_USER)
                                                .withPassword(DB_PASSWORD);
        }

        return customPostgresContainer;
    }

    private static CustomPostgresContainer extracted() {
        return new CustomPostgresContainer();
    }

    @Override
    public void start() {
        super.start();
    }

    @Override
    public void stop() {
        //do nothing, JVM handles shut down
    }
}

I get:

Connection to localhost:5555 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.

Does anyone know what is going on?

Kiroshi
  • 43
  • 1
  • 1
  • 4

1 Answers1

12

According to this link, withExposedPorts() --> this exposed port number is from the perspective of the container.
From the host's perspective Testcontainers actually exposes this on a random free port. This is by design, to avoid port collisions that may arise with locally running software or in between parallel test runs.
Because there is this layer of indirection, it is necessary to ask Testcontainers for the actual mapped port at runtime. This can be done using the getMappedPort method, which takes the original (container) port as an argument:

Integer firstMappedPort = container.getMappedPort(yourExposedPort);<br/>

Try to connect with DBeaver to the port that appears first.

Screenshot with ports

  • Thanks Vitalii. I indeed misinterpreted the perspective of the exposed port. Basically any request to the docker entry point(which is exposed on that random port) started by testcontainers is forwarded to the default postgres instance that runs inside the container(5432) AND the exposed port which was added by me(5555). Thanks again. – Kiroshi Oct 02 '19 at 08:58