Skip to content

service ​

service is Turna's reverse proxy middleware. It can proxy to one or more upstream servers with weighted round-robin, random or least-connections balancing, health checks, session affinity and traffic mirroring, or select upstreams by request path prefix.

yaml
server:
  http:
    middlewares:
      backend:
        service:
          insecure_skip_verify: false
          pass_host_header: true
          proxy: http://proxy.internal:3128
          loadbalancer:
            servers:
              - url: http://localhost:3000
              - url: http://localhost:3001

Fields ​

FieldDefaultDescription
insecure_skip_verifyfalseSkip upstream TLS certificate verification. Also applies to active health checks and mirror requests.
pass_host_headerWhen explicitly false, clear r.Host before proxying.
proxyOptional HTTP or HTTPS forward proxy URL used for upstream requests. Credentials may be included in the URL.
loadbalancer.serversUpstream list; each entry has url and optional weight (default 1).
loadbalancer.strategyround_robinround_robin (smooth weighted), random (weighted) or least_conn (active requests / weight).
loadbalancer.sticky.cookieSession affinity cookie, see below.
loadbalancer.health_checkActive health check, see below.
loadbalancer.passive_health_checkPassive health check, see below.
retry0Retries on other upstreams when an upstream is unreachable.
mirrorShadow traffic, see below.
prefixbalancer.prefixesPath-prefix-specific upstream lists.
prefixbalancer.default_serversDefault upstreams when no prefix matches.

WebSockets and streaming ​

service proxies WebSocket (Connection: Upgrade) and streaming responses (SSE) transparently. WebSocket upgrades are forwarded over the same transport as regular requests, so wss:///https:// upstreams work, honoring insecure_skip_verify. Path rewrites and the pass_host_header setting apply to upgrades too.

WebSocket upgrades use HTTP/1.1 to the upstream; backends that only speak HTTP/2 cannot accept them.

Prefix Balancer ​

yaml
service:
  prefixbalancer:
    prefixes:
      - prefix: /api
        servers:
          - url: http://api:3000
      - prefix: /admin
        servers:
          - url: http://admin:3000
    default_servers:
      - url: http://web:3000

If the prefix balancer is configured, it is used instead of the plain loadbalancer.

The loadbalancer options (strategy, sticky, health_check, passive_health_check) also apply to every prefix group and the default servers. The same upstream URL used in several groups shares its health and connection state.

Load Balancing ​

yaml
service:
  retry: 1
  loadbalancer:
    strategy: least_conn
    servers:
      - url: http://app-1:3000
        weight: 3
      - url: http://app-2:3000

Unhealthy or ejected upstreams are skipped. When every upstream is unavailable, turna still tries them (fail open) instead of rejecting the request.

Sticky Sessions ​

yaml
loadbalancer:
  sticky:
    cookie:
      name: turna_lb
      max_age: 1h
      secure: true
FieldDefaultDescription
nameturna_lbCookie name. Prefix groups get a _<index> suffix.
path/Cookie path.
domainCookie domain.
max_agesessionCookie lifetime.
securefalseSecure flag.
http_onlytrueHttpOnly flag.
same_sitelaxlax, strict or none.

The cookie holds a hash of the upstream URL. If that upstream is unhealthy, another one is picked and the cookie is updated.

Active Health Check ​

yaml
loadbalancer:
  health_check:
    path: /healthz
    interval: 10s
    timeout: 2s
    status: "200-299"
    unhealthy_threshold: 2
FieldDefaultDescription
path/Probe path, may include a query string.
methodGETProbe method.
hostHost header of the probe.
headersExtra probe headers.
interval10sTime between probes.
timeout5sProbe timeout.
status200-399Accepted status codes, e.g. 200,204,300-399.
healthy_threshold1Consecutive successes to mark healthy.
unhealthy_threshold1Consecutive failures to mark unhealthy.

Passive Health Check ​

yaml
loadbalancer:
  passive_health_check:
    max_fails: 3
    fail_timeout: 30s
    fail_statuses: [502, 503, 504]

An upstream is ejected for fail_timeout after max_fails failures within fail_timeout. Connection errors always count as failures; fail_statuses adds response codes.

Mirror ​

Mirror sends a copy of requests to shadow upstreams. Mirror responses are discarded and never change the client response.

yaml
service:
  loadbalancer:
    servers:
      - url: http://app-v1:3000
  mirror:
    servers:
      - url: http://app-v2:3000
        percent: 10
FieldDefaultDescription
servers[].urlShadow upstream.
servers[].percent100Percent of requests to mirror.
max_body_size1048576Requests with larger bodies are not mirrored.
timeout10sMirror request timeout.
max_in_flight100Concurrent mirror requests; extra ones are dropped.

WebSocket upgrades are not mirrored.