Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Behind a reverse proxy

Serve the console, the explorer, the file API and the Swagger UI under https://host/craft/, the proxy stripping the prefix or passing it through.

ModeThe proxyThe configuration
strip (Traefik StripPrefix, an Ingress rewrite-target, nginx proxy_pass http://up/;)receives /craft/x, forwards /x, writes X-Forwarded-Prefix: /craftthe paths after stripping: often the defaults
pass-throughforwards /craft/x unchangedbase_path, prefix and [api.ui] path under /craft

Stripping the prefix

[admin]
listen = "0.0.0.0:8080"

[admin.ban]
trusted_proxies = ["10.42.0.0/16"]   # the proxy

[api]
enabled = true
openapi = true

[api.ban]
trusted_proxies = ["10.42.0.0/16"]   # the same: one listener

[api.ui]
enabled = true

The browser opens the console at https://host/craft/, the explorer at https://host/craft/files/, the Swagger UI at https://host/craft/api/docs/; the API answers under https://host/craft/api/v1/files/. Open the prefix with its trailing /: nginx and the Traefik redirect below send /craft to /craft/.

nginx:

location /craft/ {
    proxy_pass http://craft-file-gate:8080/;
    proxy_set_header X-Forwarded-Prefix /craft;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_buffering off;       # the console's streams
    client_max_body_size 0;    # uploads
}

Traefik (dynamic configuration; stripPrefix writes X-Forwarded-Prefix and X-Forwarded-For):

http:
  middlewares:
    craft-slash:
      redirectRegex:
        regex: "^(https?://[^/]+/craft)$"
        replacement: "${1}/"
    craft-strip:
      stripPrefix:
        prefixes: ["/craft"]
  routers:
    craft:
      rule: "PathPrefix(`/craft`)"
      middlewares: [craft-slash, craft-strip]
      service: craft
  services:
    craft:
      loadBalancer:
        servers:
          - url: "http://craft-file-gate:8080"

Kubernetes, ingress-nginx, in front of the <release>-api Service of the chart:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: craft-file-gate
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/x-forwarded-prefix: /craft
    nginx.ingress.kubernetes.io/proxy-buffering: "off"
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
  ingressClassName: nginx
  rules:
    - host: files.example.com
      http:
        paths:
          - path: /craft/(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: craft-file-gate-api
                port:
                  name: admin

The proxy must set or clear X-Forwarded-Prefix, never pass the client’s on. trusted_proxies names the proxy’s addresses: under Kubernetes, the pod CIDR of the ingress, see Behind an ingress.

Passing the path through

[admin]
listen = "0.0.0.0:8080"
base_path = "/craft/console"

[api]
enabled = true
prefix = "/craft/api/v1/files"

[api.ui]
enabled = true
path = "/craft/files"
location /craft/ {
    proxy_pass http://craft-file-gate:8080;
    proxy_set_header X-Forwarded-Prefix "";
    proxy_buffering off;
    client_max_body_size 0;
}

The console is at https://host/craft/console/, the explorer at https://host/craft/files/. The proxy clears X-Forwarded-Prefix: it never passes the client’s on (ingress-nginx without the x-forwarded-prefix annotation passes it; HAProxy: http-request del-header X-Forwarded-Prefix). The Swagger UI stays at the server’s /api/docs: route /api/docs and /api/openapi.json on their own, or strip the prefix.

What the server writes

URLBehind a proxy that strips the prefix
pages, files, fonts, API calls, the console’s streams, redirects (/files to files/, /api/docs to docs/)relative to their page: nothing to set
a download ticket’s URL, the servers entry of the OpenAPI documentprefixed with X-Forwarded-Prefix, when the TCP peer is in trusted_proxies
/livez, /readyz, /metricsread on the pod by the kubelet and Prometheus, outside the prefix

The prefix is a path of letters, digits, -, _, ., ~, on one header line, 256 bytes at most. X-Forwarded-Host and X-Forwarded-Proto are not read: no URL the server writes carries a host or a scheme. The server’s routing does not change: only the URLs it writes follow the prefix.