Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exposing a port on a live Docker container

Tags:

docker

I'm trying to create a Docker container that acts like a full-on virtual machine. I know I can use the EXPOSE instruction inside a Dockerfile to expose a port, and I can use the -p flag with docker run to assign ports, but once a container is actually running, is there a command to open/map additional ports live?

For example, let's say I have a Docker container that is running sshd. Someone else using the container ssh's in and installs httpd. Is there a way to expose port 80 on the container and map it to port 8080 on the host, so that people can visit the web server running in the container, without restarting it?

like image 469
reberhardt Avatar asked Nov 11 '13 02:11

reberhardt


People also ask

How do you expose a port on a running Docker container?

You can do this in the following ways: Add an EXPOSE instruction in the Dockerfile. Use the –expose flag at runtime to expose a port. Use the -p flag or -P flag in the Docker run string to publish a port.

Is it possible to map a port on a running container?

Port mapping is used to access the services running inside a Docker container. We open a host port to give us access to a corresponding open port inside the Docker container. Then all the requests that are made to the host port can be redirected into the Docker container.

What does expose port do in Docker?

What Is Docker Expose Port? This tells Docker your webserver will listen on port 80 for TCP connections since TCP is the default. For UDP, specify the protocol after the port. For more than one port, you can list EXPOSE more than once.


2 Answers

You cannot do this via Docker, but you can access the container's un-exposed port from the host machine.

If you have a container with something running on its port 8000, you can run

wget http://container_ip:8000 

To get the container's IP address, run the 2 commands:

docker ps docker inspect container_name | grep IPAddress 

Internally, Docker shells out to call iptables when you run an image, so maybe some variation on this will work.

To expose the container's port 8000 on your localhost's port 8001:

iptables -t nat -A  DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000 

One way you can work this out is to setup another container with the port mapping you want, and compare the output of the iptables-save command (though, I had to remove some of the other options that force traffic to go via the docker proxy).

NOTE: this is subverting docker, so should be done with the awareness that it may well create blue smoke.

OR

Another alternative is to look at the (new? post 0.6.6?) -P option - which will use random host ports, and then wire those up.

OR

With 0.6.5, you could use the LINKs feature to bring up a new container that talks to the existing one, with some additional relaying to that container's -p flags? (I have not used LINKs yet.)

OR

With docker 0.11? you can use docker run --net host .. to attach your container directly to the host's network interfaces (i.e., net is not namespaced) and thus all ports you open in the container are exposed.

like image 55
SvenDowideit Avatar answered Oct 05 '22 08:10

SvenDowideit


Here's what I would do:

  • Commit the live container.
  • Run the container again with the new image, with ports open (I'd recommend mounting a shared volume and opening the ssh port as well)
sudo docker ps  sudo docker commit <containerid> <foo/live> sudo docker run -i -p 22 -p 8000:80 -m /data:/data -t <foo/live> /bin/bash 
like image 23
bosky101 Avatar answered Oct 05 '22 07:10

bosky101