How do you send tcp/ip requests from a docker container to the host?

4.3k views Asked by At

I'm working out how to run openproject with docker. I'm working through openproject/docker.

I've got the docker image running with an external postgres directory.

I'm now working out how to connect to an existing running instance of postgresql.

The command line I'm using looks ok according to the official documentation.

EDIT. Added in the missing -p.

docker run -p 8082:80 -p 5432:5432 --name openproject_dev -e SECRET_KEY_BASE=secret -e DATABASE_URL=postgresql://openproject:openproject-dev-
password@localhost:5432/openproject_dev  \
-v /Users/admin/var/lib/openproject/logs:/var/log/supervisor   \
-v /Users/admin/var/lib/openproject/static:/var/db/openproject   openproject/community:5.0

I've ommitted the -d [deamon] flag so I can see any errors.

When the docker container is being created I get

-----> You're using an external database. Not initializing a local database cluster.
   /usr/src/app /usr/src/app
   Starting memcached: memcached.

Which I expect. Then I get an error about connecting to the postgresql server which I don't expect.

...
PG::ConnectionBad: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
/usr/local/bundle/gems/activerecord-
4.2.7.1/lib/active_record/connection_adapters/postgresql_adapter.rb:651:in `initialize'

I'm guessing the script initialising the container is expecting postgres to be running and it's not. How would you make the docker container port forward requests to 5432 to the host machine on the command line? ... the opposite of docker run -p 5432:5432 ... which exposes 5432 from the docker container to the host.

2

There are 2 answers

6
Tarun Lalwani On BEST ANSWER

Your approach is wrong currently

docker run -p 8082:80 -p 5432:5432 --name openproject_dev -e SECRET_KEY_BASE=secret -e DATABASE_URL=postgresql://openproject:openproject-dev-password@localhost:5432/openproject_dev \ -v /Users/admin/var/lib/openproject/logs:/var/log/supervisor \ -v /Users/admin/var/lib/openproject/static:/var/db/openproject openproject/community:5.0

when you used -p 5432:5432 it means that you expect something to run inside docker on that port and you want your host machine 5432 port to map to 5432 inside docker.

Next if you were able to run that command, even though nothing is listening inside container, then that would imply that the port on your host is available. This means postgress is not listening on 5432 on host also. It may be listening on a socket. You should try to execute below command on host

psql -h 127.0.0.1

If you are not able to connect on host using this that means the postgres db is bind to a socket file and not to a IP. Now you have few options that you can exercise

Mount the socket

docker run -p 8082:80 -p 5432:5432 --name openproject_dev -e SECRET_KEY_BASE=secret -e DATABASE_URL=postgresql://openproject:openproject-dev-password@localhost:5432/openproject_dev \ -v /Users/admin/var/lib/openproject/logs:/var/log/supervisor \ -v : \ -v /Users/admin/var/lib/openproject/static:/var/db/openproject openproject/community:5.0

Bind on 0.0.0.0 on host

If you don't want to mount volume then you should change the bind address of psql to 0.0.0.0 and then change your database url to -e DATABASE_URL=postgresql://openproject:openproject-dev-password@<YOURMACHINEIP>:5432/openproject_dev

Run on host network

docker run --net host --name openproject_dev -e SECRET_KEY_BASE=secret -e DATABASE_URL=postgresql://openproject:openproject-dev-password@localhost:5432/openproject_dev \ -v /Users/admin/var/lib/openproject/logs:/var/log/supervisor \ -v : \ -v /Users/admin/var/lib/openproject/static:/var/db/openproject openproject/community:5.0

1
yamenk On
-e DATABASE_URL=postgresql://openproject:openproject-dev-
password@localhost:5432/openproject_dev

When you add this url, the container expects postgres to be running on localhost, i.e. in itself.

If you are running postgres on your host machine, you can let the container share the network stack with the host by passing --network host in the run command. In that case, localhost will refer to the host machine where postgres is running.