I have a docker container running this configuration for the gitlab-ce image:
version: "3"
services:
gitlab:
hostname: gitlab.mydomain.com
image: gitlab/gitlab-ce:latest
container_name: gitlab
restart: always
ports:
- 3000:80
volumes:
- /opt/gitlab/config:/etc/gitlab
- /opt/gitlab/logs:/var/log/gitlab
- /opt/gitlab/data:/var/opt/gitlab
networks:
default:
external:
name: custom_network
When running docker ps i see my container up and running with the 80 container port mapped to the 3000 host machine port as intended.
Altough when running : wget -O- https://172.25.0.2:3000 i am getting this error message:
Connecting to 172.25.0.2:3000... failed: Connection refused.
When you map a port, you should use the host IPs to access through the mapped port.
So if you need to access port 80 use the container IP.
If you need to access port 3000 use the host IP or localhost of the main host itself or even if you have a private interface inside your host.
So this command: wget -O- https://172.25.0.2:3000 means that you are talking to the container directly not through the mapped port and requesting a service listening on port 3000 which is not true so the result will be connection refused.
Related
i'm new to docker networking and nginx stuff, but try to "dockerize" everything on a local devserver. for tests a docker image with nginx which should redirect another container (gogs) from port 3000 to a specific url with port 80. And i want to have the reverse proxy configs and the docker images "separated", for each "app" an own docker-compose file.
so i should reach with http://app.test.local the gog installation.
BUT: i reach with http://app.test.local only a bad gateway of nginx and with http://app.test.local:3000 i reach the gog installation...
i tried many tutorials, but somehwere there have to be an error, thats slips in every time
so what i did:
$ docker network create testserver-network
created
docker-compose for nginx:
version: '3'
services:
proxy:
container_name: proxy
hostname: proxy
image: nginx
ports:
- 80:80
- 443:443
volumes:
- /docker/proxy/config:/etc/nginx
- /docker/proxy/certs:/etc/ssl/private
networks:
- testserver-network
networks:
testserver-network:
and one for gogs:
version: '3'
services:
gogs:
container_name: gogs
hostname: gogs
image: gogs/gogs
ports:
- 3000:3000
- "10022:22"
volumes:
- /docker/gogs/data:/var/gogs/data
networks:
- testserver-network
networks:
testserver-network:
(mapped directories work)
configured default.conf of nginx:
# upstream gogs {
# server 0.0.0.0:10880;
# }
server {
listen 80;
server_name app.test.local;
location / {
proxy_pass http://localhost:3000;
}
}
and added to hosts file on client
app.test.local <server ip>
docker exec proxy nginx -t and docker exec proxy nginx -s reload say everythings fine...
Answer
You should connect both containers to the same docker network and then proxy to http://gogs:3000 instead. You also shouldn't need to expose port 3000 on your localhost unless you want http://app.test.local:3000 to work. I think ideally you should remove that, so http://app.test.local should proxy to your gogs server, and http://app.test.local:3000 should error out.
Explanation
gogs is exposed on port 3000 inside its container, which is then further exposed on port 3000 on your host machine. The nginx container does not have access to port 3000 on your host, so when it tries to proxy to http://localhost:3000 it is proxying to port 3000 inside the nginx container (which is hosting nothing).
After you have joined the containers to the same network, you should be able to reference the gogs container from the nginx container by its hostname (which you've set to gogs). Now nginx will proxy through the docker network. So you should be able to perform the proxy without needing to expose 3000 on your local machine.
I'm running a container via docker-compose on Ubuntu 20.04, and I can't ping or curl the web server that's running inside from the host machine that's running docker.
I've given the container a static IP, and if I open a shell in the container I can see the service running fine and curl it as expected.
My docker-compose.yml looks like this:
version: "2.1"
services:
container:
image: imagename
container_name: container
networks:
net:
ipv4_address: 172.20.0.5
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/London
ports:
- 9000:9000
restart: unless-stopped
networks:
net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
But if I curl -v 172.20.0.5:9000 from the same machine, I get
* Trying 172.20.0.5:9000...
* TCP_NODELAY set
* connect to 172.20.0.5 port 9000 failed: No route to host
* Failed to connect to 172.20.0.5 port 9000: No route to host
* Closing connection 0
curl: (7) Failed to connect to 172.20.0.5 port 9000: No route to host
My best guess is something to do with iptables or firewall rules? I've not changed those at all from the default Docker set up. With host network mode it does work, but exposes the 9000 port publicly. I want to have it only accessible locally and then set it up behind a reverse proxy. Thanks.
The static IP you gave is within the network docker created. Your host is correctly telling you that it has no routes to that subnet. However you are binding the containers port 9000 to your host port 9000, thus you should be able to ping/curl localhost:9000. If that doesn't work your webserver may need to listen on on 0.0.0.0
I want to monitor redis running in webdis docker container.
I use telegraf which collects redis stats but, telegraf is installed on host machine and it cannot connect to redis as it is running inside docker on 6379 port.
I tried to map docker port 6379 on which redis is running inside docker with hosts 6379 port so telegraf can listen to redis metrices, but telegraf cannot listen as connection breaks.
when I use telnet on host, I get connection closed by foreign host error.
telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.
Also, I am able to connect to webdis port on host machine, which is running on port 7379 inside wedis container.
To start webdis I am using following command : "docker run -d -p 8080:7379 -p 6379:6379 webdis"
Further to debug, I checked that redis inside webdis container is running on interface 127.0.0.1:6379
I checked that it should be running on 0.0.0.0:6379 in-order for port mapping to work properly.
How can I run redis inside webdis image on 0.0.0.0:6379?
Is there any other way I can monitor redis server running inside webdis container?
I tried to start redis-server inside webdis container by binding it to 0.0.0.0 using redis.conf file, but it still binds with 127.0.0.1
To which docker image are you refering. Is it this one? https://github.com/anapsix/docker-webdis/
If yes, when checking the Dockerfile, it does not include redis itself but in docker-compose.yaml there is a redis service include. This one does not expose ports which you need to connect to redis from outside of the container.
You need to change redis service to the following:
...
redis:
image: 'anapsix/redis:latest'
ports:
- '6379:6379'
I have this problem recently ago and I solve it.
webdis.Dockerfile
FROM nicolas/webdis:0.1.19
EXPOSE 6379
EXPOSE 7379
RUN sed -i "s/127.0.0.1/0.0.0.0/g" /etc/redis.conf
docker-compose.yaml
version: "3.8"
services:
webdis:
build:
context: .
dockerfile: webdis.Dockerfile
image: webdis_with_redis_expose
container_name: webdis
restart: unless-stopped
ports:
- "6379:6379"
- "7379:7379"
then execute docker-compose up
Given a docker-compose file something like this
version: "3.8"
services:
service-one:
ports:
- "8881:8080"
image: service-one:latest
service-one:
ports:
- "8882:8080"
image: service-two:latest
what happens is that service-one is exposed to the host network on port 8881 and service-two would be exposed on the host network at port 8882.
What I'd like to be able to arrange is that in the network created for the docker-compose there be a "private host" on which service-one will be exposed at port 8881 and service-two will be exposed on port 8882 such that any container in the docker-compose network will be able to connect to the "private host" and connect to the services on their configured HOST_PORT but not on the actual docker host. That is, to have whatever network configuration that usually bridges from the CONTAINER_PORT to the HOST_PORT happen privately within the docker-compose network without having the opportunity for there to be port conflicts on the actual host network.
I tweak this to fit to your case. The idea is to run socat in a gateway so that containers nor images changed (just service names). So, from service-X-backend you are able to connect to:
service-one on port 8881, and
service-two on port 8882
Tested with nginx containers.
If you wish to make some ports public, you need to publish them from the gateway itself.
version: "3.8"
services:
service-one-backend:
image: service-one:latest
networks:
- gw
service-two-backend:
image: service-two:latest
networks:
- gw
gateway:
image: debian
networks:
gw:
aliases:
- service-one
- service-two
depends_on:
- service-one-backend
- service-two-backend
command: sh -c "apt-get update
&& apt-get install -y socat
&& nohup bash -c \"socat TCP-LISTEN: 8881,fork TCP:service-one-backend:8080 2>&1 &\"
&& socat TCP-LISTEN: 8882,fork TCP:service-two-backend:8080"
networks:
gw:
I'm looking for a way to map the same port into 2 different ports, each for another container in a different network.
consider the below docker-compose scenario:
services:
web:
build: .
ports:
- "8080:8080"
networks:
Net1:
Net2:
serv1:
image: tomcat:7.0.92-jre8
networks:
Net1:
serv2:
image: tomcat:7.0.92-jre8
networks:
Net2:
Now what I would really like to do is to actually map the "web" service port 8080 so that serv1 could consume it as 8081 and serv2 will be using it as 8082.
Is that even possible?
Thanks
Ports are published to the host, not to docker networks, and not to other docker containers. So the above "8080:8080" maps port 8080 on the docker host into that container's port 8080.
For container-to-container communication, that happens using docker's internal DNS for service discovery, and the container port. So both serv1 and serv2 can connect to http://web:8080 to reach the web service on its container port. That in no way prevents serv1 and serv2 from listening within their own container on any ports they wish.