Hello,
here is an image of what I want to do
I want to use Traefik to act as proxy for multiple docker containers running Caddy, PHP, MySQL. Each container serves a unique domain that I connected the virtual server’s IP address using DNS A records (DNS lookup works fine)
This is the current setup
- /srvtraefik.toml
- /srv/traefik_dynamic.toml
- /srv/acme.json
– /srv/lcmp/docker-compose.yml
– /srv/lcmp/caddy_docker
—/srv/lcmp/caddy_docker/Caddyfile
—/srv/lcmp/caddy_docker/Dockerfile– /srv/lcmp/php_docker
— /srv/lcmp/php_docker/Dockerfile–/srv/lcmp/www
Content of traefik.toml
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.http.redirections.entryPoint]
to = "websecure"
scheme = "https"
[entryPoints.websecure]
address = ":443"
[api]
dashboard = true
[certificatesResolvers.lets-encrypt.acme]
email = "mail@mydomain.tld"
storage = "acme.json"
[certificatesResolvers.lets-encrypt.acme.tlsChallenge]
[providers.docker]
watch = true
network = "web"
[providers.file]
filename = "traefik_dynamic.toml"
Content of traefik_dynamic.toml
[http.middlewares.simpleAuth.basicAuth]
users = [
user:<pw>"
]
[http.routers.api]
rule = "Host(`monitor.mydomain.tld`)"
entrypoints = ["websecure"]
middlewares = ["simpleAuth"]
service = "api@internal"
[http.routers.api.tls]
certResolver = "lets-encrypt"
Content of acme.json
is correct
Did a chmod 600
on acme.json
Content of /srv/lcmp/docker-compose.yml
version: "3.8"
networks:
web:
# Remove external option
# driver: bridge
external: true
internal:
external: false
services:
# PHP Service
php:
build: './php_docker/'
volumes:
- ./www/:/var/www/html/
networks:
- internal
# Caddy Service
caddy:
build: './caddy_docker/'
depends_on:
- php
restart: unless-stopped
volumes:
- ./www/:/var/www/html/
- ./caddy_docker/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
labels:
- traefik.enable=true
- traefik.http.routers.caddy.rule=Host(`mydomain.tld`)
- traefik.http.routers.caddy.entrypoint=http
- traefik.http.routers.caddy.middlewares=auth
- traefik.http.routers.caddy.middlewares=https-redirect
- traefik.docker.network=web
- traefik.constraint-label=web
#- traefik.http.routers.caddy.entrypoints=websecure
- traefik.port=80
networks:
- web
healthcheck:
test: curl --fail https://mydomain.tld || exit 1
interval: 60s
retries: 5
start_period: 20s
timeout: 10s
# MySQL Service
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: <redacted>
volumes:
- mysqldata:/var/lib/mysql
networks:
- internal
# phpMyAdmin Service
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- 8080:80
environment:
PMA_HOST: mysql
networks:
- internal
depends_on:
- mysql
# Volumes
volumes:
mysqldata:
caddy_data:
caddy_config:
Content of /srv/lcmp/caddy_docker/Caddyfile
(common) {
header /* {
-Server
}
}
mydomain.tld {
encode gzip zstd
root * /var/www/html/public
php_fastcgi php:9000
file_server
header {
-server
-Link
-X-Powered-By
# disable FLoC tracking
#Permissions-Policy interest-cohort=()
# enable HSTS
Strict-Transport-Security max-age=31536000;
# disable clients from sniffing the media type
X-Content-Type-Options nosniff
# clickjacking protection
X-Frame-Options DENY
# keep referrer data off of HTTP connections
Referrer-Policy no-referrer-when-downgrade
}
}
www.mydomain.tld {
redir https://mydomain.tld{uri}
}
Content of /srv/lcmp/caddy_docker/Dockerfile
# Use the official Caddy Docker image
FROM caddy:latest
# Update package index and upgrade installed packages
RUN apk update && apk upgrade
# Copy Caddyfile to configure Caddy server
COPY Caddyfile /etc/caddy/Caddyfile
I’ve started the Traefik Docker container using this command
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $PWD/traefik.toml:/traefik.toml \
-v $PWD/traefik_dynamic.toml:/traefik_dynamic.toml \
-v $PWD/acme.json:/acme.json \
-p 80:80 \
-p 443:443 \
--network web \
--name traefik \
traefik:v2.11
The dashboard at monitor.mydomain.tld can be opened, I enter the user and password and I see Traefik’s dashboard and all the services, routers and middleware. I also see new routers and services when I run docker compose up -d
in /srv/lcmp/
The webroot of the Caddyfile
is set to /www/public
because this is what shopware requires. Before using Traefik, the setup worked fine using this docker-compose.yml
(no Traefik container running). Browsing to mydomain.tld showed the website located in /www/public
version: "3.8"
services:
# PHP Service
php:
build: './php_docker/'
volumes:
- ./www/:/var/www/html/
# Caddy Service
caddy:
build: './caddy_docker/'
depends_on:
- php
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./www/:/var/www/html/
- ./caddy_docker/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
# MySQL Service
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: <redacted>
volumes:
- mysqldata:/var/lib/mysql
# phpMyAdmin Service
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- 8080:80
environment:
PMA_HOST: mysql
depends_on:
- mysql
# Volumes
volumes:
mysqldata:
caddy_data:
caddy_config:
I’m very confused concerning the docker labels for Traefik in the caddy service section of my docker-compose.yml
and whether I need to have the ports in the specified in the caddy service section and I also do not know how to handle https since both Caddy and Docker provide automatic https support.
Here is the output of docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9f9b1caac82d lcmp-caddy "caddy run --config …" 39 minutes ago Up 39 minutes (unhealthy) 80/tcp, 443/tcp, 2019/tcp, 443/udp lcmp-caddy-1
645f0cf71aea phpmyadmin/phpmyadmin:latest "/docker-entrypoint.…" 39 minutes ago Up 39 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp lcmp-phpmyadmin-1
66d5a3b00928 lcmp-php "docker-php-entrypoi…" 39 minutes ago Up 39 minutes 9000/tcp lcmp-php-1
5cec416971b9 mysql:8.0 "docker-entrypoint.s…" 39 minutes ago Up 39 minutes 3306/tcp, 33060/tcp lcmp-mysql-1
98c739d25175 traefik:v2.11 "/entrypoint.sh trae…" 4 hours ago Up 4 hours 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp traefik
Here is the output of docker network ls
NETWORK ID NAME DRIVER SCOPE
f94a86c9651e bridge bridge local
3c11f90c3c71 host host local
7461a2865805 internal bridge local
5cdec9ce389a lcmp_internal bridge local
f41e6078c5f8 lcmp_web bridge local
b978f9127644 none null local
f83455745ea4 web bridge local
Here is the output of docker network inspect web
[
{
"Name": "web",
"Id": "f83455745ea41d2ae698b45849102742056beb5c69b4d775940ca6afa30d3b10",
"Created": "2024-03-20T10:26:15.115720734+01:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.31.0.0/16",
"Gateway": "172.31.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"98c739d25175715f6410100eb706bb0798eb355c348ac3797eff5382426fffe2": {
"Name": "traefik",
"EndpointID": "89b36aa2ec3d3da5800710dce4a8cc07d87ddfd71abf33c9b727b051c942a90a",
"MacAddress": "02:42:ac:1f:00:02",
"IPv4Address": "172.31.0.2/16",
"IPv6Address": ""
},
"9f9b1caac82d87a87fc6304362eec5933b3b18677184ef3657d7c48ece6e84d0": {
"Name": "lcmp-caddy-1",
"EndpointID": "990411546cd871a36b9e6c5f5fd52aab4cfd9d8026b974329d4fe0407ccf0c40",
"MacAddress": "02:42:ac:1f:00:03",
"IPv4Address": "172.31.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
When I curl https://mydomain.tld
i get 404 page not found
Sorry for the long post, any help is highly appreciated since I’m quite new to all this!