I was having the hardest time getting applications in docker containers to connect to the instance of mysql runnning on the host.
I finally found a great solution, so I figured I'd post it here for myself and so that others may find it as well.
The idea is to simply enable some local routing rules and use iptables
to allow access to port 3306 for MySQL.
- Enable
route_localnet
for docker0 interface:
sysctl -w net.ipv4.conf.docker0.route_localnet=1
- At this point, you'll want to double check and see which subnet is being used by your container for its internal docker network. The default network is
172.17.0.0/24
, however if you have multiple containers / docker networks this network may be slightly different. You can check easily by either entering an interactive shell in your container and runningifconfig
orip addr
to see which network your container is on. Alternatively, you can view the docker inspect info with the commanddocker inspect <container name>
and look for the"Gateway"
address in the network config towards the bottom of the inspect information.
Finally, once you've confirmed the network your container is on, add these rules to iptables:
iptables -t nat -I PREROUTING -i docker0 -d 172.17.0.1 -p tcp --dport 3306 -j DNAT --to 127.0.0.1:3306
iptables -t filter -I INPUT -i docker0 -d 127.0.0.1 -p tcp --dport 3306 -j ACCEPT
At this point, we should be able to route on our local machine on port 3306
. That is, from the docker subnet's gateway (172.17.0.1
aka the localhost) to our hosts localhost loopback address where the MySQL instance is listening (127.0.0.1:3306
).
- Make sure you have a mysql user in your local instance who is allowed to connect from outside of 'localhost', i.e. from '%'. If you're having trouble with authentication still, you may need to add a user who is explicitly allowed to connect from the Docker subnet on your computer.
For example, with wide open privileges, allowing the user username
to connect from any host:
CREATE USER 'username'@'%' IDENTIFIED BY 'password';
Alternatively, you can lock it down a bit more and only allow username
to connect from the Docker subnet:
CREATE USER 'username'@'172.17.0.%' IDENTIFIED BY 'password';
- Finally, in your docker container setup, whether that's in a config value in the
docker-compose.yml
file or elsewhere in your dockerized application, make sure to change the mysql server address to172.17.0.1
. This is the default host's IP address from the view of the container.