Traefik

Docker - IPv6

got Docker running with Traefik as ingress Loadbalancer ?

Just enable IPv6 like this.

daemon.json

cat << EOF > /etc/docker/daemon.json
{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}
EOF

Restart Services

systemctl reload docker

Check Netstat

# netstat -tulpen |grep docker
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          15788      977/docker-proxy    
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      0          17495      952/docker-proxy    
tcp6       0      0 :::80                   :::*                    LISTEN      0          15791      984/docker-proxy    
tcp6       0      0 :::443                  :::*                    LISTEN      0          15773      963/docker-proxy 

Any Comments ?

sha256: 49c4ced1a834b70c143c7425e72ea72982f07f8d1a3e0a8fce9f08f14d3f7da6

Docker - Traefik Advanced

Intro

After a Basic Setup with fix Configuration, here an example where we put some Variables in a “.env” File.

Requirements:

Linux Host with Docker see here, Public IP Adress and rechable Port 80 & 443

two FQDN pointing to your IP:

  • traefik.yourdomain.de
  • whoami.yourdomain.de

Env Vars

let’s run the following Commands which generates a “.env” File. It will also create a User “dashboard” and ask you twice for the Password

echo 'domain="your.domain.de"'      > .env
echo 'traefik="traefik.${domain}"'  >> .env
echo 'whoami="whoami.${domain}"'    >> .env
echo 'mail="name@${domain}"'        >> .env
echo -n 'dashboardaccount="' >> .env; echo -n $(htpasswd -nB dashboard) |sed -e s/\\$/\\$\\$/g >> .env; echo '"' >> .env

.env

and here is the Content of my .env File.

Docker - Traefik

Intro

Following a Working Example how to get Traefik and a few Dummy Containers running on Docker. If you wanna have a bit advanced Example and put some Variables in a “.env” File, you may wanna check this Post.

Requirements

Linux Host with Docker see here, Public IP Adress and rechable Port 80 & 443

two FQDN pointing to your IP:

  • traefik.yourdomain.de
  • whoami.yourdomain.de

Docker Traefik Example

cat << EOF > docker-compose.yml
version: "3.3"

services:
  traefik:
    image: "traefik:v2.9"
    container_name: "traefik"
    command:
      # Traefik Log
      - "--log.level=DEBUG"
      - "--log.filePath=/logs/traefik.log"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      # Access Log
      - "--accesslog=true"
      - "--accesslog.filePath=/logs/access.log"
      # Prometheus metrics
      ## Enable prometheus metrics
      - "--metrics.prometheus=true"
      ## Create a manual router instead of the default one.
      - "--metrics.prometheus.manualrouting=true"
      - "--metrics.prometheus.addrouterslabels=true"
    ports:
      - "80:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./logs/:/logs/"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.yourdomain.de`)"
      - "traefik.http.routers.dashboard.entrypoints=web"
      - "traefik.http.routers.dashboard.service=api@internal"
      # Auth: dasboard/XXXXXXXX
      - "traefik.http.routers.dashboard.middlewares=dashboard_auth"
      - "traefik.http.middlewares.dashboard_auth.basicauth.users=dashboard:$$XXXXXXXXXXXXXXXXXXXX"

  whoami:
    image: "traefik/whoami"
    container_name: "simple-service"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.de`)"
      - "traefik.http.routers.whoami.entrypoints=web"
EOF

Up

docker compose up -d

Redirect HTTP to HTTPS

replace MAIL@YOURDOMAIN.DE, traefik.yourdomain.de and whoami.yourdomain.de with the appropriate Values …

Acme-DNS

Web

A simplified DNS server with a RESTful HTTP API to provide a simple way to automate ACME DNS challenges. Sounds promising, right ? Let’s give try ;)

Setup

fireup a new OpenBSD VM

  • let’s do it in London.
  • ip: 100.10.20.30

patch, update, add go

doas su -
syspatch
pkg_add -Vu
pkg_add go

clone repo and build acme-dns

cd /root
git clone https://github.com/joohoi/acme-dns
cd acme-dns
export GOPATH=/tmp/acme-dns
go build
cp acme-dns /usr/local/sbin/

Create Selfsign Cert

the RESTful API need’s a Cert. Let’s use a selfsigned Cert for this demonstration.

Docker - Kuma Monitoring

Intro

got a hint to try a nice monitoring tool. kuma. https://github.com/louislam/uptime-kuma

pre-condition

.env

we need few variables, edit the touch section appropriately

cat << 'EOF' > .env
# touch
HOST="kuma"
DOMAIN="your.domain"
PORT=3001

# don't touch
SERVICE="${HOST}"
EOF

docker-compose.yml

… and the docker compose file …

cat << 'EOF' > docker-compose.yml
version: '3.3'

networks:
  traefik:
    external: true

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    restart: always
    volumes:
      - ./data_kuma:/app/data
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.${SERVICE}.rule=Host(`${HOST}.${DOMAIN}`)"
      - "traefik.http.routers.${SERVICE}.tls=true"
      - "traefik.http.services.${SERVICE.loadBalancer.server.port=3001"
EOF

Run the Service

docker compose up

and wait at least 30 Seconds.

Docker - Traefik - Wildcard Subdomain

Intro

I was wondering if you can have Wildcart Certs for certain Subdomain. Idea is to provide a Service with “myservice.auth.your.domain” which automatically requests Authentication, while the same Service “myservice.whitelist.your.domain” is reachable through some Whitelisted IP only.

As Traefik can Chain Middleware, but not implements some logic (If Whitelist -> ok, else do Basic Auth …), i have to build another solution.

let’s have a look

Prepare Folders

cd /your/traffic/rootfolder
mkdir -p config/dynamic

.env File

we need two variables, so let’s put them in the .env File

Docker - Traefik - HugoBlog

Intro

as i’m playing with traefik & docker, why not duplicate this blog in container ? for fun and profit ? let’s give at try …

pre-condition

docker compose

cat << 'EOF' > docker-compose.yml
version: '3'

services:
  hugo:
    image: jakejarvis/hugo-extended:latest
    ports:
      - 1313:1313
    volumes:
      - ./src:/src
    command: server --buildDrafts --buildFuture --bind 0.0.0.0
    restart: always
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.hugo.rule=Host(`testblog.norma.li`)"
      - "traefik.http.routers.hugo.tls=true"

networks:
  traefik:
    external: true
EOF

prepare hugo

which hugo || apt install hugo
hugo new site src
mkdir src/themes
git clone https://github.com/vimux/mainroad.git src/themes/mainroad

config.toml

cat << 'EOF' > src/config.toml
baseURL = "https://testblog.norma.li/"
languageCode = "en-us"
title = "My Brandnew Docker Traefik Hugo Blog ..."
theme = "mainroad"
EOF

docker up

docker compose up -d

Create Page

cd src
hugo new posts/hello.md
sed -i '/draft: true/d' content/posts/hello.md
echo -e "hello world :)\n" >> content/posts/hello.md

Access Page

https://testblog.norma.li

Docker - Traefik - Wildcard Cert

Intro

TLS is must, but do you wanna generate a own Certificate for each Service you Provide ? Specially, when you have a *.domain.tld Record set ?

Trafik is able to handle that for you. Let’s Encrypt offers the possibility to use DNS Validation for Wildcard Domains. Here is a list of Providers that can automate DNS Verfication.

Helpful URL

Fully Example with Docker Compose, Traefik, Digital Ocean

Prepare Env

cd /where/ever/you/want
mkdir data
touch data/acme.json

Variables

we need a few Variables. Let’s put them in a .env file and docker-compose will use them when called.

Docker - Traefik - Redirect

Simple (simple ???) Redirect for all Requests to another Page. At least, it works …

docker-compose.yml

  whoami5:
    image: containous/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.redirect-regex.redirectregex.permanent=false"
      - "traefik.http.middlewares.redirect-regex.redirectregex.regex=(.)*"
      - "traefik.http.middlewares.redirect-regex.redirectregex.replacement=https://blog.stoege.net"
      - "traefik.http.routers.whoami5.middlewares=redirect-regex"
      - "traefik.http.routers.whoami5.rule=Host(`redirect.your.domain.de`)"
      - "traefik.http.routers.whoami5.tls.certresolver=letsencrypt"
      - "traefik.http.routers.whoami5.tls=true"

Any Comments ?

sha256: f98bc4f9d6b271b301836a764b2e27e64eb9f6c774b5d7ce1887ed421ffbef75

Docker - Traefik - IPWhitelist

Whitelist IP Range

docker-compose.yml

  whoami:
    image: containous/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, x.x.x.x/y"
      - "traefik.http.routers.whoami.middlewares=test-ipwhitelist@docker"
      - "traefik.http.routers.whoami.rule=Host(`whoami.your.domain.de`)"
      - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
      - "traefik.http.routers.whoami.tls=true"

-> only “localhost” and SRC IP x.x.x.x/y can access this URL. Rest will be blocked. -> Disadvantage. Container needs to be restartet if the Source Range gets modified!

we can do this better :)

Move to File

you may want to put your “IP Ranges” to a dedicated File and import it where needed.