Richard Bucker

traefik in a box

Posted at — Oct 17, 2018

Before you begin there are a few decisions to be made. The most important is whether or not you want to support wildcard domains or strictly limited to well known host/domains. If you choose to use wildcards then you are limited to dnsChallenge and there are a limited number of providers not to mention that you need credentials. (see providers)choose hardware and operating systemoptionally install docker-machineinit a docker swarmcreate a swarm networkcreate the 3 config filesLaunchBasic Authenticationmy app configurationLaunch my appAll in oneFIRST you need to deploy machine that can be physical or virtual, however, in order for it to deploy SSL via letsencrypt you must have a public IP and registered DNS and nameserver. Depending on the DNS strategy you may need to create the A-record. The host OS you select should or must support Docker. I prefer CoreOS or RancherOS.Not all OS’ pre-install docker-machine and many container OS’ use read-only partitions in order to maintain immutability. This is how I install docker-machine on CoreOSsudo mkdir -p /opt/local/binbase=https://github.com/docker/machine/releases/download/v0.14.0 && curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine && sudo install /tmp/docker-machine /opt/local/bin/docker-machineInitiate docker swarm… this can be one or more machines. You need to know more about this…docker swarm initDocker containers can talk to each other via private virtual networks. Swarm has a variation where the network can span physical machines with additional features like encryption. The basic declaration looks like:docker network -d overlay webtraefikCreate the three config files:sudo mkdir -p /opt/traefiksudo touch /opt/traefik/docker-compose.ymlsudo touch /opt/traefik/acme.json && chmod 600 /opt/traefik/acme.jsonsudo touch /opt/traefik/traefik.tomlThe acme.json file is left blank as traefik will fill it in as it registers with letsencrypt.This is the traefik.toml file. There are a number of functions here like redirecting all http to https and the acme(letsencrypt) config. Notice the dnsChallenge section and the acme domains. Sine we are configuring wildcard domains dnsChallenge is required. The other challenge methods do not apply.traefik.toml:debug = truelogLevel = “ERROR"defaultEntryPoints = [“https”,“http”][entryPoints] [entryPoints.http] address = “:80" [entryPoints.http.redirect] entryPoint = “https" [entryPoints.https] address = “:443" [entryPoints.https.tls][retry][docker]endpoint = “unix:///var/run/docker.sock"domain = “ooc.systems"watch = trueexposedByDefault = false[acme]email = “richard@bucker.net"storage = “acme.json"entryPoint = “https"onHostRule = true [acme.dnsChallenge] provider = “digitalocean” # DNS Provider name (cloudflare, OVH, gandi…) delayBeforeCheck = 0entryPoint = “http"[[acme.domains]] main = “*.ooc.systems"docker-compose.ymlversion: ‘3.1'services: traefik: image: traefik:latest restart: always command: –api –docker –docker.swarmMode –configFile=/traefik.toml environment: - DO_AUTH_TOKEN=api token goes here… env and docker secrets have not been resolved ports: - 80:80 - 443:443 networks: - webtraefik volumes: - /var/run/docker.sock:/var/run/docker.sock - /opt/traefik/traefik.toml:/traefik.toml - /opt/traefik/acme.json:/acme.json deploy: placement: constraints: - node.role == manager labels: traefik.docker.network: “webtraefik" traefik.port: “8080" traefik.basic.frontend.rule: “Host:t3.ooc.systems" traefik.frontend.auth.basic.users: “admin:$$apr1$$PfJ7s9fA$$YsXtXor2kSCgjJa.“networks: webtraefik: external: trueLaunching traefik is simple but needs to be done as a docker swarm. It’s probably best to know more about how the swarm ingress policy works with traefik. Notice in the docker-compose file above there is a constraint to insure that traefik is only launched on worker nodes.Also notice that the traefik container offers a basic console and so the labels section registers the URL and configures the Basic Authentication.Launch:docker stack deploy -c docker-compose.yml traefikYou should be familiar with BASIC AUTH… but creating the config looks like:echo $(htpasswd who password “) | sed -e s/\$/\$\$/gUnfortunately this does not really work because the result never let me in… but I probably don’t know something… Also CoreOS does not have an htpasswd instance. So I found an openssl variation that was also wrong and eventually made this work:openssl passwd -apr1 mypasswd | sed s/\$/\$\$/gNow that I have traefik up and running I need to deploy my simple app. Here is the compose file:version: ‘3.1'services: whoami: image: emilevauge/whoami networks: - webtraefik deploy: labels: traefik.port: “80" traefik.frontend.rule: “Host:ami2.ooc.systems" traefik.docker.network: “webtraefik" traefik.enable: “true" traefik.frontend.entryPoints: “http,https" traefik.frontend.auth.basic.users: “who:$$apr1$$ItuvI6$$fkOoJ1"networks: webtraefik: external: trueLaunch my app. Since there is no role constraint the container can be deployed anywhere in the swarm.docker stack deploy -c docker-compose.yml whoamiDepending on what you have in mind you can deploy the system in an all-in-one configuration so that the traefik and your service(s) are deployed in one deploy command. This has some advantages when your service domain is an all in one universe but it also means that you have a deep interdependence between services.WARNING WARNING WARNINGimplementing wildcard DNS means that anyone with access to the swarm manager can instantly deploy a service under the domain either intentionally or unintentionally exposing the domain to various security and data problems. On the other hand not all sites have problems with their people or their content.