I am trying to get a container built that has ports forwarded, such that code running in the container can access a remote db for instance.
So I put the line
CMD ssh -L 27017:localhost:27017
in my dockerfile and then run it, but in no case do I see ports forwarded (I tried RUN instead of cmd, and tried both interactively running the container or using -d , but in the former case I don't have forwarding and in the latter case the container exits soon after starting, even after tacking && /bin/bash to the end of the ssh command).
The only way I have succeeded doing this is doing an interactive run
$docker run -it --name cont_name im_name /bin/bash
and then from the interactive shell doing the ssh necessary for port forwarding (which now ties up the shell). Then from another window on my local host, I 'get inside' the first container using
$ docker exec -it cont_name bash
where I now indeed see ports forwarded . Is there a better/automatic way to do this? 'screen' seems to be a hassle to get running in a container.
I think what you want to do is "bind" the port from the container to the host. First thing you need to know is if the port has been exposed via EXPOSE in the docker container you plan on using. The next thing would be to add this to the docker run...:
-p 127.0.0.1:3360:3306
Let's assume it's a mysql instance that you are using, the port that is exposed is 3306, so you would bind that to the host on the same port or whatever port you prefer on the host.
Related
I have created an image of my application and run a container on one machine. my inner container port is: 8081.
I see that the container is running.
I would like to talk with that container from another machine from an application that doesnt run as a docker container, with a GET request, all the machines in the same VLAN.
How do I communicate with that docker container from another machine? with which ip and port ?
in the first trial - I run the container with the exposed port as the inner port :
sudo docker run -d -p 8081:8081 myimage:2.0
in my second trial I run the container like this:
sudo docker run -d -p 80:8081 myimage:2.0
_______
Update:
so I would like to share what was the problem with my container:
so initially I was adding at the end of my docker file the following line so that it will not exit immediately.:
CMD tail -f /dev/null
it seems to run however only when adding in my sh script
while true; do sleep 1000; done
I was able to access my container.
Exposing the port with the -p <outside>:<inside> flag will pass through the all traffic on the outside port of your machine running the container to the inside port in your container. So you can just communicate with the container through either port 80 or port 8081 depending on what command you start your container with. The ip will be the ip of the machine running the container.
In my case I was running sh file from the Dockerfile.
Adding: "while true; do sleep 1000; done" to my sh file solved the issue.
this is in addition to Exposing the port with the -p : flag
I am creating an Nginx container that I would like to access locally at http://api. Using Docker Machine, I assumed running docker-machine create default and docker-machine ip default to receive the IP and editing my hosts file to something like this:
# docker-machine ip default --> 192.168.99.100
192.168.99.100 api
should map requests to api\ to the Docker Machine IP and serve my content.
Two things are confusing me:
I launch Docker through the Mac App and can create Nginx containers and access content at http://localhost. However, running docker-machine ls returns no machines. This is confusing because I thought Docker had to run on a VM.
Starting from scratch and starting Docker Machine, then spinning up containers seems to have no effect. In other words, I still can access content at http://localhost but not http://api
Instead of accessing my container at http://localhost I want to access it at http://api. How do I do this?
I'm using Docker for Mac 17.12 and Docker Machine 0.14.
On the base of your this question:
Instead of accessing my container at http://localhost I want to access
it at http://api. How do I do this?
Your docker run command:
docker run -it --rm --name test --add-host api:192.168.43.8 -p 80:80 apachehttpd
1st Thing: The --add-host flag add value to /etc/hosts in your container /etc/hosts so http://api will also response inside the container if ping inside that container.
This is how will ping response inside container
2nd Thing: Edit your host etc/hosts file and add
api 192.168.43.8 [your ip]
This is how you can see in Browser.
I am new to docker, and I am a bit confused about what the following command options do specifically for the command I came across.
--name : appname is the name of the image?
-t : Run in terminal?
-d : run as daemon?
-p : for somebody outside the container to talk to port 9090 they have to connect on port 9000?
Same for port 15501 but it is a udp port?
appname2: name assigned to running image?
docker run -t --name=appname -p 9090:9000 -p 15501:15501/udp -d appname2
docker run -t --name=appname -p 9090:9000 -p 15501:15501/udp -d appname2
Q: --name : appname is the name of the image?
No. It's the name of the container that you are creating (optional).
--name string Assign a name to the container
Q: -t : Run in terminal?
-t, --tty Allocate a pseudo-TTY
Q: -d : run as daemon?
Sort of. It means that you want to run your container detached from your terminal.
-d, --detach Run container in background and print container ID
Q: -p : for somebody outside the container to talk to port 9090 they have to connect on port 9000?
9090:9000 means: port 9090 on the host machine binded to port 9000 on the container. To talk to the container port someone outside should talk to 9090.
-p, --publish list Publish a container's port(s) to the host (default [])
Q: Same for port 15501 but it is a udp port?
Right.
Q: appname2: name assigned to running image?
That is the image that you are running on. The container is based on top of it.
Bonus! You can find all of this info here: docker help run
Bonus 2! Try it yourself:
docker run -d -it --name my-container alpine sh
docker inspect my-container
# See all this funny output. It's all about the container that you've created
From https://docs.docker.com/engine/reference/run/
The -d flag means detached. When you run a docker container, you can either run a container in foreground, or you can run it in the background. The choice of how to run your container really depends on your use case. If, for example, you run an OS container with some functionality, you would probably want run the container in foreground in order to use this functionality. But if you run a DB server, you may want to run it in the background.
The -p flag, when used, publishes all exposed ports to the host interfaces. If for example you run a DB server inside a container which has some ports exposed, and you wish to communicate to the server from a distance, you may want to map the ports inside the container to a single or multiple ports of choice on your host system. That way when you connect to the port on your host, you connect to the docker server running inside of it (I hope this is clear). The mapping format is as follows:
ip:hostPort:contain`enter code here`erPort | ip::containerPort | hostPort:containerPort | containerPort
The --name flag gives the running container a nice name. If not used, it would generate a name. It can be used, for example, if you executed a container in detached mode, and then you wanted to get inside the container using the attach command.
The -t flag allocates a text console for the container.
appname2 is the name of the docker image.
I have two services running in separate containers, one is grunt(application) and runs off port 9000 and the other is sails.js (server) which runs off port 1337. What I want to try to do is have the client app connect with the server through localhost:1337. Is this feasible? Thanks.
HOST
You won't be able to connect to the other container with localhost (as localhost is the current container) but you can connect via the container host (the host that is running your container). In your case you need boot2docker VM IP (echo $(boot2docker ip)). For this to work, you need to expose your port at the host level (which you are doing with -p 1337:1337).
LINK
Another solution that is most common and that I prefer when possible, is to link the containers.
You need to add the --name flag to the server docker run command:
--name sails_server
You need to add the --link flag to the application docker run command:
--link sails_server:sails_server
And inside your application, you will be able to access the server at sail_server:1337
You could also use environment variables to get the server IP. See documentation: https://docs.docker.com/userguide/dockerlinks/
BONUS: DOCKER-COMPOSE
Your run commands may start to be a bit long... in this case I like to use docker-compose that allows me to define my containers and their relationships (volumes, names, link, commands...) in one file.
Yes if you use docker parameter -p 1337:1337 in your docker run command, it will expose the port 1337 from inside the container to your localhost:1337
We can create a new container and define your application port in docker run command like
sudo docker run -d -p 5000:5000 training/webapp python app.py
or
sudo docker run -d -P training/webapp python app.py
But, what if someone forgot to specify -p or -P option in docker run command? The container get created and runs the application locally. Now how could I assign a port on which application is running locally in container to the port of my Ubuntu host machine?
Kindly, help on this.
Thanks.
Short: You can't. You need to stop the container (or not) and start a new one with the proper parameters.
Docker spins up a local proxy and setup the iptables for proper NAT. If you really can't start a new container, you could manually setup the iptables and spin up a socat. You can take a look at the network part of the Docker code for more info.