My development system runs multiple containers for several web based apps. Traffic should be routed by rules through one single entry point. Here is a possible configuration with traefik as router.
Setup
Several web applications are run as docker-compose stacks. To enable sharing, one docker network connects the traefik container with all frontend app containers.
To create the common network, use this command:
docker network create --driver=bridge --attachable --internal=false traefik
Run traefik
To run traefik, use this docker-compose file:
services:
reverse-proxy:
# The official v3 Traefik docker image
image: traefik:v3.3
# Enables the web UI and tells Traefik to listen to docker
command: command: --api=true --api.basePath=/routes --providers.docker --providers.docker.network=traefik
container_name: "traefik80"
restart: "always"
labels:
- "traefik.http.routers.dashboard.rule=(PathPrefix(`/routes/api`) || PathPrefix(`/routes/dashboard`))"
- "traefik.http.routers.dashboard.service=api@internal"
ports:
# The HTTP port
- "80:80"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
networks:
- default
networks:
default:
name: traefik
Then start the instance: docker-compose up -d
The traefik dashboard provides information about enabled routes and is available at http://127.0.0.1/routes/dashboard/.
Simple example application
services:
adminer:
image: adminer:4.8.1
networks:
- traefik
labels:
- traefik.http.routers.adminer.rule=Host(`adminer.localhost`)
The adminer application is now available at http://adminer.localhost/.
Complex example
services:
adminer:
image: adminer:4.8.1
networks:
- default
- traefik
labels:
- traefik.http.routers.adminer.rule=Host(`adminer.localhost`)
maildev:
image: maildev/maildev
labels:
- traefik.http.routers.maildev.rule=Host(`maildev.localhost`)
- traefik.http.services.maildev.loadbalancer.server.port=80
networks:
- default
- traefik
database:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=admin1234
- MYSQL_PASSWORD=app123
- MYSQL_DATABASE=app
- MYSQL_USER=appuser
labels:
- "traefik.enable=false"
volumes:
- db:/var/lib/mysql
networks:
- default
networks:
traefik:
external: true
volumes:
db: null
The database container is not connected to the traefik network.