Skip to content

Traefik

Traefik is used as my reverse proxy.

🛠 Installation

Default Port: 80

bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/traefik.sh)"
bash -c "$(wget -qLO - https://github.com/asylumexp/Proxmox/raw/main/ct/{{ app_name | lower }}.sh)"
bash -c "$(wget -qLO - https://github.com/asylumexp/Proxmox/raw/main/ct/traefik.sh)"

⚙ Config

All internal URLs use an l sub domain so that only one certificate is needed from letsencrypt. E.g. https://app.l.nicholaswilde.io/

Note

Paths in config file should be absolute.

App

Tip

Use the staging value of caServer during testing.

homelab/pve/traefik/traefik.yaml
---
providers:
  file:
    filename: /root/git/nicholaswilde/homelab/pve/traefik/middlewares.yaml
    directory: /root/git/nicholaswilde/homelab/pve/traefik/conf.d/
    watch: true

entryPoints:
  web:
    address: ':80'
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ':443'
    http:
      tls:
        certResolver: cloudflare
  traefik:
    address: ':8080'
  # mailsecure:
    # address: ':465'

certificatesResolvers:
  cloudflare:
    acme:
      email: [email protected]
      storage: /root/git/nicholaswilde/homelab/pve/traefik/ssl/acme.json
      caServer: https://acme-v02.api.letsencrypt.org/directory # prod (default)
      # caServer: https://acme-staging-v02.api.letsencrypt.org/directory # staging
      dnsChallenge:
        provider: cloudflare
        #disablePropagationCheck: true # uncomment this if you have issues pulling certificates through cloudflare, By setting this flag to true disables the need to wait for the propagation of the TXT record to all authoritative name servers.
        delayBeforeCheck: 60s # uncomment along with disablePropagationCheck if needed to ensure the TXT record is ready before verification is attempted 
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"
  # letsencrypt:
    # acme:
      # email: "[email protected]"
      # storage: /etc/traefik/ssl/acme.json
      # tlsChallenge: {}

serversTransport:
  insecureSkipVerify: true

api:
  dashboard: true
  insecure: true
  debug: true

log:
  filePath: /var/log/traefik/traefik.log
  format: common
  level: INFO

accessLog:
  filePath: /var/log/traefik/traefik-access.log
  format: json
  filters:
    statusCodes:
      - "200"
      - "400-599"
    retryAttempts: true
    minDuration: "10ms"
  bufferingSize: 0
  fields:
    headers:
      defaultMode: drop
      names:
        User-Agent: keep
homelab/pve/traefik/conf.d/config.yaml
---
http:
  routers:
    traefik:
      entrypoints:
        - web
      rule: Host(`traefik.l.nicholaswilde.io`)
      middlewares: traefik-https-redirect
      service: api@internal
    traefik-secure:
      entrypoints:
        - websecure
      rule: Host(`traefik.l.nicholaswilde.io`)
      # middlewares: traefik-auth
      tls:
        certresolver: cloudflare
        domains:
          - main: l.nicholaswilde.io
            sans: 
              - '*.l.nicholaswilde.io'
      service: api@internal

  middlewares:
    # traefik-auth:
      # basicAuth:
        # users: ${TRAEFIK_DASHBOARD_CREDENTIALS}
    traefik-https-redirect:
      redirectScheme:
        scheme: https
    sslheader:
      headers:
        customRequestHeaders:
          X-Forwarded-Proto: https

🤝 Service

Update EnvironmentFile and ExecStart to point to your homelab directories.

/etc/systemd/system/traefik.service

cat > /etc/systemd/system/traefik.service <<EOF
[Unit]
Description=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience

[Service]
Type=notify
EnvironmentFile=/root/git/nicholaswilde/homelab/pve/traefik/.env
ExecStart=/usr/local/bin/traefik --configFile=/root/git/nicholaswilde/homelab/pve/traefik/traefik.yaml
Restart=on-failure
ExecReload=/bin/kill -USR1 $MAINPID

[Install]
WantedBy=multi-user.target

EOF
wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/traefik/traefik.service -O /etc/systemd/system/traefik.service
[Unit]
Description=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience

[Service]
Type=notify
EnvironmentFile=/root/git/nicholaswilde/homelab/pve/traefik/.env
ExecStart=/usr/local/bin/traefik --configFile=/root/git/nicholaswilde/homelab/pve/traefik/traefik.yaml
Restart=on-failure
ExecReload=/bin/kill -USR1 $MAINPID

[Install]
WantedBy=multi-user.target

Enable service

(
 systemctl enable traefik.service && \
 systemctl start traefik.service && \
 systemctl status traefik.service
) 

📝 Usage

  1. Create new config for app

    homelab/pve/traefik/conf.d/

    APP_NAME=AppName task new > appname.yaml
    
    jinja2 -D APP_NAME=AppName .template.yaml.j2 > appname.yaml
    
  2. Edit config file.

    Update http.routers.<app_name>.rule and services.<app_name>.loadBalancer.servers.url[0]

    homelab/pve/traefik/conf.d/mcp-server.yaml
    ---
    http:
     #region routers 
      routers:
        mcp-server:
          entryPoints:
            - "websecure"
          rule: "Host(`mcp-server.l.nicholaswilde.io`)"
          middlewares:
            - default-headers@file
            - https-redirectscheme@file
          tls: {}
          service: mcp-server
    #endregion
    #region services
      services:
        mcp-server:
          loadBalancer:
            servers:
              - url: "http://192.168.2.177:8080"
            passHostHeader: true
    #endregion
      middlewares:
        https-redirectscheme:
          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
    
        default-whitelist:
          ipAllowList:
            sourceRange:
            - "10.0.0.0/8"
            - "192.168.0.0/16"
            - "172.16.0.0/12"
    
        secured:
          chain:
            middlewares:
            - default-whitelist
            - default-headers
    
  3. Restart traefik

    homelab/pve/traefik/conf.d/

    task restart
    
    systemctl restart traefik.service
    
    1. Test URL in browser.
  4. Comment out middleware in config file.

    homelab/pve/traefik/conf.d/mcp-server.yaml
    ---
    http:
     #region routers 
      routers:
        mcp-server:
          entryPoints:
            - "websecure"
          rule: "Host(`mcp-server.l.nicholaswilde.io`)"
          middlewares:
            - default-headers@file
            - https-redirectscheme@file
          tls: {}
          service: mcp-server
    #endregion
    #region services
      services:
        mcp-server:
          loadBalancer:
            servers:
              - url: "http://192.168.2.177:8080"
            passHostHeader: true
    #endregion
      # middlewares:
        # https-redirectscheme:
          # 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
    #
        # default-whitelist:
          # ipAllowList:
            # sourceRange:
            # - "10.0.0.0/8"
            # - "192.168.0.0/16"
            # - "172.16.0.0/12"
    #
        # secured:
          # chain:
            # middlewares:
            # - default-whitelist
            # - default-headers
    
  5. Restart traefik

  6. Test URL

  7. Remove middleware or uncomment middleware

    homelab/pve/traefik/conf.d/mcp-server.yaml
    ---
    http:
     #region routers 
      routers:
        mcp-server:
          entryPoints:
            - "websecure"
          rule: "Host(`mcp-server.l.nicholaswilde.io`)"
          middlewares:
            - default-headers@file
            - https-redirectscheme@file
          tls: {}
          service: mcp-server
    #endregion
    #region services
      services:
        mcp-server:
          loadBalancer:
            servers:
              - url: "http://192.168.2.177:8080"
            passHostHeader: true
    #endregion
    
  8. Restart traefik

📁 Logs

/var/log/traefik/traefik.log

task logs
tail -n10 /var/log/traefik/traefik.log

Follow

/var/log/traefik/traefik.log

task watch
tail -f /var/log/traefik/traefik.log

Task List

task: Available tasks for this project:
* decrypt:       Decrypt sensitive configuration files using SOPS.
* encrypt:       Encrypt sensitive configuration files using SOPS.
* export:        Export the task list
* new:           Create a new config file
* restart:       Restart Traefik
* status:        View the Traefik service status
* stop:          Stop the Traefik service
* update:        Update running containers
* watch:         Watch the log file

🔗 References