Expose Docker container to public ip - networking

I started an Ubuntu Docker container, installed ssh, run ssh with port 22 attached to it.
$ docker ps
CONTAINER ID IMAGE COMMAND PORTS
f580e36aa7f0 martin/ssh2 /usr/sbin/sshd -D 0.0.0.0:49154->22/tcp
From my server I can now ssh my container. It work fine!
ssh root#172.17.42.1 -p 49154
But how can I ssh my container from the outside word?
(my server is running in my local network on 192.168.1.8/24)
Should I install a load balancer who redirect 192.168.1.8:2222 to 172.17.42.1:49154?
Should I need pipework for that? How?
Can someone point me in the right decision?

You should be able to connect to your container at 192.168.1.8:49154 already.
Your ssh container is bind to 0.0.0.0 (=any interfaces) and port 49154 so it means container port 22 is accessible on any interface on your host at port 49154.

Related

Docker for Windows application not accessible over browser when connected via VPN

I have docker for windows running windows container. Machine is connected to corporate network via Cisco AnyConnect VPN. We have been having this issue for sometime with no solutions. To explain the problem here is an example. Go to docker image here https://hub.docker.com/_/microsoft-dotnet-samples and run the below commands in command prompt / powershell in sequence
docker pull mcr.microsoft.com/dotnet/samples:aspnetapp
docker run -it --rm -p 8000:80 --name aspnetcore_sample mcr.microsoft.com/dotnet/samples:aspnetapp
replace port 8000 with something else if there is an error in lines of hns file being used. Go to browser and do http://localhost:8000 assuming its running on port 8000. It doesn't connect for me. Instead of localhost i also tried below command to find the ipaddress of the container running the image and then replace localhost with that ip address but with same response unable to connect.
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
here is an screenshot of the network adapter docker sets up by default
here is another screenshot of the nat network adapter

Connecting Docker Containers

Hello Helpful Developers,
I'm having issues connecting docker containers. I have built a subversion docker container and a mongo docker container.
docker run -d -p 3343:3343 -p 4434:4434 -p 18080:18080 --name svn-server mamohr/subversion-edge
docker run -p 27017:27017 --name my-mongo -d mongo
I'm able to hit http://x.x.x.x:18080/ from a browser, but unable to curl from the my-mongo instance. I can talk to each container from my development machine, but unable to talk from container to container.
I see things like --net=bridge, host, ????, but I'm getting confused.
Please help.....
Borrowing this schema from SDN hub, imagine that C1 is your SVN container and C2 is your Mongo container:
Both containers are connected to docker0 bridge and NATed to external 192.168.50.16 network.
To connect from your Mongo container, check the bridge0 IP address of the SVN container:
# docker inspect <svn-container-name>
"Networks": {
"bridge0": {
"IPAddress": "172.17.0.19",
}
then CURL directly to it's bridge0 IP address:
curl http://172.17.0.19:18080/
To get you immediately going, you can start your hosts with --net=host and then both containers and host will be able to communicate.
Or you can use link( --link ) between from mongo to the other container.
There is lot to explain about docker networking and the docker documentation will be good point to start.
Read the documentation at https://docs.docker.com/engine/userguide/networking/dockernetworks/
I would advice you to take a look at docker compose. I think it's the best way to manage a system, which is composed of many containers.
Here is the official guide: https://docs.docker.com/compose/
Docker containers by default start attached to a bridge network called default. You can do docker network ls and see the networks you have available. You can also create networks with different attributes etc...
So in your case, both your containers are being started on the same default network, which means they should be able to communicate with each other just fine. In fact, if you only want your SVN server to be able to talk to Mongo (and don't need to connect to mongo from your host) you don't even need to expose ports on the Mongo container. Containers on the same network as each can communicate with each other just fine without ports being exposed. Exposing ports is to allow host > container connectivity.
So, what hostname / port are you using when you try to curl from the mongo instance to your SVN instance? You should be using svn-server as that will resolve to the SVN container (using Docker's built-in DNS resolution).
Direct container to container networking via container name can be achieved with a user defined network.
docker network create mynet
docker run -d --net=mynet --name svn-server mamohr/subversion-edge
docker run -d --net=mynet --name my-mongo mongo
docker exec <svn-id> ping my-mongo
docker exec <mongo-id> ping svn-server
You should always be able to connect to mapped ports though, even in your current setup. The hosts runs a process that listens on that port so any host IP should do.
$ docker run -d -p 8080:80 --net=mynet --name sleep busybox nc -lp 80 -e echo here!
63115ef88664f1186ea012e41138747725790383c741c12ca8675c3058383e68
$ ss -lntp | grep 8080
LISTEN 0 128 :::8080 :::* users:(("exe",pid=6287,fd=4))
$ docker run busybox nc <any_host_ip> 8080
here!
Please remember, container is not available by default to the ourside world.
When you running the svn-server container, you published the container's 18080 port and mapped it from the host's 18080 port. So you can access it by http://your_host_IP:18080.
From your two docker run commands, both svn-server container and my-mongo container are on the default bridge network. These two containers are connected by docker0, so they can communicate each other directly by localhost.
But if you tried to access http://your_host_IP:18080 from within your my-mongo container, that means your request would first be send to docker0, but docker0 will drop your request because you're trying to access the host, not the svn-server container.
So try this curl http://localhost:18080 or curl http://svn-server_IP:18080 from my-mongo container to access svn-server container.

Can not access nginx container on a local windows machine

I'm running an nginx container on a windows 10 machine. I've stripped it down to a bare minimum - an nginx image provided in the Docker hub. I'm running it using:
docker run --name ng -d -P nginx
This is the output of docker ps:
b5411ff47ca6 nginx "nginx -g 'daemon off" 22 seconds ago Up 21 seconds 0.0.0.0:32771->80/tcp, 0.0.0.0:32770->443/tcp ng
And this is the IP I'm getting when doing docker inspect ng: "IPAddress": "172.17.0.2"
So, the next thing I'm trying to do is access the Nginx server from the host machine by opening http://172.17.0.2:32771 in browser of the host machine. This is not working (host not found etc).
Please advise
On windows, you are using Docker Toolbox, and the IP you need is 192.168.99.100 (which is the IP of the Docker Toolbox VM). The IP you got is the IP of the container inside the VM, which is not accessible directly from Windows.
Follow this article... https://docs.docker.com/get-started/part2/#run-the-app
And make sure your application is running not just docker.
docker run -d -p 4000:80 friendlyhello
After this on Windows 10 host machine
Worked http://192.168.99.100:4000/
Not working: http://localhost:4000/
I used the following command to map the internal port 80 on the running container to port 82 off localhost:
docker run --name webserver2 -d -p 82:80 nginx
accessing nginx image off localhost:82 works great.
The port you want to access from your local web browser is the first number before the :80 which is where nginx image runs virtually in the container.
There is lots of miscommunication out there on the issue -- it's a simple port mapping between the host machine (Windows you are running) and the container running on docker.

docker nginx container not receiving request from outside, connection refused

I have a running nginx container: # docker run --name mynginx1 -P -d nginx;
And got its PORT info by docker ps: 0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp
Then I could get response from within the container(id: c30991a04b2f):
docker exec -i -t c3099 bash
curl http://localhost => which return the default index.html page content, it works
However, when I make the curl http://localhost:32769 outside of the container, I got this:
curl: (7) failed to connect to localhost port 32769: Connection refused
I am running on a mac with docker version 1.9.0; nginx latest
Does anyone know what cause this? Any help? thank you
If you are On OSX, you are probably using a VirtualBox VM for your docker environment.
Make sure you have forwarded your port 32769 to your actual host (the mac), in order for that port to be visible from localhost.
This is valid for the old boot2docker, or the new docker machine.
VBoxManage controlvm "boot2docker-vm" --natpf1 "tcp-port32769 ,tcp,,32769,,32769"
VBoxManage controlvm "boot2docker-vm" --natpf1 "udp-port32769 ,udp,,32769,,$32769
(controlvm if the VM is running, modifyvm is the VM is stopped)
(replace "boot2docker-vm" b ythe name of your vm: see docker-machine ls)
I would recommend to not use -P, but a static port mapping -p xxx:80 -p yyy:443.
That way, you can do that port forwarding once, using fixed values.
Of course, you can access the VM directly through docker-machine ip vmname
curl http://$(docker-machine ip vmname):32769
Solved.. I misunderstood how docker port mapping works.
Since I'm using mac, the host for nginx container is a VM, 0.0.0.0:32769->80/tcp maps the port 80 of the container to the port 32769 of the VM.
solution:
docker-machine ip vm-name => 192.168.99.xx
curl http://192.168.99.xx:32769
Not exactly answers for your question but spend some time trying to figure out similar thing in context of "why is my docker container not connecting to elastic search localhost:9200" and this was the first S.O. question that pops up, so I hope it helps some other googling person
if you are linking containers together (e.g. docker run --rm --name web2 --link db:db training/webapp env)
... then Dockers adds enviroment variables:
DB_NAME=/web2/db
DB_PORT=tcp://172.17.0.5:5432
DB_PORT_5432_TCP=tcp://172.17.0.5:5432
DB_PORT_5432_TCP_PROTO=tcp
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_ADDR=172.17.0.5
... and also updates your /etc/hosts
# /etc/hosts
#...
172.17.0.9 db
so you can technically connect to ping db
https://docs.docker.com/v1.8/userguide/dockerlinks/
so for elastic search is
# /etc/hosts
# ...
172.17.0.28 elasticsearch f9db83d0dfb5 ecs-awseb-qa-3Pobblecom-env-f7yq6jhmpm-10-elasticsearch-fcbfe5e2b685d0984a00
so wget elasticseach:9200 will work

How do I connect a Docker container running in boot2docker to a network service running on another host?

I am using the latest version of boot2docker version 1.3.2, 495c19a on a windows 7 (SP1) 64 bit machine.
My docker container is running a celery process which attempts to connect to a rabbitMQ service running on the same machine that boot2docker is running on.
The Celery process running within the docker container cannot connect to RabbitMQ and reports the following :
[2014-12-02 10:28:41,141: ERROR/MainProcess] consumer: Cannot connect
to amqp:// guest:**#127.0.0.1:5672//: [Errno 111] Connection refused.
Trying again in 2.00 seconds...
I have reason to believe this is a network related issue, associated with routing from the container, to the VirtualBox host, and from the host to the RabbitMQ service running on the local machine; I do not know how to configure this and I was wondering if anyone can advise me how to proceed?
I tried setting up port 5672 in port forwarding but it didn't work (but I believe this is for incoming traffic to the VM, like boot2docker ssh).
I am running the container as docker run -i -t tagname
I am not specifying a host with -h when I run the container.
I'm sorry if this question appears rather clueless or if the answer appears obvious ... I appreciate any help!
Some additional information :
The routing table of the host VM is what boot2docker configured during installation as follows :
docker0 IP Address is 172.17.42.1
eth0 IP Address is 10.0.2.15
eth1 IP Address is 192.168.59.103
eth0 is attached to NAT (Adapter 1) in the VirtualBox VM network configuration.
Adapter 1 has port forwarding setup for ssh; default setting of host IP 127.0.0.1, host port 2022, guest port 22.
eth1 is attached to Host-only adapter (Adapter 2).
Both adapters are set to promiscuous mode (allow all).
The IP Address of the docker container is 172.17.0.33.
[2014-12-02 10:28:41,141: ERROR/MainProcess] consumer: Cannot connect to amqp:// guest:**#127.0.0.1:5672//: [Errno 111] Connection refused. Trying again in 2.00 seconds...
127.0.0.1 is a special IP address that means "me", and inside the container it means "me the container", so this is why it is not connecting to the outer host. So the first thing to do is change the IP address where you are trying to connect to Rabbit to that of the outer host where it is running.
Then you probably have to do something about routing, but let's take one step at a time.
as your RabbitMQ server is running on your Windows host, you need to tell your container that it should talk to that IP - which would probably be 192.168.59.3
most importantly, your container's 127.0.0.1 is only a loopback device to that container's services - not even the boot2docker vm's ports.
You could set up an ambassador container that has --expose=80 and uses something like socat to forward all traffic from that container to your host (see svendowideit/ambassador). Then you'd --link that ambassador container to your current image
but personally, I'd avoid that initially, and just configure your containerised app to talk to the real host's IP
You have to specifc explicitely ports for port redirection separately for boot2docker and docker.
Please try this:
c:\>boot2docker init
c:\>boot2docker up
c:\>boot2docker ssh -L 0.0.0.0:5672:localhost:5672
docker#boot2docker:~$ docker run -it -p 5672:5672 tagname

Resources