I'm having a problem with MySQL running inside a Docker container. My testing image is built from the following Dockerfile:

# See: https://index.docker.io/u/brice/mysql/

FROM ubuntu:12.10
MAINTAINER Joni Kahara <[email protected]> 

# Because docker replaces /sbin/init: https://github.com/dotcloud/docker/issues/1024
RUN dpkg-divert --local --rename --add /sbin/initctl
RUN ln -s /bin/true /sbin/initctl

RUN apt-get update
RUN apt-get upgrade -y

RUN apt-get -y install mysql-server

RUN sed -i -e"s/^bind-address\s*=\s* =" /etc/mysql/my.cnf

RUN /usr/bin/mysqld_safe & \
    sleep 10s && \
    mysql -e "GRANT ALL ON *.* to 'root'@'%'; FLUSH PRIVILEGES;"


VOLUME ["/var/lib/mysql", "/var/log/mysql"]

CMD ["mysqld_safe"]

After building an image from the file above, I run it with:

docker run -p 3306:3306 asyncfi/magento-mysql

After which everything is swell and I can log in to this instance of MySQL from the local machine. However, I can also log in from any other machine.

I have set up my firewall to filter everything except traffic coming in to specific ports ("hidden" SSH, HTTP, HTTPS), and this filtering does in fact seem to work; if I for example run a Django development server on port 1234 then I am able to connect from the local machine, but not from outside. So the firewall seems to be filtering packets when they're destined to a server that is running as a "plain" process, but not when the server is running inside a container.

iptables -L -v --line-numbers says the following:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     2265  107K ACCEPT     all  --  lo     any     anywhere             anywhere
2     240K  319M ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
3       14  1040 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:<REDACTED>
4       21  1092 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:http
5        6   360 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:https
6      538 34656 LOG        all  --  any    any     anywhere             anywhere             limit: avg 5/min burst 5 LOG level debug prefix "iptables DROP: "
7      551 35424 DROP       all  --  any    any     anywhere             anywhere

Chain FORWARD (policy ACCEPT 5 packets, 296 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     all  --  docker0 docker0  anywhere             anywhere
2     6752  396K ACCEPT     all  --  docker0 !docker0  anywhere             anywhere
3     125K  188M ACCEPT     all  --  any    docker0  anywhere             anywhere             ctstate RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT 51148 packets, 14M bytes)
num   pkts bytes target     prot opt in     out     source               destination

Docker version is:

Client version: 0.7.3
Go version (client): go1.2
Git commit (client): 8502ad4
Server version: 0.7.3
Git commit (server): 8502ad4
Go version (server): go1.2
Last stable version: 0.7.3

Why is the MySQL port exposed to the outside world?

1 Answer 1


Thanks to #docker IRC channel users Michael Crosby and Paul Czar I am now able to answer my own question. The problem lies in the fact that I ran the container like this:

docker run -p 3306:3306 asyncfi/magento-mysql

This publishes the container's port to all interfaces of the host machine, which is definitely not what I was looking for at this time. To bind only to localhost, it was necessary to run the container as follows:

docker run -p asyncfi/magento-mysql

Also the EXPOSE line in Dockerfile is not necessary as the "expose" mechanism is used to link containers.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .