Traefik cannot reach backend when docker-compose has port mapping - docker

My docker is in swarm mode.
I am puzzled about why traefik is no more able to reach my nexus backend as soon as I settle a port mapping from within its compose file : I got a 504 (timeout) error instead. Without the mapping, traefils works fine.
Traefik is deployed on the swarm, as a service, with the following command :
docker network create --driver=overlay traefik-net
docker service create \
--name traefik \
--constraint=node.role==manager \
--publish 80:80 --publish 8088:8080 \
--with-registry-auth \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/var/opt/data/flat/gerdce/shared/servers/traefik/out/,target=/out/ \
--mount type=bind,source=/var/opt/data/flat/gerdce/shared/servers/traefik/traefik.toml,target=/traefik.toml \
--network traefik-net \
dvckzasc03.rouen.francetelecom.fr:5000/pli/traefik \
--docker \
--docker.domain=docker.localhost \
--docker.swarmMode=true \
--docker.watch=true \
--api
(Il also tried running traefik from a docker-compose file, but with no more success)
The nexxus stack :
version: '3.3'
services:
nexus:
image: some_nexus:5000/sonatype/nexus3
volumes:
- /var/opt/data/flat/gerdce/shared/repositories/nexus/data:/nexus-data
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
labels:
- "traefik.enable=true"
- "traefik.static.frontend.rule=PathPrefix:/static/rapture"
- "traefik.serviceext.frontend.rule=PathPrefix:/service/extdirect"
- "traefik.serviceout.frontend.rule=PathPrefix:/service/outreach"
- "traefik.nexus.frontend.rule=PathPrefixStrip:/nexus"
- "traefik.port=8081"
networks:
- traefik-net
#ports:
#- "5050:5050"
networks:
traefik-net:
external: true
Everything works fine this way : traefik redirects well every call to /nexus (and s.o.) .... until I uncomment the port mapping!
I really need this port mapping, in order to login / push / pull from my VM.
Any idea on
why this is happening (have I missed stg from the docs ?
what may be the fix or workaround here?
Versions :
Docker version 18.03.0-ce, build 0520e24
docker-compose version 1.22.0, build f46880fe
Traefik 1.6.5

First, I would recommend sticking this into a docker-stack.yml like your Nexus stack file as it will be easier to maintain.
Here's an example of a traefik proxy I deployed yesterday which works with port mappings
version: "3.4"
services:
traefik:
image: traefik:latest
ports:
- "80:80"
- "443:443"
- "8080:8080"

Eventually, I had it working adding a missing label:
- "traefik.docker.network=traefik-net"

Related

What is the difference between docker run --config vs docker compose config?

So what I am looking at is a docker run command being used in to create a docker container for open telemetry that passes in a config command, and the code looks like...
$ git clone git#github.com:open-telemetry/opentelemetry-collector.git; \
cd opentelemetry-collector/examples; \
go build main.go; ./main & pid1="$!";
docker run --rm -p 13133:13133 -p 14250:14250 -p 14268:14268 \
-p 55678-55679:55678-55679 -p 4317:4317 -p 8888:8888 -p 9411:9411 \
-v "${PWD}/local/otel-config.yaml":/otel-local-config.yaml \
--name otelcol otel/opentelemetry-collector \
--config otel-local-config.yaml; \
kill $pid1; docker stop otelcol
(https://opentelemetry.io/docs/collector/getting-started/#docker)
What I don't understand is how a non-docker related config file(open telemetry config) fits into the "docker run --config" or "docker compose config" commands. Below is the open telemetry config file that seems to be non-docker related
extensions:
memory_ballast:
size_mib: 512
zpages:
endpoint: 0.0.0.0:55679
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
memory_limiter:
# 75% of maximum memory up to 4G
limit_mib: 1536
# 25% of limit up to 2G
spike_limit_mib: 512
check_interval: 5s
exporters:
logging:
logLevel: debug
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [logging]
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [logging]
extensions: [memory_ballast, zpages]
https://github.com/open-telemetry/opentelemetry-collector/blob/main/examples/local/otel-config.yaml
Now I have looked at these Docker links
https://docs.docker.com/engine/swarm/configs/#how-docker-manages-configs
https://nickjanetakis.com/blog/docker-tip-43-using-the-docker-compose-config-command
but I couldn't figure out how to get the docker run --config command in the open telemetry example to start working in docker compose with docker compose config. Here is my docker compose
version: "3.9"
services:
opentelemetry:
container_name: otel
image: otel/opentelemetry-collector:latest
volumes:
- ~/source/repos/CritterTrackerProject/DockerServices/OpenTelemetry/otel-collector-config.yml:/otel-local-config.yml
config:
- otel-local-config.yml
ports:
- 13133:13133
- 14250:14250
- 14268:14268
- 55678-55679:55678-55679
- 4317:4317
- 8888:8888
- 9411:9411
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- my-network
jaeger:
# restart: unless-stopped
container_name: jaeger
image: jaegertracing/all-in-one:latest
ports:
- 16686:16686
# - 14250:14250
# - 14268:14268
# - 5775:5775/udp
- 6831:6831/udp
# - 6832:6832/udp
# - 5778:5778
# - 9411:9411
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- my-network
postgres:
restart: always
container_name: postgres
image: postgres:latest
environment:
- POSTGRES_USER=code
- POSTGRES_PASSWORD=code
ports:
- 5432:5432
volumes:
- postgres:/var/lib/postgresql/data
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- my-network
nginx:
restart: always
container_name: webserver
image: nginx:latest
build:
context: ~/source/repos/CritterTrackerProject
dockerfile: DockerServices/Nginx/Dockerfile
ports:
- 80:80
- 443:443
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- my-network
volumes:
postgres:
networks:
my-network:
external: true
name: my-network
Here is my error after running docker compose up in a Git Bash terminal
$ docker compose -f ./DockerServices/docker-compose.yml up -d
services.opentelemetry Additional property config is not allowed
The general form of docker run is
docker run [docker options] image [command]
And if you look at your original command it matches this pattern
docker run \
--rm -p ... -v ... --name ... \ # Docker options
otel/opentelemetry-collector \ # Image
--config otel-local-config.yaml # Command
So what looks like a --config option is really the command part of the container setup; it overrides the Dockerfile CMD, and it is passed as additional arguments to the image's ENTRYPOINT.
In a Compose setup, then, this would be the container's command:.
services:
opentelemetry:
image: otel/opentelemetry-collector:latest
command: --config otel-local-config.yaml
Since this is an application-specific command string, it's unrelated to the docker-compose config command, which is a diagnostic tool that just dumps out parts of your Compose configuration.
What you're doing in the docker run command is the following mounting:
${PWD}/local/otel-config.yaml on the local host to /otel-local-config.yaml from inside the docker
You can achieve same behavior with volumes option from docker compose:
volumes:
"${PWD}/local/otel-config.yaml":/otel-local-config.yaml

traefik configuration always end with bad gateway with the lounge

I'm trying to run a docker on my personal server and make it accessible through traefik (it works if I expose directly the port).
Here is the command I tried.
# This is not working, and always ends in Bad Gateway
sudo docker run --detach \
--name thelounge \
--volume ~/.thelounge:/var/opt/thelounge \
--restart always \
--label traefik.enable=true \
--label 'traefik.http.routers.thelounge.rule=Host(`irc.example.fr`)' \
--label 'traefik.http.routers.thelounge.priority=10' \
--label 'traefik.http.routers.thelounge.entryPoints=websecure' \
--label 'traefik.http.routers.thelounge.tls=true' \
--label 'traefik.http.routers.thelounge.tls.certresolver=example' \
thelounge/thelounge:latest
Notice: example certResolver works for every other domain, and I also have this configuration for it:
[http.routers.Router-Example-To-Legacy]
# won't listen to entry point web
entryPoints = ["websecure"]
# https://docs.traefik.io/routing/routers/#rule
# rule = "Host(`localhost`)"
rule = "HostRegexp(`example.fr`, `{subdomain:.*}.example.fr`)"
service = "legacy-webserver-service"
priority = 2
[http.routers.Router-Example-To-Legacy.tls]
certResolver = "example"
[[http.routers.Router-Example-To-Legacy.tls.domains]]
main = "example.fr"
sans = ["*.example.fr"]
Problem: I have a bad gateway on curl https://irc.example.fr
This is basically running a docker directly inside a traefik network. This last word matters.
I needed to add the network of traefik to my command. To get the network I simply used docker network list.
Also I change my mind about using just the command line and I created a complete docker-compose file.
version: '3'
services:
homeirc:
image: thelounge/thelounge:latest
volumes:
- ./thelounge:/var/opt/thelounge
restart: always
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.homeirc.rule=Host(`irc.example.fr`)"
- "traefik.http.routers.homeirc.priority=10"
- "traefik.http.routers.homeirc.entryPoints=websecure"
- "traefik.http.routers.homeirc.tls=true"
- "traefik.http.routers.homeirc.tls.certresolver=example"
- "traefik.http.services.homeirc.loadbalancer.server.port=9000"
# Http redirect to https
- "traefik.http.routers.homeirc-non-secure.rule=Host(`irc.example.fr`)"
- "traefik.http.routers.homeirc-non-secure.priority=10"
- "traefik.http.routers.homeirc-non-secure.entryPoints=web"
- "traefik.http.routers.homeirc-non-secure.middlewares=home-irc-https"
- "traefik.http.middlewares.home-irc-https.redirectscheme.scheme=https"
- "traefik.http.middlewares.home-irc-https.redirectscheme.permanent=true"
networks:
traefik:
external:
name: traefikexample_default

Converting docker run to docker compose

I want to convert my docker run command, but I cannot get it working. This is the docker run command I use and works well
sudo docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $PWD/traefik.toml:/traefik.toml \
-v $PWD/acme.json:/acme.json \
-p 80:80 \
-p 443:443 \
-l traefik.frontend.rule=Host:monitor.localhost \
-l traefik.port=8080 \
--network traefik-proxy \
--name traefik \
traefik --docker
And this is the compose file I built:
version: "3"
services:
traefik:
image: traefik
container_name: traefik-2
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./traefik.toml:/traefik.toml
- ./acme.json:/acme.json
labels:
traefik.frontend.rule: "Host:monitor.localhost"
traefik.port: "8080"
networks:
default:
external:
name: traefik-proxy
The problem is that when I use docker-compose, the proxy seems to be working, but when I access the monitor site (monitor.localhost), it gives me a 404 not found. I have double checked everything, but I just can't figure it out what is wrong with the compose file. I tried to get into the shell of the container to see if it looks alright, but apparently Alpine based Traefik image doesn't have bash, or even sh.
As Wie already pointed out in the comments, you're not passing the --docker flag in your docker-compose.yml. Try it like this:
version: "3"
services:
traefik:
image: traefik
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
- ./acme.json:/acme.json
ports:
- 80:80
- 443:443
labels:
traefik.frontend.rule: Host:monitor.localhost
traefik.port: 8080
command: ["--docker"]
networks:
default:
external:
name: traefik-proxy

docker run vs docker-compose one of these things is not like the other

I have an nginx proxy setup with a shellscript that looks something like this
docker run --detach --name nginx-proxy --publish 80:80 --publish 443:443 --volume /etc/nginx/certs \
--volume /etc/nginx/vhost.d --volume /usr/share/nginx/html --volume /var/run/docker.sock:/tmp/docker.sock:ro --restart unless-stopped jwilder/nginx-proxy:alpine
echo proxy up
docker run --detach --name nginx-proxy-letsencrypt --volumes-from nginx-proxy --volume /var/run/docker.sock:/var/run/docker.sock:ro \
--restart unless-stopped jrcs/letsencrypt-nginx-proxy-companion
echo ssl companion up
docker run -d \
-e VIRTUAL_HOST=[domain] \
\-e "LETSENCRYPT_HOST=[domain]" \
-e "LETSENCRYPT_EMAIL=[emailaddress]" \
--name [domain] \
--expose 80 \
--restart always \
-v /code/[domain]:/var/www/html \
fauria/lamp
echo test site up at [domain]
and this site works properly and functions as expected.
I then stop the web server container and use the following docker-compose.yaml and it fails with a 502..
version: '3.3'
services:
lamp:
restart: always
image: fauria/lamp
container_name: [domain]
expose:
- "80"
volumes:
- /code/[domain]:/var/www/html
environment:
- VIRTUAL_HOST=[domain]
- LETSENCRYPT_HOST=[domain]
- LETSENCRYPT_EMAIL=[emailaddress]
Why? Aren't they the same? What am I missing?
When you use docker-compose, docker-compose creates a docker network for you, in which all of the services can communicate with each other. Since you simply stopped the container and started it with docker-compose, now it does not have access to the containers on your localhost. This is why you get the 502 error. What you need to do is add the other containers to your docker compose file, and make sure you are connecting to the hosts using the proper service name (instead of localhost use http://service_name:443). Alternatively you can somehow give the containers in your docker network access to your localhost, but I'm not sure how to do this. Maybe you need to use 0.0.0.0 instead of 127.0.0.1?
The problem is that i was not connecting my docker-compose to the bridge network used by default in the proxy image.
version: '3.3'
services:
lamp:
restart: always
image: fauria/lamp
network-mode: bridge
container_name: [domain]
expose:
- "80"
volumes:
- /code/[domain]:/var/www/html
environment:
- VIRTUAL_HOST=[domain]
- LETSENCRYPT_HOST=[domain]
- LETSENCRYPT_EMAIL=[emailaddress]

Running Cloudant as docker container with docker compose

I am trying to use this image https://hub.docker.com/r/ibmcom/cloudant-developer/ with docker compose, when I use the original instructions it works, however when I translate it to docker compose format it doesn't work properly, I see the dashboard page but it is empty and seems broken.
The original run command:
docker run \
--privileged \
--detach \
--volume cloudant:/srv \
--name cloudant-developer \
--publish 8080:80 \
--hostname cloudant.dev \
ibmcom/cloudant-developer
The compose file I created:
version: '3'
services:
cloudant:
image: ibmcom/cloudant-developer:latest
container_name: cloudant-developer
hostname: cloudant.dev
ports:
- "8080:80"
expose:
- "80"
volumes:
- cloudant:/srv
privileged: true
volumes:
cloudant:
Thanks for helping.
P.S - I do executed the commands for license agreement manually
Took me a while to figure this out. Turns out the cloudant docker container is tied to the default docker network subnet. Specifically, I found that haproxy was mapped to redirect to 172.17.0.2:5984 and was failing because by default docker compose creates a new network in a different ip range. There may be other issues related to this. Ultimately I found that you could run docker compose on the default docker network with the following config:
network_mode: bridge
So, your docker-compose.yml would look like this:
version: '3'
services:
cloudant:
image: ibmcom/cloudant-developer:latest
container_name: cloudant-developer
hostname: cloudant.dev
ports:
- "8080:80"
expose:
- "80"
volumes:
- cloudant:/srv
privileged: true
network_mode: bridge
volumes:
cloudant:

Resources