I have an application that is meant to send UDP messages to other devices on a local network. When I run the application as a standalone Docker container using the docker run command, the behavior is as expected and the messages are sent to the correct address and port that corresponds to a computer on the local network. Please note that it works whether or not I run it with the bridge or host network. However, when attempting to run the application through docker compose the UDP messages are not sent. To verify that there was no conflict with other containers running in compose, I ran the container on its own in docker-compse and the messages were still not being sent. I tried running the container in docker-compose while specifying network_mode: host as well. I checked Wireshark and it reported that UDP messages were being sent when the application was started with docker run but none appearend when running with docker-compose. Additionally, I enabled Ipv4 forwarding from docker containers to the outside world on the host machine as described here with no luck.
Here are the two ways I am running the container:
Docker:
docker run --network host -e OUTPUT=192.168.1.3:14551 container_name
Docker-Compose:
version: "3"
services:
name:
image: name
network_mode: host # have tried with and without this
environment:
- OUTPUT=192.168.1.3:14551
I have also tried exposing the 14551 port in a ports section of the docker-compose, however that did not change anything.
What could explain the difference in behavior with docker vs docker-compose? Is it due to an extra layer of networking with docker compose specifically? Is there a workaround to get docker-compose working?
Related
I have 2 containers on a docker bridge network. One of them has an apache server that i am using as a reverse proxy to forward user to server on another container. The other container contains a server that is listening on port 8081. I have verified both containers are on the same network and when i log into an interactive shell on each container i tested successfully that i am able to ping the other container.
The problem is, is that when i am logged into the container with the apache server, i am not able to ping the actual server in the other container.
the ip address of container with server is 172.17.0.2
How i create the docker network
docker network create -d bridge jakeypoo
How i start the containers
docker container run -p 8080:8080 --network="jakeypoo" --
name="idpproxy" idpproxy:latest
docker run -p 8081:8080 --name geoserver --network="jakeypoo" geoserver:1.1.0
wouldn't the uri to reach out to the server be
http://172.17.0.2:8081/
?
PS: I am sure more information will be needed and i am new to stack overflow and will happily answer any other questions i can.
Since you started the two containers on the same --network, you can use their --name as hostnames to talk to each other. If the service inside the second container is listening on port 8080, use that port number. Remappings with docker run -p options are ignored, and you don't need a -p option to communicate between containers.
In your Apache config, you'd set up something like
ProxyPass "/" "http://geoserver:8080/"
ProxyPassReverse "/" "http://geoserver:8080/"
It's not usually useful to look up the container-private IP addresses: they will change whenever you recreate the container, and in most environments they can't be used outside of Docker (and inside of Docker the name-based lookup is easier).
(Were you to run this under Docker Compose, it automatically creates a network for you, and each service is accessible under its Compose service name. You do not need to manually set networks: or container_name: options, and like the docker run -p option, Compose ports: are not required and are ignored if present. Networking in Compose in the Docker documentation describes this further.)
Most probably this can be the reason.
when you log into one of the container that container do not know anything about the other container network. when you ping, that container think you are try to ping a service inside that container.
Try to use docker compose if you can use it in your context. Refer this link:
https://docs.docker.com/compose/
My problem is specific to k6 and InfluxDB, but i think the root cause is more general.
I'm using the official k6 distribution and its docker-compose.yml to run Grafana and InfluxDB which i start with the docker-compose up -d influxdb grafana command.
Grafana dashboard is accessible from localhost:3000, but running k6 with the recommended command $ docker run -i loadimpact/k6 run --out influxdb=http://localhost:8086/myk6db - <script.js (following this guide) k6 throws the following error (on Linux and MacOS as well):
level=error msg="InfluxDB: Couldn't write stats" error="Post \"http://localhost:8086/write?consistency=&db=myk6db&precision=ns&rp=\": dial tcp 127.0.0.1:8086: connect: connection refused"
I tried the command with localhost and 127.0.0.1 as well for InfluxDB as well. Also with IP addresses returned by docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' k6_influxdb_1 It either failed with the above error or didnt work, which means k6 didn't complain, but no data appeared in InfluxDB.
However, if i query the "internal IP" address which the network interface is using (with ifconfig command) and use that IP (192.168.1.66), everything works fine:
docker run -i loadimpact/k6 run --out influxdb=http://192.168.1.66:8086/k6db - <test.js
So my questions are:
Why does Grafana work fine with localhost:3000 and InfluxDB with localhost:8086 doesn't?
Why does only the "internal IP" work and no other IP?
I know there is a similar question, but that doesn't answer mine.
Docker containers run in an isolated network space. Docker can maintain internal networks, and there is Compose syntax to create them.
If you're making a call to a Docker container from outside Docker space but on the same host, you can usually connect to it as localhost, and the first port number listed in the Compose ports: section. If you look at the docker-compose.yml file you link to, it lists ports: [3000:3000], so port 3000 on the host forwards to port 3000 in the container; and if you're calling http://localhost:3000 from a browser on the same host, that will reach that forwarded port.
Otherwise, calls from one container to another can generally use the container's name (as in docker run --name) or the Compose service name; but, they must be on the same Docker network. That docker-compose.yml file also lists
services:
influxdb:
networks:
- k6
- grafana
so you can reach http://influxdb:8086 using the service's normal port number, provided the calling container is on one of those two networks. If the service has ports:, they're not considered for inter-container calls.
In the Docker documentation, Networking in Compose has more details on this setup.
There's one final trick that can help you run the specific command you're trying to run. docker-compose run will run a one-off command, using the setup for some container in the docker-compose.yml, except without its ports: and replacing its command:. The docker-compose.yml file you reference includes a k6 container, on the k6 network, running the loadimpact/k6 image. So you can probably run
docker-compose run k6 \
run --out influxdb=http://influxdb:8086/myk6db - \
<script.js
(And probably the K6_OUT environment variable in the docker-compose.yml can supply that --out option for you.)
You shouldn't ever need to look up the container-private IP addresses. They aren't usable in a variety of common scenarios, and in between Docker networking for calls between containers and published ports for calls from outside Docker, there are better ways to make calls to containers.
I've read this post and I've tried adding ports: "7080:7080" in docker-compose.yml but still can't connect to the container using 172.18.0.2:7080 (btw I'm a docker newbie)
The container is one of several in a DockStation project on Windows 10. The image I'm using is for OpenLiteSpeed with WordPress.
The docker-compose.yml file contents is below:
version: '2'
services:
gnome-3-28-1804:
image: ubuntudesktop/gnome-3-28-1804
firefox:
image: jlesage/firefox
browser-box:
image: jim3ma/browser-box
openlitespeed:
image: litespeedtech/openlitespeed
ports:
- "7080:7080"
Any ideas please?
UPDATE: IP 172.17.0.1 appears to be the default bridge gateway IP so I assume 172.18.0.2 for this container is in some way related to that; Docker and DockStation are both running locally on host 10.0.0.10 Not sure if the setup should even be using a bridge. http://localhost:7080/ says ERR_CONNECTION_REFUSED
UPDATE 2: I'm using Docker for Windows (Docker Desktop). Tried turning off the Windows firewall but makes no difference. Still getting ERR_CONNECTION_REFUSED for http://localhost:7080/ and http://10.0.0.10:7080/. There are 3 other containers in the project but not running, only the LiteSpeed one is running.
UPDATE 3: I created a new project and installed tutum/hello-world/ then ran the new container. The hello-world container is running and I've not found any error in the logs, but neither localhost nor 10.0.0.10 will connect, the error in Chrome is ERR_CONNECTION_REFUSED. Same if I run docker run -d -p 80 tutum/hello-world in Windows command prompt.
What is this IP (172.18.0.2) representing? Is it a remote machine where DockStation is running?
If this is a case, check if this port is publicly available on that machine. You did add ports section to the Dockerfile which will map container's port to machine's port - but it is a matter whether e.g. firewall blocks outside access to that port.
I would first troubleshoot it by trying to access localhost:7080 from 172.18.0.2 machine - if it works, your Docker configuration is good and you need to look for the problem in that machine's configuration (e.g. firewall).
I tried your Compose file on my system and it works as expected - I can access port 7080 both using my host's system IP and hostname and the container's IP and ports 80 and 443 using only the container's IP (since they're not mapped to any of the host's ports).
You did not specify whether you're using Docker for Windows or Docker Toolbox - DockStation works with both, but if you're using Docker Toolbox, then you'll have to use the virtual machine's IP or hostname to access port 7080, instead of localhost. If you're using Docker for Windows, then I do not understand what is going on - are you sure the containers are running?
As for where those IP's you mentioned come from - 172.17.0.1 is most likely your hosts IP on Docker's default bridged network. Docker-compose, by default, creates its own bridged networks for every project. In your case, in your project's network, your host's IP would be 172.18.0.1. You can view Docker's networks with command docker network ls and their details with docker network inspect <network-name>.
You should not use any of those IP's for any reason, since there's no guarantee they'll remain the same. If you need to connect from outside, map internal container ports to your Docker's host's ports, like you did with port 7080 and if you need containers to connect to each other - with docker-compose you can use service names as hostnames, without it you have to connect them to the same, non-default, bridged Docker network and use their container names as hostnames.
This solution worked for me.
docker run -d -p 127.0.0.1:80:80 tutum/hello-world
Apparently you have to specify you want the port exposed under localhost. Then localhost entered in the browser address bar loaded the Hello World page - hurrah!
Once I changed the ports in docker-compose.yml to '127.0.0.1:80:80' then it also worked when run from DockStation.
I was doing some devops and writing a script to turn my current host/nginx server/nginx setup into a host/docker/nginx server/docker/nginx set up so I can keep directories and etc the same between them.
The problem is that any ports I expose on a docker container are only accessible on the host and not from any other machines on the host network.
When typing 192.168.0.2 from a machine such as 192.168.0.3 it just says took too long to respond, but typing 192.168.0.2 from 192.168.0.2 will bring up the welcome to nginx page?! The interesting part is I did a wireshark analysis on en0 on port 80 and there are actually some packets coming through
See pastebins of packet inspections:
LAN to docker: https://pastebin.com/4qR2d1GV
Host to docker: https://pastebin.com/Wbng9nDB
I've tried using docker run -p 80:80 nginx/nginx and docker run -p 192.168.0.2:80:80 nginx/nginx and docker run -p 127.0.0.1:80:80 nginx/nginx but this doesn't seem to fix anything.
Should see welcome to nginx when connecting from 192.168.0.3 to 192.168.0.2.
this is in my dev environment which is an osx 10.13.5 system.
when I push this to my ubuntu 16.04 server it works just fine with the containerized nginx accessible from the www and when I run ngnix on my host without docker I can connect from external machines on the network too
Your description is a bit confusing the 127.0.0.1 within the port line will bind it to localhost only - you won't be able to access the docker from another machine. Remove the IP address and you should be able to access the docker from outside localhost.
I'm using a dedicated container for running generic project-related shell scripts in order to avoid having to test scripts on multiple environments(mac, win, ubuntu, debian...) and to minimize software requirements on the host OS. Even docker-compose commands are run from the console container. /var/run/docker.sock is bind mounted from host.
Everything else seems to be working fine, but for example if I run docker-compose up traefik inside the console container, traefik starts normally but it's unreachable both on the host and even on another container in the same network. If docker-compose up traefik is run from the host OS(Windows 10), traefik becomes reachable as expected. I suspect this has something to do with how Docker or docker-compose handle networking but I'm not completely sure. I did check that regardless of how I start the traefik container, the same ports appear instantly in NirSoft CurrPorts(sort of gui for netstat).
Is there any way (and how) to fix this?
EDIT
I realised that this must be somehow an error on my part, since dockerized docker guis exist and they assumably don't have any problems bringing up containers that are accessible from the host and outside world.
Now I'm wondering if this might be a simple configuration error either in my docker(-compose) settings or somewhere else on my host machine, or do guis like Portainer go through some extra steps in order to expose the started containers to the host?
For development purpose we all map the port of Traefik to 80, so I will assume the same in your case as well. Let's assume that you are running Traefik container in a port 80 which is mapped to the port 80 in the host. But according to your Traefik container the host machine is nothing but the container which is used for running the scripts. But the port 80 of the shell script container is not mapped to the Host machine of that particular container. I hope now you have been lost somewhere around the port mapping and containers.
Let me describe your situation in the image below.
To make your setup working you should deploy your containers as shown above along with the port mapping.
To simplify the answer,
docker run -t -d -p 80:80 shellScriptImage
docker run -t -d -p 80:80 traefik (- inside the shell script container)
By doing this you can access the traefik container from the outside.