Skip to content
SHC Docs

Traefik

Traefik is a modern reverse proxy and load balancer.

Key features:

  • Automatic service discovery
  • Let’s Encrypt integration
  • HTTP/2 and gRPC support
  • Dashboard and metrics
Terminal window
shc install traefik --stack proxy

Common variables:

  • email - Email for Let’s Encrypt
  • dashboard_host - Dashboard hostname
  • dashboard_user - Dashboard username
  • dashboard_password - Dashboard password

Traefik automatically discovers services with public_hosts:

# In app.yaml
services:
web:
public_hosts:
- myapp.example.com

SHC generates Traefik labels automatically:

  • Router rules
  • TLS configuration
  • Certificate resolver

TLS is only enabled when explicitly requested (for example via CLI flags). When enabled without an explicit mode, Traefik uses ACME HTTP-01 by default. DNS-01 is available when selected and a DNS provider is configured.

SHC manages DNS records for --host deployments using the resolved provider for that deployment scope. Traefik receives provider updates only when DNS providers are added, removed, or modified in SHC config.

Before telling the ACME CA that a DNS-01 challenge is ready, lego checks that the challenge TXT record is actually being served. Left to its defaults that check runs against the node’s own recursive resolver and fires roughly a second after the record is created — usually before the DNS provider’s edge serves it. The resolver answers NXDOMAIN and caches that negative for the zone’s SOA minimum (commonly 1800s), lego then polls the poisoned cache until the order times out, and Traefik re-poisons it on the next retry. The estate does not recover on its own: every DNS-01 issuance stays stuck until the negative cache expires.

Every DNS-01 certificate resolver SHC seeds therefore carries two settings:

VarDefaultEffect
dns01.checkResolvers1.1.1.1:53,8.8.8.8:53Runs the pre-check against these servers instead of the node’s own resolver, so a negative answer never contaminates the resolver everything else on the node shares.
dns01.checkDelay30sDelays the first pre-check query so the record is genuinely being served before anything asks for it. Costs its value once per ACME order, on the DNS-01 path only.

Both are ordinary install vars on the system Traefik stack, so they are overridable without forking the app:

Terminal window
shc config set system.apps.traefik.vars.dns01.checkResolvers "10.0.0.53:53"
shc config set system.apps.traefik.vars.dns01.checkDelay "60s"

The defaults assume a public zone. Change them when that is not your topology:

  • Split-horizon / internal DNS — point checkResolvers at the server that is authoritative for the zone being challenged. A public resolver answers for the public view and will disagree with the internal record.
  • Airgapped1.1.1.1 and 8.8.8.8 are unreachable and every check will time out. Set checkResolvers to the estate’s own authoritative nameserver (the in-estate PowerDNS / BIND / RFC2136 target the DNS-01 provider writes to).
  • Opt out — set either var to "". That key is then not emitted at all and Traefik keeps its stock behaviour.

A change to either var re-renders and restarts Traefik. Already-issued certificates live in the bind-mounted ACME storage and survive the restart.

Apps connect to Traefik via the traefik_access network:

Terminal window
shc install traefik --stack proxy
shc install nextcloud --stack cloud # Auto-connects to Traefik

Access public URL: https://cloud.example.com

Access Traefik dashboard:

  • URL: https://{dashboard_host}
  • Username: {dashboard_user}
  • Password: {dashboard_password}

Common issues:

Problem: SSL certificate not issued Solution: Verify DNS points to server, check email configuration

Problem: Service not accessible Solution: Check the deployment is healthy with shc status myapp, then inspect the rendered Traefik labels via shc inspect myapp

Problem: Dashboard shows 404 Solution: Verify dashboard_host configuration