1
votes

I set up an Elixir / Phoenix app in a docker container and a separate container for a Postgresql server. I can only connect to the Postgresql server when I expose the 5432 port. But I don't want the port to be public since this is pretty unsafe. The Postgresql server should only be accessible from the phoenix container.

But if I don't expose the port I just get an "Connection refused" error in the phoenix container.

app-phoenix-1 | 2016-03-15T11:41:32.701295542Z ** (Mix) The database for App.Repo couldn't be created, reason given: psql: could not connect to server: Connection refused
app-phoenix-1 | 2016-03-15T11:41:32.701369511Z  Is the server running on host "POSTGRES" (10.7.0.7) and accepting
app-phoenix-1 | 2016-03-15T11:41:32.701395350Z  TCP/IP connections on port 5432?

I linked the service and don't get, why it isn't working. Postgresql is up and running.

There is nothing in the log files of the Postgres Container.

This is the result of docker ps on my node:

8204a82ca192        myrepo/app       "elixir --erl '-smp d"   37 seconds ago      Up Less than a second   0.0.0.0:80->4000/tcp   app-phoenix-1.585afb94
7a4dded80c36        postgres:latest  "/docker-entrypoint.s"   2 hours ago         Up 10 minutes           5432/tcp               postgres-1.aed0697d

Somehow the Postgres container is blocking all connections from my phoenix container. Any clue how to fix this?

1
How do you run the containers. If you run with --link it should work. Also you should delay the app container for a few seconds as postgres may need time to boot up.Xiongbing Jin
Postgres is running a long time. I am deploying / running via the docker cloud web interface but I'm linking the postgres service in the phoenix container.Ole Spaarmann
Limiting traffic from the outside the host machine is the job of a firewall. In my case I use Ubuntu's native solution: ufw.Mark O'Connor

1 Answers

2
votes

I found the solution: The problem were the iptables settings. I had a rule in there to drop all forwarding unless otherwise defined:

-A FORWARD -j REJECT

This rule was at the wrong position in the filter chain. The right way is to put it at the very end of the filter chain, after the rules created by docker. So if you have the same problem, this works for me:

Get rid of the rule

$ sudo iptables -D FORWARD -j REJECT

Add it again to move it to the end of the set

$ sudo iptables -A FORWARD -j REJECT

Make sure they are in the right order. So the reject all else rule should be at the very end.

$ sudo iptables -v -L FORWARD

On Debian this is how you can make sure the rules still apply when restarting the server:

Once you are happy, save the new rules to the master iptables file:

$ iptables-save > /etc/iptables.up.rules

To make sure the iptables rules are started on a reboot we'll create a new file:

$ editor /etc/network/if-pre-up.d/iptables

Add these lines to it:

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.up.rules

The file needs to be executable so change the permissions:

$ sudo chmod +x /etc/network/if-pre-up.d/iptables

Edit: Just removing the rule is a bad idea.