# Version of the Composefile spec; this is the latest version: "3.9" # Each service is a single container services: ### https://github.com/traefik/traefik ## Files for basicauth middleware should be generated with the following: # $ htpasswd -c "${filename}" "${username}" traefik: # The base image to use for the container image: traefik:2.6 # The container name that will show up in e.g. `docker ps` container_name: traefik # Always restart the container on failure or reboot unless manually stopped restart: unless-stopped # Arguments passed to the command running inside the container, used for static configuration of traefik command: # Logs to specified file in common log format - "--accesslog=true" - "--log.filePath=/var/log/traefik.log" - "--log.level=ERROR" # Used for dashboard - "--api" # Traefik will request and renew certificates from LetsEncrypt via the ACME protocol # The certificates will be domain-validated via an HTTP request to /.well-known/acme-challenge/ - "--certificatesresolvers.letsencrypt-http.acme.httpchallenge.entrypoint=http" - "--certificatesresolvers.letsencrypt-http.acme.storage=/certs/acme.http.json" # An entrypoint maps a listening port to a service - "--entrypoints.http.address=:80" - "--entrypoints.http.http.redirections.entrypoint.scheme=https" - "--entrypoints.http.http.redirections.entrypoint.to=https" - "--entrypoints.https.address=:443" # Tells traefik to read container labels for configuration - "--providers.docker=true" # By default, traefik attempts to handle every container on every network; we prefer explicit config - "--providers.docker.exposedbydefault=false" - "--providers.docker.network=traefik" # Config files can be in either toml or yaml format - "--providers.file.directory=/conf" - "--providers.file.watch=true" # Arbitrary container metadata, used to dynamically configure traefik at runtime labels: # Mandatory, tells traefik to route for the container - "traefik.enable=true" # Middlewares are used to modify traffic in-flight (see https://doc.traefik.io/traefik/middlewares/overview/) - "traefik.http.middlewares.compress.compress=true" - "traefik.http.middlewares.adminauth.basicauth.usersfile=/conf/auth/vtinoc" # Specifies the URL(s) that will be routed to the container - "traefik.http.routers.traefik.rule=Host(`dashboard.example.tld`)" # Specifies the ports that the service will listen on (declared in command: section) - "traefik.http.routers.traefik.entrypoints=https" # This router points to a special internal service instead of a port on a container - "traefik.http.routers.traefik.service=api@internal" # Enables automatic HTTPS certificate generation and renewal, using HTTP domain validation - "traefik.http.routers.traefik.tls.certresolver=letsencrypt-http" # Requires HTTP basicauth for access and only allows traffic from the subnets listed in whitelist.yaml - "traefik.http.routers.traefik.middlewares=adminauth,whitelist@file" # Traefik binds to the http and https ports, then routes traffic to non-port-forwarded containers ports: - "80:80" - "443:443" # Only services attached to this network will be handled by traefik networks: - traefik # Host volumes to mount to the container; used for persistent storage # Source: path on host, target: path inside container # ***Everything not stored at a path specified here will be lost when the container is rebuilt*** volumes: # Contains all TLS certificates - type: bind source: /mnt/docker/traefik/certs target: /certs # Directory for runtime config via file provider - type: bind source: /mnt/docker/traefik/config target: /conf read_only: true # Traefik needs to be able to read the docker socket to read container labels - type: bind source: /var/run/docker.sock target: /var/run/docker.sock read_only: true ### https://git.seedno.de/seednode/docker-nginx nginx: image: nginx:latest container_name: nginx restart: unless-stopped # The container will only become active and routable when the php-fpm container is running depends_on: - nginx-php-fpm labels: - "traefik.enable=true" - "traefik.http.routers.nginx.rule=Host(`example.tld`)" - "traefik.http.routers.nginx.entrypoints=https" - "traefik.http.routers.nginx.tls.certresolver=letsencrypt-http" - "traefik.http.routers.nginx.middlewares=compress" - "traefik.http.routers.nginx.service=nginx" # Specifies the port to route traffic to on the container (in this case, 8080/TCP) - "traefik.http.services.nginx.loadbalancer.server.port=8080" networks: # Used to allow traefik to reverse proxy to the container, allows internet access - traefik # Used to talk to php-fpm, does not allow internet access - php # Config and webroot directories are mounted readonly here because nginx has no reason to modify them volumes: # Config directory - type: bind source: /mnt/docker/nginx/config target: /etc/nginx read_only: true # Logging directory - type: bind source: /mnt/docker/nginx/logs target: /var/log/nginx # Webroot directory - type: bind source: /var/www/html target: /var/www/html read_only: true # PHP is split into its own container and denied internet access # Nginx talks to it over an internal-only network nginx-php-fpm: image: php:8-fpm-alpine container_name: nginx-php-fpm restart: unless-stopped networks: - php # The php container needs to be able to access any files it might use # We mount the webroot here so it can access any needed .php files volumes: - type: bind source: /var/www/html target: /var/www/html read_only: true # Any networks referenced by services must be declared here networks: # Used for communication with the traefik container traefik: name: traefik # Set a custom name for the bridge interface on the host driver: bridge driver_opts: com.docker.network.bridge.name: br_traefik # Declare a custom DHCP scope for containers on the network ipam: driver: default config: - subnet: 10.160.36.0/22 # Internal networks do not provide internet access, only inter-container access php: name: php internal: true