problem statement

In a free tier oci instance I wanted to have a single point of entry with TLS and valid certs I also wanted to have multiple containers served using a wildcard domain. Also needed to be able to add new containers and immediately have them available with cert and fqdn

BOM

  • traefik
  • duckdns
  • letsencrypt
  • docker compose
  • env-file for docker compose

docker compose

This is the choice for deploying services.

duckdns

my choice of free dns. Provides a token to be used for DNS challenge (needed for the certificate generation) All domains are also working as wildcards example: domain.com entry will be used to resolve xyz.domain.com test.domain.com www.domain.com e.t.c.

letsencrypt

provides certificates for free (throttled of course, pay the service if you need more)

traefik

proxy, lb with many capabilities like triggering certificate creation and update, redirecting traffic based on service names/fqdns

current status

currently the traefik used is in v2.11 (v3 is out in RC). Managed to do letsencrypt certificate generation with wildcard but only by using DNS-01 challenge and disabling the check the it has been updated (--certificatesresolvers.myresolver.acme.dnschallenge.disablepropagationcheck=true)

It could generate individual certs (no wildward) with the TLS challenge but that would mean we will end up having multiple certs that eventually end up in the cert database (look for csr.sh) and fqdns are eventually exposed (in case we don’t want to then this is not an option)

services:
  reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:v2.11
    # Enables the web UI and tells Traefik to listen to docker
    command:
      - "--api.insecure=true"
      - --entrypoints.web.address=:80
      - --entrypoints.web-secure.address=:443 # Declares the web-secure entrypoint in Traefik
      - --providers.docker
      # - "--entrypoints.web.http.redirections.entrypoint.to=web-secure"
      # - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      # - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      - "--log=true"
      - "--log.level=DEBUG"
      - "--accesslog=true"
      # Letsencrypt
      - "--certificatesresolvers.myresolver.acme.dnschallenge=true"
      - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=duckdns"
      - --certificatesresolvers.myresolver.acme.dnschallenge.disablepropagationcheck=true
      # - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.myresolver.acme.email=${EMAIL}"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      # add a wildcard for certificate
      #- "--certificateresolvers.myresolver.acme.sans=`*.${DOMAIN}`"
      - "--entrypoints.web-secure.http.tls.certResolver=myresolver"
      - "--entrypoints.web-secure.http.tls.domains[0].main=$DOMAIN"
      - "--entrypoints.web-secure.http.tls.domains[0].sans=*.yourdomain.duckdns.org"

    environment:
      - DUCKDNS_TOKEN=${DUCKDNS_TOKEN}

    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
      # Docker sends requests on port 443 to Traefik on port 443
      - "443:443"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
      - "./letsencrypt:/letsencrypt"

environment file

update these accordingly.

DOMAIN=<yourdomain.duckdns.org>
EMAIL=<your.email@whatever>
CERT_RESOLVER=letsencrypt
TRAEFIK_USER=<user>
TRAEFIK_PASSWORD_HASH=<hash>
DUCKDNS_TOKEN=<duckdns token>

how it is used

assuming there is an env file named: env-traefik the command to run docker compose is: docker compose --env-file env-traefik up -d

todo

  • automate process
  • blog post
  • multiple networks on traefik done 20240403 based on this blog
  • gitops

links

I’ve used several resources to progress. Below is a list for reference