A small, reusable Docker Compose setup for running Traefik as a shared reverse proxy. It provides automatic HTTP-to-HTTPS redirects, Let's Encrypt certificates, Docker service discovery, access logs, and a health check.
- Traefik
v3.7 - Automatic HTTP-to-HTTPS redirection
- Automatic TLS certificates through Let's Encrypt
- Docker provider with services disabled by default
- Shared external Docker network named
vnet - Persistent ACME certificate storage
- Access logging and container health checks
- Anonymous usage reporting disabled
- Docker Engine
- Docker Compose v2
- Ports
80and443available on the host - A domain name whose DNS records point to the server
- A public email address for Let's Encrypt notifications
The vnet network must exist before starting Traefik. Create it once on the server:
docker network create vnetTraefik and every proxied service must be connected to this network. Traefik uses vnet as its default Docker provider network, which also avoids ambiguous routing when an application is connected to multiple networks.
Copy the example environment file:
cp .env.example .envSet your Let's Encrypt email address in .env:
LETSENCRYPT_EMAIL=admin@example.comThe .env file is excluded from version control.
docker compose up -dCheck its status and logs:
docker compose ps
docker compose logs -f traefikConnect the service to vnet and add Traefik labels. Replace app.example.com and port 3000 with the hostname and internal port of your application.
services:
app:
image: your-image:latest
restart: unless-stopped
networks:
- vnet
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls=true"
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
- "traefik.http.services.app.loadbalancer.server.port=3000"
networks:
vnet:
external: true
name: vnetRouter and service names such as app must be unique across containers discovered by the same Traefik instance.
Traefik listens on ports 80 and 443. Requests arriving over HTTP are redirected to HTTPS. For enabled containers on vnet, Traefik reads Docker labels, routes requests by hostname, and obtains certificates through the Let's Encrypt HTTP-01 challenge.
Certificate state is stored in ./data/acme.json. The startup script creates the file when necessary and restricts its permissions to 600.
# Start or update the stack
docker compose up -d
# View logs
docker compose logs -f traefik
# Validate the Compose configuration
docker compose config
# Stop the stack
docker compose downBecause vnet is external, docker compose down does not remove it.
- Do not commit
.envor thedata/directory. - Keep ports
80and443reachable for normal traffic and Let's Encrypt validation. - Only containers with
traefik.enable=trueare exposed. - The Docker socket is mounted read-only, but access to it is still security-sensitive. Run only trusted containers on the host.
- The Traefik dashboard is not enabled by this configuration.
.
|-- .env.example
|-- .gitignore
|-- docker-compose.yml
`-- runtime/
`-- entrypoint.sh
This project is open-source software licensed under the MIT License. You are free to use, modify, and distribute it, including for commercial purposes, subject to the terms of the license.