← Start of tutorial

WIUNIX ACADEMY

Set up Traefik with Let’s Encrypt and HTTP/3 on Ubuntu and Debian

Page 2 of 6. Review the earlier steps and prerequisites before continuing.

YOUR SYSTEM. YOUR STEPS.

Where are you working?

Choose your OS and version. The prerequisites, commands and troubleshooting follow your environment.

Ubuntu 26.10Reviewed against official documentation ·

USE YOUR OWN VALUES

Configure this tutorial

Set the example values for your environment; related explanations and copy panels update together. Never enter passwords, private keys or tokens. Values stay in this tab and are not sent to the server or share links. Check actual DNS, certificates and network policy before running commands.

Different IP addresses, domains or ports? Open the settings below, change the values and select “Apply to tutorial”, then copy the updated commands.

Set values for my environment11 editable values
04

LET’S BUILD

Install ordinary prerequisites

Use the selected distribution’s signed repositories. These packages supply HTTPS downloads, checksum/archive tools, diagnostics and the harmless Python marker service. This is not a full OS upgrade. Ubuntu 26.10 is the reviewed stable default; the LTS and Debian choices use the same upstream Traefik binary workflow. OS support and upstream Traefik maintenance are separate responsibilities.

Bash

Dedicated Linux host

sudo apt-get update
sudo apt-get install --no-install-recommends ca-certificates curl tar coreutils python3 dnsutils openssl iproute2
How do I know it worked?

APT completes without signature/repository errors.

05

LET’S BUILD

Verify and install the pinned official release

On 20 October 2026 the current stable release is 3.7.15, including security fixes. This pin is reproducible, not a promise it remains current. Review official advisories and migration notes before later updates. Download as your normal user, verify the matching archive against the vendor checksum file, then install only the executable. Both files arrive over HTTPS from the same release: this detects corruption but is not an independent signature verification. Use your organization’s separate artifact-approval process where required. Never pipe a download into a root shell.

Bash

Dedicated Linux host

bash -eu <<'DOWNLOAD'
version=3.7.15
case "$(dpkg --print-architecture)" in
  amd64) arch=amd64;; arm64) arch=arm64;; *) echo 'Unsupported architecture' >&2; exit 1;;
esac
work=$(mktemp -d)
cd "$work"
archive="traefik_v${version}_linux_${arch}.tar.gz"
base="https://github.com/traefik/traefik/releases/download/v${version}"
curl --fail --location --proto '=https' --tlsv1.2 -o "$archive" "$base/$archive"
curl --fail --location --proto '=https' --tlsv1.2 -o checksums.txt "$base/traefik_v${version}_checksums.txt"
awk -v name="$archive" '$2 == name {print}' checksums.txt > selected.sha256
test "$(wc -l < selected.sha256)" -eq 1
sha256sum --check selected.sha256
tar -xzf "$archive" traefik
test ! -e /usr/local/bin/traefik
sudo install -o root -g root -m 0755 traefik /usr/local/bin/traefik
/usr/local/bin/traefik version
printf 'Retained download directory: %s\n' "$work"
DOWNLOAD
How do I know it worked?

Exactly one checksum passes; installed version reports 3.7.15 and the expected Linux architecture.

06

LET’S BUILD

Create isolated service state

Only on the fresh host, create a dedicated non-login user after verifying that name is unused. Configuration stays root-owned; only the ACME state directory is writable by Traefik. The Python origin uses a separate unprivileged existing www-data account. No service gets Docker-group membership or socket access. Both empty ACME files are created once with 0600; never truncate them on reruns.

Bash

Dedicated Linux host

sudo bash -eu <<'SETUP'
! getent passwd traefik-academy
test ! -e '/etc/traefik-academy'
test ! -e '/var/lib/traefik-academy'
test ! -e '/srv/traefik-academy-origin'
useradd --system --user-group --no-create-home --home-dir /nonexistent --shell /usr/sbin/nologin traefik-academy
getent passwd www-data >/dev/null
install -d -o root -g traefik-academy -m 0750 '/etc/traefik-academy' '/etc/traefik-academy/dynamic'
install -d -o traefik-academy -g traefik-academy -m 0700 '/var/lib/traefik-academy'
install -o traefik-academy -g traefik-academy -m 0600 /dev/null '/var/lib/traefik-academy/acme-staging.json'
install -o traefik-academy -g traefik-academy -m 0600 /dev/null '/var/lib/traefik-academy/acme-production.json'
install -d -m 0755 '/srv/traefik-academy-origin'
install -d -m 0755 "$(dirname '/srv/traefik-academy-origin/health.txt')"
printf '%s\n' 'academy-traefik-origin-ok' > '/srv/traefik-academy-origin/health.txt'
chmod 0644 '/srv/traefik-academy-origin/health.txt'
SETUP
How do I know it worked?

Dedicated account and directories exist; state is 0700, both ACME files 0600; marker is public non-secret data.

07

LET’S BUILD

Open the dedicated origin unit

This Python HTTP server is only an observable learning fixture, not a production application server. Its document root contains only the marker, never a repository, home, key or backup directory. Create only the following new unit.

Bash

Dedicated Linux host

test ! -e /etc/systemd/system/academy-traefik-origin.service &&
sudoedit /etc/systemd/system/academy-traefik-origin.service
How do I know it worked?

Editor open for the new origin unit.

Origin service file

FILE CONTENT: save this unit. Binding to 127.0.0.1 is a fixed security boundary, not a public setting.

ini · /etc/systemd/system/academy-traefik-origin.service
[Unit]
Description=Academy Traefik loopback marker
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
ExecStart=/usr/bin/python3 -m http.server 8081 --bind 127.0.0.1 --directory /srv/traefik-academy-origin
Restart=on-failure
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true

[Install]
WantedBy=multi-user.target
08

LET’S BUILD

Open the staging configuration

Start against Let’s Encrypt staging with its separate account/state. api.insecure remains false. No public dashboard router exists. The default HTTP redirect is temporary to avoid sticky browser redirects during setup; HTTP-01 is compatible with the entrypoint redirect. No certificate, password or private key is pasted into the public settings.

Bash

Dedicated Linux host

sudoedit '/etc/traefik-academy/traefik.yml'
How do I know it worked?

Editor ready for the complete static YAML below.

Static Traefik YAML: staging first

FILE CONTENT: HTTP/3 is enabled on the TLS TCP entrypoint and also opens UDP/443; it is not an experimental flag in this release. Only TLS routers use it. The ACME contact email is optional in this example; if your account policy requires one, add email under acme in this root-controlled editor, not in a browser field. No DNS API credential is needed for HTTP-01. Access logs are not enabled; operational logs can still contain domain/error data and need protected retention.

yaml · /etc/traefik-academy/traefik.yml
global:
  checkNewVersion: false
  sendAnonymousUsage: false
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: false
  websecure:
    address: ":443"
    http3: {}
  admin:
    address: "127.0.0.1:8080"
api:
  dashboard: true
  insecure: false
  debug: false
providers:
  file:
    directory: "/etc/traefik-academy/dynamic"
    watch: true
certificatesResolvers:
  le:
    acme:
      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      storage: "/var/lib/traefik-academy/acme-staging.json"
      httpChallenge:
        entryPoint: web
log:
  level: INFO
Explore all tutorials ↗