Traefik proxy multiple networks, application single

hmm im having trouble in relation to setting up docker compose networks and ownership

please flame my logic and show me where i am wrong

i guess i should start by saying that i think the vast majority of how people are setting up their reverse proxies is wrong, or at least could be better by being more isolated. the way people are doing it currently, is to create a proxy network and then they throw all the containers into that proxy network and have traefik route in and out of it

but in doing so, it means that all containers can talk to each other. would it not be far better as a potential attack vector and isolation to shove each of the applications you use into their own unique network and then have traefik in every single one of those networks and route accordingly?

im trying to do this, and i've got it to work but the problem i am facing is one of ownership

for example when i create
activity_NW:
name: activity_NW

and then throw that into the traefik file too, one of them will complain about the network being external

one of the solutions is to just create all these networks externally beforehand but its kind of nice that docker compose handles all of that as is...

and whilst docker compose does moan about it when starting up, it does seem to throw it into the same network even though it moans about it

do you think this is a problem and how would i rectify it whilst keeping my isolation desire

  1. to offer an example of what im talking about, this might help - now of couse something similar to this would work if its in a single docker compose but the problem i face is due to having different individual compose files

services:
traefik:
image: traefik:v2.3
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
networks:
- public_net
- app1_net
- app2_net
- app3_net
- app4_net
- app5_net

app1:
image: nginx
networks:
- app1_net
labels:
- "traefik.http.routers.app1.rule=Host(app1.example.com)"
- "traefik.docker.network=app1_net"

app2:
image: nginx
networks:
- app2_net
labels:
- "traefik.http.routers.app2.rule=Host(app2.example.com)"
- "traefik.docker.network=app2_net"

app3:
image: nginx
networks:
- app3_net
labels:
- "traefik.http.routers.app3.rule=Host(app3.example.com)"
- "traefik.docker.network=app3_net"

app4:
image: nginx
networks:
- app4_net
labels:
- "traefik.http.routers.app4.rule=Host(app4.example.com)"
- "traefik.docker.network=app4_net"

app5:
image: nginx
networks:
- app5_net
labels:
- "traefik.http.routers.app5.rule=Host(app5.example.com)"
- "traefik.docker.network=app5_net"

networks:
public_net:
name: public_net
app1_net:
name: app1_net
app2_net:
name: app2_net
app3_net:
name: app3_net
app4_net:
name: app4_net
app5_net:
name: app5_net

so possible solutions / observations;

  1. just ignore the warning, it'll just function fine then but depending upon which compose file you started first the warning will rotate but your docker network ls will function properly and traefik properly flows

  2. if you remove name: from each of them then docker compose will append at the start the stack name so if the app stack is called bacon then the network would appear in docker network ls as bacon_app1_net and traefik has a hard time then since its effectively 2 separate networks even if they are named the same across compose files and you'll find you get Gateway Timeout because it cant figure out where to go

  3. manually declaring the external networks but i dont like this solution it seems cumbersome and dumb

  4. maybe something like variable substitution for the networks and reference them in the global .env file instead, i don't know how this will pan out but it might work

  5. something im not seeing?

1 and 4 seem like frontrunners

You could create the networks with Traefik, set name and attachable, and set name and external on target services.

Make sure to set .docker.network= in router labels, as Traefik only fetched the IP during configuration discovery, and you need to tell it which network to use.

I think different networks improves security, but it’s also a lot of hassle when you have lots of services. Especially if you continuously add new ones and want HA, but need to restart Traefik every time.

Sidenote: use 3 backticks before and after code to make code/config more readable. In yaml every space matters.


Security has multiple aspects, and they all depend on your risk profile.

We use a service per tenant, all with the same software. If one instance is hacked because of a vulnerability, all others would probably be hackable, too. So the lateral movement through network might not have a big impact.

I see it more important to have a strong first line of defense (the proxy): always use latest Traefik, use restricted users for containers, potentially use a docker proxy. You don’t want your Traefik server taken over by a know vulnerability, give the bad actor root access (when escaping the container) and enable full Docker control.

Maybe check this post about Docker security.