Migrating from Apache to Traefik: A Minimal Reverse Proxy Configuration Guide for LXD Containers


4 views

When moving from Apache to Traefik as a reverse proxy for LXD containers, we need to ensure functional equivalence while leveraging Traefik's simpler configuration model. The Apache configuration shown uses classic proxy directives:

<VirtualHost *:80>
    ServerName example.com
    ProxyRequests off
    ProxyPass / http://10.0.0.142/ retry=0
    ProxyPassReverse / http://10.0.0.142/
    ProxyPreserveHost On
</VirtualHost>

The provided Traefik configuration does achieve similar functionality, though we can optimize it further:

defaultEntryPoints = ["http"]
[entryPoints]
  [entryPoints.http]
  address = ":80"

[backends]
  [backends.backend1]
    [backends.backend1.servers.server1]
       url = "http://10.0.0.142"

[frontends]
  [frontends.frontend1]
      backend = "backend1"
      passHostHeader = true
      [frontends.frontend1.routes.example]
          rule = "Host:example.com"

For a minimal Traefik setup without Docker, we can simplify further using these key optimizations:

[http.routers]
  [http.routers.my-router]
    rule = "Host(example.com)"
    service = "my-service"

[http.services]
  [http.services.my-service.loadBalancer]
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://10.0.0.142"
  • Host Header Preservation: The passHostHeader in Traefik mirrors Apache's ProxyPreserveHost
  • Path Handling: Traefik automatically handles path routing to the backend
  • Health Checks: Traefik includes built-in health checking unlike Apache's basic retry=0

For production environments, consider adding these enhancements:

[http.middlewares]
  [http.middlewares.https-redirect.redirectScheme]
    scheme = "https"
    permanent = true

[http.routers]
  [http.routers.http-catchall]
    entryPoints = ["http"]
    middlewares = ["https-redirect"]
    rule = "HostRegexp({any:.+})"
    priority = 1
    service = "noop@internal"

When moving from Apache's reverse proxy setup to Traefik, we need to ensure equivalent functionality while leveraging Traefik's modern architecture. The original Apache configuration:

<VirtualHost *:80>
    ServerName example.com
    ProxyRequests off
    ProxyPass / http://10.0.0.142/ retry=0
    ProxyPassReverse / http://10.0.0.142/
    ProxyPreserveHost On
</VirtualHost>

The equivalent Traefik configuration using the file provider (static configuration) would be:

# traefik.toml
[entryPoints]
  [entryPoints.web]
    address = ":80"

[http]
  [http.routers]
    [http.routers.my-router]
      rule = "Host(example.com)"
      service = "my-service"

  [http.services]
    [http.services.my-service.loadBalancer]
      [[http.services.my-service.loadBalancer.servers]]
        url = "http://10.0.0.142"

Breaking down the Traefik configuration:

  • entryPoints: Defines network entry points (ports 80/443)
  • http.routers: Routes requests based on rules (Host header in this case)
  • http.services: Defines how to load balance to backend servers

For Traefik v2.x (current version), we can further simplify:

# traefik.yml (YAML format)
http:
  routers:
    example-com:
      rule: "Host(example.com)"
      service: backend-service

  services:
    backend-service:
      loadBalancer:
        servers:
          - url: "http://10.0.0.142"

To match all Apache proxy features, consider these additions:

# For retry functionality
services:
  backend-service:
    loadBalancer:
      servers:
        - url: "http://10.0.0.142"
      healthCheck:
        path: /
        interval: "10s"
        timeout: "2s"

# For host header preservation (default in Traefik)
# No additional config needed as passHostHeader is true by default

Unlike Apache requiring reload/restart, Traefik supports hot-reload:

# Watch for configuration changes
[providers]
  [providers.file]
    watch = true
    filename = "traefik.toml"