These days, many applications are installed via containers. Traefik is a modern open-source reverse proxy and ingress controller that simplifies and secures service deployment.

In this article, we’ll set up Traefik and use LetsEncrypt to obtain certificates for your applications.

Requirements:

  • Docker and Docker Compose installed on your server
  • Public Domain name
  • Port 80 & 443 forwarded from your router to your server

Setup Traefik with Docker

Traefik will run inside a docker container with Docker Compose. First we need to make the needed directories and files needed for Traefik to start.

mkdir traefik
nano traefik/docker-compose.yml
# Project URL: https://github.com/traefik/traefik
# Docs URL: https://doc.traefik.io/traefik/
services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    environment:
      - TZ=Europe/Amsterdam # Change this to your timezone
    networks:
      - frontend
    ports:
      - 80:80 # HTTP entryPoints
      - 443:443 # HTTPS entryPoints
      - 8080:8080 # Dashbaord WebGui 
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro # Docker socket to watch for Traefik
      - ./traefik.yml:/traefik.yml:ro # Traefik config file
      - traefik-certs:/certs # Docker volume to store the acme file for the Certifactes

volumes:
  traefik-certs:
    name: traefik-certs

networks:
  proxy:
    name: frontend

Traefik configuration

We need to make a traefik.yml file which will contain the configuration for Traefik.

nano treafik/traefik.yml
api:
  dashboard: true # Optional can be disabled
  insecure: true # Optional can be disabled
  debug: false # Optional can be Enabled if needed for troubleshooting 
entryPoints:
  web:
    address: ":80"
  # Optional if you want to redirect all HTTP to HTTPS
  #  http:
  #    redirections:
  #      entryPoint:
  #        to: websecure
  #        scheme: https
  websecure:
    address: ":443"
serversTransport:
  insecureSkipVerify: true
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: proxy # Optional; Only use the "proxy" Docker network, even if containers are on multiple networks.
certificatesResolvers:
  letencrypt:
    acme:
      email: [email protected]
      storage: /certs/acme.json
      # caServer: https://acme-v02.api.letsencrypt.org/directory # prod (default)
      caServer: https://acme-staging-v02.api.letsencrypt.org/directory # staging
      httpChallenge:
        entryPoint: web

Start Traefik

Run the command below to start the container.

docker compose -f traefik/docker-compose.yml up -d

Then you can access the dashboard at http://serverip:8080.

Add service

To verify everything works, we’ll start a simple service. We will use the whoami application from Traefik. It’s just a HTTP service to display some browers and OS information.

To do so we will make another directory called whoami and a docker-compose.yml

mkdir whoami
nano whoami/docker-compose.yml
services:
    whoami:
        container_name: simple-service
        image: traefik/whoami
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.whoami.rule=Host(`test.example.com`)"
            - "traefik.http.routers.whoami.entrypoints=websecure"
            - "traefik.http.routers.whoami.tls=true"
            - "traefik.http.routers.whoami.tls.certresolver=letencrypt"
            - "traefik.http.services.whoami.loadbalancer.server.port=80"
        networks:
            - proxy
networks:
  proxy:
    name: proxy

Change the test.example.com with your own domain name. Don’t forget to create it at your DNS provider. Run the command below to start the container.

docker compose -f whoami/docker-compose.yml up -d

Production Certificates

Now everything is working we need to change the CaServer to the production version, so we can obtain trusted certificates . We also have to remove the certificates from the staging server otherwise Traefik will not request new ones. To do this we stop the Traefik docker container and remove the docker volume which holds the acme.json with the certificates.

docker stop traefik
docker volume rm treafik

In the traefik.yml uncomment the first CaServer and comment the second one.

nano treafik/treafik.yml
...
      caServer: https://acme-v02.api.letsencrypt.org/directory # prod (default)
      #caServer: https://acme-staging-v02.api.letsencrypt.org/directory # staging
...

Restart Traefik container to obtain the trusted certificates. Run the command below to start the container.

docker compose -f traefik/docker-compose.yml up -d

You can use the same test service we made before the check if you now get the trusted certificates.

Note: some browsers keep a hold on the previous served certificates for some time. If you still get the staging certificate, try another browser or incognito window

Clean up
Now everything is working with production as well. We can remove the test service we made. In the whoami folder run:

docker compose -f whoami/docker-compose.yml down
sudo rm -rf whoami

Conclusion

Now we have Traefik running as a proxy in front of our applications. Securing it with a Certificate and all reachable on the their own domain names 🙂