0

From my docker container I want to access the MySQL server running on my host at 127.0.0.1. I want to access the web server running on my container container from the host. I tried this:

docker run -it --expose 8000 --expose 8001 --net='host' -P f29963c3b74f

But none of the ports show up as exposed:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
093695f9bc58        f29963c3b74f        "/bin/sh -c '/root/br"   4 minutes ago       Up 4 minutes                            elated_volhard
$
$ docker port 093695f9bc58

If I don't have --net='host', the ports are exposed, and I can access the web server on the container.

How can the host and container mutually access each others ports?

user2233706
  • 6,148
  • 5
  • 44
  • 86

2 Answers2

1

When --expose you define:

The port number inside the container (where the service listens) does not need to match the port number exposed on the outside of the container (where clients connect). For example, inside the container an HTTP service is listening on port 80 (and so the image developer specifies EXPOSE 80 in the Dockerfile). At runtime, the port might be bound to 42800 on the host. To find the mapping between the host ports and the exposed ports, use docker port.

With --net=host

--network="host" gives the container full access to local system services such as D-bus and is therefore considered insecure.

Here you have nothing in "ports" because you have all ports opened for host.

If you dont want to use host network you can access host port from docker container with docker interface
- How to access host port from docker container
- From inside of a Docker container, how do I connect to the localhost of the machine?.

When you want to access container from host you need to publish ports to host interface.

The -P option publishes all the ports to the host interfaces. Docker binds each exposed port to a random port on the host. The range of ports are within an ephemeral port range defined by /proc/sys/net/ipv4/ip_local_port_range. Use the -p flag to explicitly map a single port or range of ports.

In short, when you define just --expose 8000 the port is not exposed to 8000 but to some random port. When you want to make port 8000 visible to host you need to map published port -p 8000:8000.

Community
  • 1
  • 1
VladoDemcak
  • 4,893
  • 4
  • 35
  • 42
  • I'm testing things out, so I'm OK with docker using a random port on the host. From programmerq's post, it seems that you can't expose/map ports when using ```--net=host```. – user2233706 Nov 25 '16 at 15:58
  • @user2233706 sure, you cannot expose ports when using `--net=host` (it doesn't make sense - thats why you have nothing in "ports" column). When you dont `publish` ports how does your host know exposed ports eg. `8000->XXXX`? ports on host should be accessed with `docker0` interface (`IP` respectively). – VladoDemcak Nov 25 '16 at 20:25
0

Docker's network model is to create a new network namespace for your container. That means that container gets its own 127.0.0.1. If you want a container to reach a mysql service that is only listening on 127.0.0.1 on the host, you won't be able to reach it.

--net=host will put your container into the same network namespace as the host, but this is not advisable since it is effectively turning off all of the other network features that docker has-- you don't get isolation, you don't get port expose/publishing, etc.

The best solution will probably be to make your mysql server listen on an interface that is routable from the docker containers.

If you don't want to make mysql listen to your public interface, you can create a bridge interface, give it a random ip (make sure you don't have any conflicts), connect it to nothing, and configure mysql to listen only on that ip and 127.0.0.1. For example:

sudo brctl addbr myownbridge
sudo ifconfig myownbridge 10.255.255.255
sudo docker run --rm -it alpine ping -c 1 10.255.255.255

That IP address will be routable from both your host and any container running on that host.

Another approach would be to containerize your mysql server. You could put it on the same network as your other containers and get to it that way. You can even publish its port 3306 to the host's 127.0.0.1 interface.

programmerq
  • 6,262
  • 25
  • 40
  • 1
    According to [this](http://serverfault.com/questions/139323/mysql-bind-to-more-than-one-ip-address) you can't have MySQL listen on multiple IP addresses. I got your script working, but when I set ```bind-address=10.255.255.255``` in ```my.cnf```, I still can't connect to the MySQL server. – user2233706 Nov 25 '16 at 15:33
  • I'm going to run MySQL in a container. – user2233706 Nov 27 '16 at 03:32
  • you would also need to configure mysql to listen on that ip. – programmerq Nov 27 '16 at 15:31