As a relative docker and Traefik novice, I am trying to get Traefik with multiple services in separate docker-compose files running. For illustration purposes, the first service A is a simple web service (nginxdemos/hello) with an additional database (postgres).
My traefik/docker-compose.yml is as follows:
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080" # Traefik Dashboard
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- web
networks:
web:
external: true
The service-A/docker-compose.yml looks as follows:
version: '3.8'
services:
service-a:
image: nginxdemos/hello
environment:
- DATABASE_URL=postgresql://user:password@service-a-db:5432/dbname
labels:
- "traefik.enable=true"
- "traefik.http.routers.service-a.rule=Host(`a.dock.er`)"
- "traefik.http.services.service-a.loadbalancer.server.port=80"
networks:
# - service-a-network
- web
ports:
- 9080:80 # just for testing
# depends_on:
# - service-a-db
service-a-db:
image: postgres:13
environment:
- POSTGRES_DB=dbname
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
networks:
- service-a-network
networks:
service-a-network:
internal: true
web:
external: true
With this configuration, the service is accessible through Traefik via 'A.dock.er'.
However, as soon as I add the additional 'service-a-network' network (as well as the 'depends_on' option) to service-a, the service is no longer accessible via Traefik (but still accessible via port 9080).
I am lost, what is causing this. I believe this should be the correct configuration, with separating internal sub-services into their own network and thus having the main service in both the 'public' Traefik network as well as the internal network.
Any help would be greatly appreciated.
When you have a service connected to multiple networks, traefik will see multiple ip addresses for that service...and it will pick a random one when it tries to connect. This won't work if it picks an address on a network to which it is not connected.
You can tell traefik which network to use by setting the traefik.docker.network
label on the service with multiple connections. If we rewrite service-a
like this, it will work as expected:
services:
service-a:
image: nginxdemos/hello
environment:
- DATABASE_URL=postgresql://user:password@service-a-db:5432/dbname
labels:
- "traefik.enable=true"
- "traefik.http.routers.service-a.rule=Host(`a.dock.er`)"
- "traefik.http.services.service-a.loadbalancer.server.port=80"
- "traefik.docker.network=web"
networks:
- service-a-network
- web
With that in place:
$ curl -s http://localhost -H Host:a.dock.er
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
.
.
.