docker-compose exposing ports on remote container - docker

I run my docker-compose service remotely on another physical machine on my local network via -H=ssh://user#192.168.0.x.
I'm exposing ports using docker-compose:
ports:
- 8001:8001
However, when I start the service, the port 8001 is not exposed to my localhost. I can ssh into the machine running the container, and port 8001 is indeed listening there.
How do I instruct docker-compose to tunnel this port from the remote machine running the container, to my local docker client?

Docker doesn't have the ability to do this. But from your ssh client's point of view, the container is no different from any other program running on the remote host, and you can use the ssh -L option to forward a local port to the remote system.
# Tell ssh to forward local port 8001 to remote port 8001
ssh -L 8001:localhost:8001 user#192.168.0.x \
# Incidentally the remote port happens to be via a Docker container
docker run -p 127.0.0.1:8001:8001 ...
Whenever you set DOCKER_HOST or use the docker -H option, you're giving instructions to a remote Docker daemon which interprets them relative to itself. docker -H ... -v ... mounts a directory on the same system as the Docker daemon into a container; docker -H ... -p ... publishes a port on the same system as the Docker daemon. Docker has no ability to somehow take into account the content or network stack of the local system when doing this.
(The one exception is docker -H ... build, which actually creates a tar file of the local directory and sends it across the network to use as the build context, so you can have a remote Docker daemon build an image of a local source tree.)

Related

Docker port exposed to outside world

I've installed docker in a VM which is publicy available on internet. I've installed mongodb in a docker container in the VM.Mongodb is listening on 27017 port.
I've installed using the following steps
docker run -p 27017:27017 --name da-mongo -v ~/mongo-data:/data/db -d mongo
The port from container is redirected to the host using the -p flag. But the port 27017 is exposed on the internet. I don't want it to happen.
Is there any way to fix it?
Well, if you want it available for certain hosts then you need a firewall. But, if all you need is it working on localhost (your VM machine), then you don't need to expose/bind the port with the host. I suggest you to run the container without the -p option, then, run the following command:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' your_container_id_or_name
After that, it will display an IP, it is the IP of the container you've just ran (Yes, docker uses somewhat an internal virtual network connecting your containers and your host machine between them).
After that, you can connect to it using the IP and port combination, something like:
172.17.0.2:27017
When you publish the port, you can select which host interface to publish on:
docker run -p 127.0.0.1:27017:27017 --name da-mongo \
-v ~/mongo-data:/data/db -d mongo
That will publish the container port 27017 to host interface 127.0.0.1 port 27017. You can only add the interface to the host port, the container itself must still bind to 0.0.0.0.

How does Docker use ports 2375 and 4243?

I see various instances of ports 2375 and 4243 being used for seemingly the same thing while searching the internet. Also, my local machine requires I use 2375 to connect whereas when I push it to our CI server it requires it be set to 4243.
What does Docker use these ports for and how do they differ?
The docker socket can be configured on any port with the dockerd -H option. Common docker ports that I see include:
2375: unencrypted docker socket, remote root passwordless access to the host
2376: tls encrypted socket, most likely this is your CI servers 4243 port as a modification of the https 443 port
2377: swarm mode socket, for swarm managers, not for docker clients
5000: docker registry service
4789 and 7946: overlay networking
Only the first two are set with dockerd -H, swarm mode can be configured as part of docker swarm init --listen-addr or docker swarm join --listen-addr.
I strongly recommend disabling the 2375 port and securing your docker socket. It's trivial to remotely exploit this port to gain full root access without a password from remote. The command to do so is as simple as:
docker -H $your_ip:2375 run -it --rm \
--privileged -v /:/rootfs --net host --pid host busybox
That can be run on any machine with a docker client to give someone a root shell on your host with the full filesystem available under /rootfs, your network visible under ip a, and every process visible under ps -ef.
To setup TLS security on the docker socket, see these instructions. https://docs.docker.com/engine/security/https/

How to access a Process running on docker on a host from a remote host

How to access or connect to a process running on docker on host A from a remote host B
consider a Host A with ip 192.168.0.3 which is running a application on docker on port 3999 .
If i want to access that application from remote machine with IP 192.168.0.4 in same subnet.
To be precise i am running Kafka producer on the server and i am trying to receive using Kafka-console-Consumer.
Use --net=host to run your container and it'll use the host's network stack, then you can connect to the application running inside container like it's running on host directly.
Port mapping, use option -p to map the port inside your container to a port of your host. e.g. docker run -d -p <container port>:<host port> <image>, then you can connect to <host>:<host port> to connect your application inside container
Docker's built-in multi-host network. In early releases the network driver is isolated from docker's core, you have to use 3rd party tools like flannel or weave for multi-host connection, but from release 1.9, it has been merged into docker. You can follow it's guide to set it up.
Hope this is helpful :-)
First you need to bind docker container's port to the Host A:
docker run -d -p 3999:3999 kafka-producer
Then you need to access Host A from Host B using IP:Port
192.168.0.3:3999

docker for windows how to access docker daemon from container

Im running Docker Desktop for Windows (hyper V) and I need to access docker daemon from the container via tcp. It is possible to connect to it from the host like:
curl -v 127.0.0.1:2375/info but not possible to access it from a container using my host IP address. Maybe someone knows how to do that or at least how to ssh to that docker vm, for example it is possible to ssh in to it on mac by executing:
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
I've figured how to do that using socat tool which takes docket.socket and proxy TCP calls to it.
So I've launched container with a socat which mount docker.sock since it is available inside of a VM and expose 2375 port:
docker run -p 2375:2375 -v /var/run/docker.sock:/var/run/docker.sock codenvy/socat -d -d TCP-L:2375,fork UNIX:/var/run/docker.sock
With that now, I'm able to access docker daemon API through socat container.

Remote access to webserver in docker container

I've started using docker for dev, with the following setup:
Host machine - ubuntu server.
Docker container - webapp w/ tomcat server (using https).
As far as host-container access goes - everything works fine.
However, I can't manage to access the container's webapp from a remote machine (though still within the same network).
When running
docker port <container-id> 443
output is as expected, so docker's port binding seems fine.
172.16.*.*:<random-port>
Any ideas?
Thanks!
I figured out what I missed, so here's a simple flow for accessing docker containers webapps from remote machines:
Step #1 : Bind physical host ports (e.g. 22, 443, 80, ...) to container's virtual ports.
possible syntax:
docker run -p 127.0.0.1:443:3444 -d <docker-image-name>
(see docker docs for port redirection with all options)
Step #2 : Redirect host's physical port to container's allocated virtual port. possible (linux) syntax:
iptables -t nat -A PREROUTING -i <host-interface-device> -p tcp --dport <host-physical-port> -j REDIRECT --to-port <container-virtual-port>
That should cover the basic use case.
Good luck!
Correct me if I'm wrong but as far as I'm aware docker host creates a private network for it's containers which is inaccessible from the outside. That said your best bet would probably be to access the container at {host_IP}:{mapped_port}.
If your container was built with a Dockerfile that has an EXPOSE statement, e.g. EXPOSE 443, then you can start the container with the -P option (as in "publish" or "public"). The port will be made available to connections from remote machines:
$ docker run -d -P mywebservice
If you didn't use a Dockerfile, or if it didn't have an EXPOSE statement (it should!), then you can also do an explicit port mapping:
$ docker run -d -p 80 mywebservice
In both cases, the result will be a publicly-accessible port:
$ docker ps
9bcb… mywebservice:latest … 0.0.0.0:49153->80/tcp …
Last but not least, you can force the port number if you need to:
$ docker run -d -p 8442:80 mywebservice
In that case, connecting to your Docker host IP address on port 8442 will reach the container.
There are some alternatives of how to access docker containers from an external device (in the same network), check out this post for more information http://blog.nunes.io/2015/05/02/how-to-access-docker-containers-from-external-devices.html

Resources