Proxying Docker containers through Traefik, using systemd

Wednesday, 3 November 2021

This post is outdated and I recommend looking at my newer post to a better resource.

I’ve been using Docker more for things lately, along with Traefik for acting as the reverse proxy. There are lots of guides to getting things going with docker-compose, but I was curious what it would take to keep each Docker container managed by systemd while still utilizing the Docker integrations that Traefik offers.

Running Docker containers with systemd

I decided the simplest way to do this would be with a systemd service definition for each docker container, the 2 that I will use to demonstrate here are Traefik itself, and a Plex media server.

My configuration for Traefik, which I think is pretty standard. I’m not worrying about anything TLS right now though. I have port 8000 for the Traefik dashboard to see the state of things and port 80 is used for the actually proxy.

[Unit]
Description=Traefik for Docker containers
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
Restart=always
ExecStart=/usr/bin/docker run \
        --rm \
        --name traefik \
        --publish 80:80 \
        --publish 8000:8080 \
        --volume traefik-letsencrypt:/letsencrypt \
        --volume /var/run/docker.sock:/var/run/docker.sock:ro \
        traefik:v2.5 \
        traefik \
        "--providers.docker=true" \
        "--providers.docker.exposedbydefault=false" \
        "--entrypoints.web.address=:80" \
        "--api.dashboard=true" \
        "--api.insecure=true"

[Install]
WantedBy=multi-user.target

My configuration for a Plex media server. Most of this is pretty Plex-specific, but the labels at the end is what lets Traefik discover the service, with a port 32400 designated to be the proxy target with the .loadbalancer.server.port=32400 section.

[Unit]
Description=Plex Media Server
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
Restart=always
ExecStart=/usr/bin/docker run \
        --rm \
        --name plex \
        -e TZ="America/Vancouver" \
        -e PLEX_CLAIM="claim-XXXXXXXXXX" \
        -e ADVERTISE_IP="plex.home.arpa" \
        --publish 32400:32400/tcp \
        --publish 1900:1900/udp \
        --publish 3005:3005/tcp \
        --publish 5353:5353/udp \
        --publish 8324:8324/tcp \
        --publish 32410:32410/udp \
        --publish 32412:32412/udp \
        --publish 32413:32413/udp \
        --publish 32414:32414/udp \
        --publish 32469:32469/tcp \
        --hostname plex.home.arpa \
        ---volume /storage/plex/config:/config \
        ---volume /storage/plex/transcode:/transcode \
        ---volume /storage/plex/data:/data \
        --label "traefik.enable=true" \
        --label "traefik.http.routers.plex-http.rule=Host(`plex.home.arpa`)" \
        --label "traefik.http.routers.plex-http.entrypoints=web" \
        --label "traefik.http.routers.plex-http.service=plex-http-service" \
        --label "traefik.http.services.plex-http-service.loadbalancer.server.port=32400" \
        plexinc/pms-docker

[Install]
WantedBy=multi-user.target

Closing remarks

Only time will tell if I want to stick with this setup, but it seems to be working well enough for my simple home use case. The systemd configuration kind of sucks with so many arguments being passed on the command line to docker so maybe that will annoy me enough to seek out a different solution.

Maybe it would have been easier to just run this through Docker Swarm or some other orchestrator but that seems overkill for a single-server solution to running some containers.

Written Wednesday, 3 November 2021

Tagged with linux.

Categorized as “

What do you think of this post?