-
-
Notifications
You must be signed in to change notification settings - Fork 54
Middlewares
Middleware names are case-insensitive and accept both snake_case, PascalCase and camelCase, e.g. redirectHTTP
, redirect_http
and RedirectHttp
are equivalent.
Middleware execution is does not follow label order, you have to set priority
manually, e.g.
services:
app:
...
container_name: app
labels:
proxy.app.middlewares.redirectHTTP.priority: 1
proxy.app.middlewares.cidrWhiteList.priority: 2
proxy.app.middlewares.cidrWhiteList.allow: 127.0.0.1, 10.0.0.0/16
Middlewares can be used in the following ways:
-
entrypoint middlewares
-
docker labels
-
route files
-
middleware compose - declare reusable middlewares with YAML files under
config/middlewares
# syntax <name>: - use: <middleware> <option1>: <value1> <option2>: <value2> ... # config/middlewares/whitelist.yml myWhitelist: - use: CloudflareRealIP - use: CIDRWhitelist allow: - 127.0.0.1 - 223.0.0.0/8 # Add them in your route # docker compose services: app: labels: proxy.#1.middlewares.myWhitelist@file: # route file app: middlewares: myWhitelist@file: # entrypoint entrypoint: middlewares: myWhitelist@file:
# docker compose - full namespace
labels:
proxy.server.middlewares.redirect_http:
proxy.server.middlewares.cidr_whitelist.allow: 127.0.0.1, 10.0.0.0/16
# docker compose - inline yaml
labels:
proxy.server.middlewares: |
redirect_http:
cidr_whitelist:
allow:
- 127.0.0.1
- 10.0.0.0/16
# config.yml
entrypoint:
middlewares:
- use: cidr_whitelist
allow:
- 127.0.0.1
- 10.0.0.0/16
# route file
openai:
host: https://api.openai.com/
middlewares:
cidr_whitelist:
allow:
- 127.0.0.1
- 10.0.0.0/16
modify_request:
set_headers:
Host: api.openai.com
homepage:
show: false
OIDC uses the settings from .env
file, with configurable allowed_groups
and allowed_users
overrides.
Note: Do not use this middleware on entrypoint if your OIDC provider is proxied by GoDoxy itself.
# docker labels
proxy.app1.middlewares.oidc:
# with overrides
proxy.app1.middlewares.oidc.allowed_groups: admin
proxy.app1.middlewares.oidc.allowed_users: user1, user2
# route file
app1:
middlewares:
oidc:
Redirect http requests to https
# docker labels
proxy.app1.middlewares.redirect_http:
# route file
app1:
middlewares:
redirect_http:
nginx equivalent:
server {
listen 80;
server_name domain.tld;
return 301 https://$host$request_uri;
}
Please check Custom Error Pages
# docker labels
proxy.app1.middlewares.custom_error_page:
# route file
app1:
middlewares:
custom_error_page:
nginx equivalent:
location / {
try_files $uri $uri/ /error_pages/404.html =404;
}
This middleware is used for setting $remote_addr
, $remote_host
from real_ip.header
(i.e.) X-Real-IP
. Doing so will also change the IP address in access log.
# docker labels
proxy.app1.middlewares.real_ip.header: X-Real-IP
proxy.app1.middlewares.real_ip.from: |
- 127.0.0.1
- 192.168.0.0/16
- 10.0.0.0/8
proxy.app1.middlewares.real_ip.recursive: true
# route file
app1:
middlewares:
real_ip:
header: X-Real-IP
from:
- 127.0.0.1
- 192.168.0.0/16
- 10.0.0.0/8
recursive: true
nginx equivalent:
location / {
set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Real-IP;
real_ip_recursive on;
}
This is a preset for Cloudflare Tunnels. It will skip all local IPs.
-
header
:CF-Connecting-IP
-
from
: CIDR List of Cloudflare IPs from (updated every hour) -
recursive
: true
# docker labels
proxy.app1.middlewares.cloudflare_real_ip:
# route file
app1:
middlewares:
cloudflare_real_ip:
# docker labels
proxy.app1.middlewares.cidr_whitelist: |
allow:
- 10.0.0.0/8
- 192.168.0.0/16
status_code: 403
message: "IP not allowed"
# route file
app1:
middlewares:
cidr_whitelist:
allow:
- 10.0.0.0/8
- 192.168.0.0/16
status_code: 403 # default
message: "IP not allowed" # default
average
: average number of requests per period
burst
: maximum number of requests allowed in a period
periods
: time period in format number[unit]
# docker labels
proxy.app1.middlewares.ratelimit: |
average: 100
burst: 100
periods: 1s
# route file
app1:
middlewares:
ratelimit:
average: 100
burst: 100
periods: 1s
In docker compose, you need double dollar signs $$
like $$req_method
since single $
is treated as environment variables.
-
$req_method
: request http method -
$req_scheme
: request URL scheme (http/https) -
$req_host
: request host without port -
$req_port
: request port -
$req_addr
: request host with port (if present) -
$req_path
: request URL path -
$req_query
: raw query string -
$req_url
: full request URL -
$req_uri
: request URI (encoded path?query) -
$req_content_type
: request Content-Type header -
$req_content_length
: length of request body (if present) -
$remote_addr
: client's remote address (may changed by middlewares likeRealIP
andCloudflareRealIP
) -
$remote_host
: client's remote ip parse from$remote_addr
-
$remote_port
: client's remote port parse from$remote_addr
(may be empty) -
$resp_content_type
: response Content-Type header -
$resp_content_length
: length response body -
$status_code
: response status code -
$upstream_name
: upstream server name (alias) -
$upstream_scheme
: upstream server scheme -
$upstream_host
: upstream server host -
$upstream_port
: upstream server port -
$upstream_addr
: upstream server address with port (if present) -
$upstream_url
: full upstream server URL -
$header(name)
: get request header by name -
$resp_header(name)
: get response header by name -
$arg(name)
: get URL query parameter by name
# docker labels
proxy.app1.middlewares.request.set_headers: |
X-Custom-Header1: value1, value2
X-Real-IP: $$remote_host
# route file
app1:
middlewares:
request:
set_headers:
X-Custom-Header1: value1, value2
X-Real-IP: $$remote_host
nginx equivalent:
location / {
add_header X-Custom-Header1 value1, value2;
add_header X-Custom-Header2 value3;
}
Example use case (set X-Real-IP
from remote IP):
# docker labels
proxy.app1.middlewares.request.set_headers: |
X-Real-IP: $remote_host
# docker labels
proxy.app1.middlewares.request.add_headers: |
X-Custom-Header1: value1, value2
X-Custom-Header2: value3
# route file
app1:
middlewares:
request:
add_headers:
X-Custom-Header1: value1, value2
X-Custom-Header2: value3
nginx equivalent:
location / {
more_set_headers "X-Custom-Header1: value1, value2";
more_set_headers "X-Custom-Header2: value3";
}
# docker labels
proxy.app1.middlewares.modify_request.hide_headers: |
X-Custom-Header1
X-Custom-Header2
# route file
app1:
middlewares:
modify_request:
hide_headers:
- X-Custom-Header1
- X-Custom-Header2
nginx equivalent:
location / {
more_clear_headers "X-Custom-Header1";
more_clear_headers "X-Custom-Header2";
}
Remove Forwarded
and X-Forwarded-*
headers before request
# docker labels
proxy.app1.middlewares.hide_x_forwarded:
# route file
app1:
middlewares:
hide_x_forwarded:
Replace existing X-Forwarded-*
headers with GoDoxy provided headers
# docker labels
proxy.app1.middlewares.set_x_forwarded:
# route file
app1:
middlewares:
set_x_forwarded:
Fields:
-
address
: authentication provider URL (required) -
trust_forward_header
: whether to trustX-Forwarded-*
headers from upstream proxies (default:false
) -
auth_response_headers
: list of headers to copy from auth response (default: empty) -
add_auth_cookies_to_response
: list of cookies to add to response (default: empty)
# docker labels
proxy.app1.middlewares.forward_auth: |
address: https://auth.example.com
trust_forward_header: true
auth_response_headers:
- X-Auth-Token
- X-Auth-User
add_auth_cookies_to_response:
- uid
- session_id
# route file
app1:
middlewares:
forward_authorization:
address: https://auth.example.com
trust_forward_header: true
auth_response_headers:
- X-Auth-Token
- X-Auth-User
add_auth_cookies_to_response:
- uid
- session_id
Traefik equivalent:
traefik.http.middlewares.authentik.forwardauth.address: https://auth.example.com
traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true
traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-Auth-Token, X-Auth-User
traefik.http.middlewares.authentik.forwardauth.addAuthCookiesToResponse: uid, session_id