64
submitted 1 day ago by [email protected] to c/[email protected]

Cross-posted from: https://programming.dev/post/33674513

Any general suggestions when getting started with headscale?

you are viewing a single comment's thread
view the rest of the comments
[-] [email protected] 6 points 1 day ago

Looks like they introduce the use Traefik with NixOS here:

How does Traefik compare to a reverse proxy like Caddy?

[-] [email protected] 11 points 1 day ago* (last edited 1 day ago)

In terms of setup, Caddy is a lot simpler in syntax, but you will find more tutorials for Traefik and it has better integration with Docker. You can add labels to a container and Traefik uses that as config, whereas in Caddy, you need to set up both the container and the config file. If you want to drop a service, then it is easier in Traefik for this reason. But with decent Nix code, you can basically replicate this in Caddy. Once you set them up, they're pretty much the same. I've seen some people saying Traefik is faster, but realistically, I don't think it's meaningful.

[-] [email protected] 1 points 22 hours ago

Note that its also possible to set up service auto discovery with traefik, the only traefik related config I do on new containers is

Traefik.enabled=true
[-] [email protected] 1 points 3 hours ago

Shit there is? How do I set up auto discovery?

[-] [email protected] 1 points 3 hours ago* (last edited 3 hours ago)

I can share my traefik setup - note I am doing this on my phone at work, so I might miss something

compose.yaml

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.middlewares=authwares@file"
  GNU nano 7.2                      /config/traefik/dynamic/middlewares.yaml
http:
  middlewares:

    limit:
      buffering:
        memRequestBodyBytes: 5000000000
        memResponseBodyBytes: 5000000000
        maxRequestBodyBytes: 5000000000
        maxResponseBodyBytes: 5000000000

    authwares:
      chain:
        middlewares:
          - default-headers
          - authelia
          - limit

    default-headers:
      headers:
        accessControlAllowHeaders: "content-type,authorization"
        accessControlAllowMethods:
          - GET
          - OPTIONS
          - PUT
          - POST
          - DELETE
        frameDeny: true
        accessControlAllowOriginList: "*"
        accessControlMaxAge: 100
        addVaryHeader: true
        browserXssFilter: true
        contentTypeNosniff: true
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 15552000
        customFrameOptionsValue: SAMEORIGIN
        referrerPolicy: "strict-origin-when-cross-origin"
        customRequestHeaders:
          X-Forwarded-Proto: https
        customResponseHeaders:
          X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex"
          server: ""
          X-Forwarded-Proto: "https,wss"
        hostsProxyHeaders:
          - "X-Forwarded-Host"

    authelia:
      forwardAuth:
        address: http://auth/api/verify?rd=https%3A%2F%2Fauth.example.com%2F
        trustForwardHeader: true
        authResponseHeaders:
          - "Remote-User"
          - "Remote-Groups"
          - "Remote-Email"
          - "Remote-Name"
  GNU nano 7.2                            /config/traefik/traefik.yaml
global:
  checkNewVersion: false
  sendAnonymousUsage: false

entryPoints:
  web:
    address: :80
    proxyProtocol:
      insecure: false
      trustedIPs:
        - 172.32.0.0/16
        - 192.168.1.0/24
    forwardedHeaders:
      insecure: false
      trustedIPs:
        - 172.32.0.0/16
        - 192.168.1.0/24
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
  websecure:
    address: :443
    proxyProtocol:
      insecure: false
      trustedIPs:
        - 172.32.0.0/16
        - 192.168.1.0/24
    forwardedHeaders:
      insecure: false
      trustedIPs:
        - 172.32.0.0/16
        - 192.168.1.0/24
    http:
      tls:
        options: modern@file
        certResolver: letsencrypt
        domains:
          - main: "example.com"
            sans:
              - "*.example.com"

  providers:
  docker:
    exposedByDefault: false
    network: compose_proxied
    allowEmptyServices: true
    endpoint: "http://socket:2375/"
    defaultRule: "Host(`{{ index .Labels \"com.docker.compose.service\"}}.example.com`)"
  file:
    directory: /config/dynamic
    watch: true

api:
  insecure: false
  dashboard: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /certificates/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

log:
  level: DEBUG
  filePath: /config/logs/traefik.log
  format: json
accesslog:
  filepath: /config/logs/access.log
  bufferingSize: 100
  format: json
load more comments (1 replies)
load more comments (1 replies)
this post was submitted on 10 Jul 2025
64 points (94.4% liked)

Selfhosted

49359 readers
474 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

Rules:

  1. Be civil: we're here to support and learn from one another. Insults won't be tolerated. Flame wars are frowned upon.

  2. No spam posting.

  3. Posts have to be centered around self-hosting. There are other communities for discussing hardware or home computing. If it's not obvious why your post topic revolves around selfhosting, please include details to make it clear.

  4. Don't duplicate the full text of your blog or github here. Just post the link for folks to click.

  5. Submission headline should match the article title (donโ€™t cherry-pick information from the title to fit your agenda).

  6. No trolling.

Resources:

Any issues on the community? Report it using the report flag.

Questions? DM the mods!

founded 2 years ago
MODERATORS