Running Traefik in an LXC Container (Part 2): Docker Integration & Service Discovery

Introduction

Modern web infrastructure demands seamless automation, flexible security, and robust observability across every layer. Traefik, with its dynamic routing and native cloud provider integrations, is a top-tier reverse proxy for cutting-edge self-hosted setups. In this continuation, we explore comprehensive configurations to run Traefik as a production-grade proxy with full automation for SSL, dynamic configuration reloading, and managed service control via systemd inside an LXC container.

Essential Building Blocks

To run a highly available, secure Traefik reverse proxy, you’ll need:

  • A registered domain name (be mindful of renewal, not just purchase price)
  • External DNS provider: Cloudflare is demonstrated, but Traefik supports many. DNS-based ACME challenges offer automated SSL for any subdomain.
  • A public (routable/white) IP address
  • Split DNS: Optional but highly recommended to ensure local domain queries stay on-premises.

Tip: Investigate domain renewal costs, not just the initial price—renewals can be significantly higher!

DNS Setup with Cloudflare

  • Move your domain to Cloudflare or another supported DNS provider.
  • In Cloudflare, generate a custom API token with only the minimum required permissions.
  • Store the token securely; you can’t view it again once generated.

Cloudflare might occasionally be blocked in certain regions—consult the official Traefik documentation for alternatives.

Exporting the Cloudflare Token

Before starting Traefik, declare the token so Traefik’s ACME provider can manage DNS entries for certificate challenges:

export CLOUDFLARE_DNS_API_TOKEN="your-cloudflare-token"

Static Configuration: /etc/traefik/traefik.yaml

A robust static config example:

global:
checkNewVersion: true
sendAnonymousUsage: true

api:
dashboard: true
insecure: false
debug: true
disableDashboardAd: true

entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
metrics:
address: ":8082"

metrics:
prometheus:
entryPoint: metrics

serversTransport:
insecureSkipVerify: true

providers:
file:
directory: /etc/traefik/dynamic
watch: true

certificatesResolvers:
cloudflare:
acme:
caServer: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
storage: /etc/traefik/acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"

log:
level: "INFO"
filePath: "/var/log/traefik/traefik.log"
maxSize: 100
compress: true

accessLog:
addInternals: true
filePath: "/var/log/traefik/access.log"
bufferingSize: 100

The config decouples static and dynamic settings, ensures all HTTP gets redirected to HTTPS, and enables Prometheus metrics and access logging for deep observability.

Dynamic Configuration: /etc/traefik/dynamic/config.yaml

A typical dynamic configuration might enable a protected dashboard and a service like Radarr:

http:
routers:
dashboard:
entryPoints: [websecure]
rule: "Host(`traefik-dashboard.domain.example`)"
service: api@internal
middlewares: [auth]
tls:
certResolver: cloudflare

radarr:
entryPoints: [websecure]
rule: "Host(`radarr.domain.example`)"
middlewares: [default-headers, https-redirect]
tls:
certResolver: cloudflare
service: radarr

services:
radarr:
loadBalancer:
servers:
- url: "http://192.168.1.100:7878"
passHostHeader: true

middlewares:
auth:
basicAuth:
users:
- "admin:$apr1$hashedpassword"
https-redirect:
redirectScheme:
scheme: https
permanent: true
default-headers:
headers:
frameDeny: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN
customRequestHeaders:
X-Forwarded-Proto: https

tls:
options:
default:
minVersion: VersionTLS12
curvePreferences: [X25519, CurveP256, CurveP384, CurveP521]
sniStrict: true
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

stores:
default:
defaultGeneratedCert:
resolver: cloudflare
domain:
main: domain.example
sans:
- "*.domain.example"

Passwords for basicAuth must be hashed, e.g. via:

openssl passwd -1 "your-password"

Launching Traefik as a Systemd Service

To ensure Traefik starts on boot and runs as a managed background service, create /etc/systemd/system/traefik-proxy.service:

[Unit]
Description=Start Traefik Proxy
Documentation=https://doc.traefik.io/traefik/

[Service]
Environment="CLOUDFLARE_DNS_API_TOKEN=your-cloudflare-token"
ExecStart=/usr/local/bin/traefik
Restart=always

[Install]
WantedBy=multi-user.target
  • Use systemctl start traefik-proxy to start, systemctl status traefik-proxy to check status, and systemctl disable traefik-proxy to prevent autostart.
  • Monitor SSL issuance and proxy logs in /var/log/traefik/.

Key Best Practices and Pitfalls

  • Secure your API tokens and config files—exposure can allow attackers to hijack all your domains!
  • Log and monitor frequently for certificate renewals and failed ACME challenges.
  • Regularly backup your dynamic config and ACME storage—a lost acme.json file means certificate resets.

Conclusion

With this advanced setup, Traefik acts as a true cloud-native gateway, bridging dynamic service discovery, encrypted communication, and full automation inside a lightweight LXC container. Paired with Proxmox, this approach combines resource efficiency, operational security, and enterprise-grade observability. Iterate, expand, and enhance—your infrastructure now has a reverse proxy backbone that’s ready for anything!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *