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?
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.