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.
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
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.
Dedicated Linux host
sudo apt-get update
sudo apt-get install --no-install-recommends ca-certificates curl tar coreutils python3 dnsutils openssl iproute2
APT completes without signature/repository errors.
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.
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
Exactly one checksum passes; installed version reports 3.7.15 and the expected Linux architecture.
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.
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
Dedicated account and directories exist; state is 0700, both ACME files 0600; marker is public non-secret data.
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.
Dedicated Linux host
test ! -e /etc/systemd/system/academy-traefik-origin.service &&
sudoedit /etc/systemd/system/academy-traefik-origin.service
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.
[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
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.
Dedicated Linux host
sudoedit '/etc/traefik-academy/traefik.yml'
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.
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