23

I received the following error when trying to write session data using Tomcat's PersistentManager to a Postgres DB running on my local machine:

SEVERE: A SQL exception occurred org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.

The application itself runs in a docker container. For completeness sake, my current context.xml file is:

<?xml version='1.0' encoding='utf-8'?>
<Context>
<Manager className="org.apache.catalina.session.PersistentManager"
    distributable="true"  processExpiresFrequency="6" maxIdleBackup="0" debug="99" >
    <Store className="org.apache.catalina.session.JDBCStore"
        driverName="org.postgresql.Driver"
        connectionURL="jdbc:postgresql://localhost/admin?stringtype=unspecified"
        connectionName="admin" connectionPassword="admin"
        sessionAppCol="app_name" sessionDataCol="session_data" sessionIdCol="session_id"
        sessionLastAccessedCol="last_access" sessionMaxInactiveCol="max_inactive"
        sessionTable="tomcat_sessions_tb" sessionValidCol="valid_session" />
</Manager>
</Context>

Pursuant to the suggestions here: Postgresql : Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections

I confirmed via a netstat -aln | grep LISTEN that Postgresql is running and listening on the correct ports:

tcp4       0      0  127.0.0.1.5432         *.*                    LISTEN     
tcp6       0      0  ::1.5432                                      *.*                                           LISTEN     

and that my postgresql.conf (located in usr/local/var/postgres) has listen_addresses = localhost and port = 5432, which mirrors the host and port of my running server in Pgadmin3.

I suspect that the problem is that Docker runs in a VM, and thus the local information I have obtained may not be the whole story. Reading up on the available information online, it seems that I may require some sort of bridged networking.
However, I admit I am a novice in this area, and I'm unsure of how to set it up.

catch23
  • 17,519
  • 42
  • 144
  • 217
Rome_Leader
  • 2,518
  • 9
  • 42
  • 73
  • I've since moved to memcached, and am having a near identical error. I'm convinced now it is the bridging, but I'm unsure how to approach it from the Docker side of things. – Rome_Leader May 30 '16 at 18:00

5 Answers5

24

Why I can NOT connect to localhost:5432?

Cat your container's /etc/hosts

$ sudo docker exec -it [container] cat /etc/hosts

For docker networks is bridge by default, the localhost inside points to container itself(Docker default bridge network). Then you don't have 5432 listening in your container:

$ sudo docker exec [container] nc -v -z localhost 5432

Solution 1. If you wanna hardcode the "localhost:5432" inside your config xml, the easiest way is creating your container with the option "--net=host":

$ sudo docker run --net=host -it ...

Solution 2. Change the localhost of your docker host ip inside the container
  • Get your docker host ip
    $ sudo docker inspect -f '{{ .NetworkSettings.Gateway }}' 
    192.168.5.1
  • Enter your container:
    $ sudo docker exec -it [container] /bin/bash
  • Edit the file /etc/hosts to point the localhost to docker host ip:
    $ sudo vim /etc/hosts
    192.168.5.1 localhost

Solution 3. Modify your db config file to use an alias instead of localhost:

connectionURL="jdbc:postgresql://DB_ALIAS/admin?stringtype=unspecified"
Then add the DB_ALIAS to the container's hosts :
$ sudo docker run --add-host DB_ALIAS:192.168.5.1 -it [image] ...
LittleQ
  • 1,860
  • 1
  • 12
  • 14
13

If you are using docker-compose together with postgres image, than you can reuse service name as IP inside jdbc connection (here: app-db)

  web:
    build: ./web
    ports:
      - "8080:8080"
    links:
      - app-db
    environment:
      - MYAPP_JDBC_URL=jdbc:postgresql://app-db:5432/somedb
      - MYAPP_JDBC_USER=someuser
      - MYAPP_JDBC_PASS=pass

  app-db:
    image: postgres:9.6
    environment:
      - POSTGRES_USER=someuser
      - POSTGRES_PASSWORD=pass
      - POSTGRES_DB=somedb
    expose:
      - 5432
    volumes_from:
      - app-db-data

  app-db-data:
    image: cogniteev/echo
    command: echo 'Data Container for PostgreSQL'
    volumes:
      - /opt/postgresdata/:/var/lib/postgresql/data
vinga
  • 1,912
  • 20
  • 33
  • I had setup a container running a webapp and trying to connect to another container containing postgresdb. And it was not working. The docker-compose file was similar to above except for the links tag. Docker documentation mentions that this is not the necessary step for containers to be able to communicate with each other. However, it did not work without links tag for me. – Ameya Mar 28 '18 at 05:19
  • 1
    service name in postgres url connection working for me. – borino Jul 27 '20 at 08:21
11

The best decision! jdbc:postgresql://host.docker.internal:5432/somedb Don't thank.

7

I had to expose port with -p 5432:5432:

docker run --name postgres -e POSTGRES_PASSWORD=secret -d -p 5432:5432 postgres
Aleksei Mialkin
  • 2,257
  • 1
  • 28
  • 26
5

I was getting the same error but this simple solution works perfect for me.
sudo docker run -d --net="host" -it <IMAGE> Now I can run my app https://x.x.x.x:pppp/../.. and everything works fine. I hope this helps

Didier R. G.
  • 437
  • 5
  • 11