Docker labels

When run against the Docker provider, Sōzune discovers your services through container labels. Each label has the form:

sozune.<protocol>.<service>.<key>=<value>

Where <service> is your own identifier — it groups labels for the same logical service. Containers sharing the same <service> name are merged as backends of one cluster.

Activation

LabelDescription
sozune.enable=trueEnables discovery for the container. Required unless expose_by_default is set on the Docker provider
sozune.network=<name>Docker network used for routing (when the container is on multiple networks)

Readiness — Docker HEALTHCHECK

When a container declares a Docker HEALTHCHECK (via HEALTHCHECK in the Dockerfile or healthcheck: in compose), Sōzune treats it as the container's readiness probe and gates routing on its status:

State.Health.StatusRouted?
(no HEALTHCHECK declared)Yes — as soon as the container is running
startingNo
healthyYes
unhealthyNo (backend removed; re-added when status returns to healthy)

There is no label or flag to opt out: declaring a HEALTHCHECK is itself the opt-in to the readiness contract. If you want traffic during warmup, drop the HEALTHCHECK or use --health-start-period to delay the first probe.

Routing — HTTP

LabelExampleReference
sozune.http.<svc>.hostapp.example.comHostnames
sozune.http.<svc>.port8080Backend port (defaults: 80 for http, 443 for https, 8080 for tcp/udp)
sozune.http.<svc>.path/apiPath matching
sozune.http.<svc>.prefix/apiAlias for path
sozune.http.<svc>.pathRegex/users/[0-9]+Path matching
sozune.http.<svc>.priority100Higher wins when multiple rules match (default 0)
sozune.http.<svc>.methodsGET,POSTRestrict the route to these HTTP methods (comma-separated; default: any)
sozune.http.<svc>.tlstrueEnables TLS termination (provisions an ACME cert)

Middleware

LabelReference
sozune.http.<svc>.auth.basicBasic auth
sozune.http.<svc>.forwardAuth.addressForward auth — required to enable
sozune.http.<svc>.forwardAuth.responseHeadersForward auth — comma-separated headers to copy from auth response onto the request
sozune.http.<svc>.forwardAuth.trustForwardHeaderForward auth — keep client X-Forwarded-* headers when calling the auth service
sozune.http.<svc>.headers.<name>Custom headers — request-side by default
sozune.http.<svc>.headers.response.<name>Custom headers — response-side
sozune.http.<svc>.headers.both.<name>Custom headers — both directions
sozune.http.<svc>.stripPrefixStrip prefix
sozune.http.<svc>.addPrefixAdd prefix
sozune.http.<svc>.httpsRedirectRedirects
sozune.http.<svc>.httpsRedirectPortRedirects
sozune.http.<svc>.redirectRedirects
sozune.http.<svc>.redirectSchemeRedirects
sozune.http.<svc>.redirectTemplateRedirects
sozune.http.<svc>.wwwAuthenticateBasic auth
sozune.http.<svc>.ratelimit.averageRate limit
sozune.http.<svc>.ratelimit.burstRate limit
sozune.http.<svc>.compressResponse compression (zstd, br, gzip)
sozune.http.<svc>.backendTimeoutBackend timeout
sozune.http.<svc>.stickySessionSticky sessions

Routing — TCP

TCP routing requires a listener declared under proxy.tcp in the main config. Labels then attach a backend to that listener by name. See TCP routing for the full picture.

LabelExampleDescription
sozune.tcp.<svc>.entrypointpostgresListener name declared under proxy.tcp. Required.
sozune.tcp.<svc>.port5432Backend port on the container.
sozune.tcp.<svc>.priority100Higher wins when multiple services share the same listener (default 0).

Routing — UDP

Note: UDP entrypoints are recognised at the label-parsing level but are not currently proxied — the Sōzu UDP worker integration is not yet wired in.

Full example

services:
  api:
    image: my-api
    labels:
      - "sozune.enable=true"
      - "sozune.http.api.host=api.example.com"
      - "sozune.http.api.port=8080"
      - "sozune.http.api.tls=true"
      - "sozune.http.api.httpsRedirect=true"
      - "sozune.http.api.path=/v1"
      - "sozune.http.api.stripPrefix=true"
      - "sozune.http.api.ratelimit.average=100"
      - "sozune.http.api.ratelimit.burst=50"
      - "sozune.http.api.headers.X-Powered-By=sozune"

  db:
    image: postgres:16
    labels:
      - "sozune.enable=true"
      - "sozune.tcp.db.entrypoint=postgres"
      - "sozune.tcp.db.port=5432"