Reverse proxy (settings.php)¶
Tells Drupal to trust X-Forwarded-* headers from the reverse proxy chain (Traefik → Varnish → Nginx) so generated URLs use https, the public hostname, and logs show the real client IP.
When it is written¶
- First install: if
DRUPAL_PROXY_ADDRESSESis notnone/ empty - Every boot:
sync-reverse-proxy.shreplaces the block (idempotent) - Disabled:
DRUPAL_PROXY_ADDRESSES=noneremoves the block on boot
Managed by: config/drupal/sync-reverse-proxy.sh + config/drupal/lib/reverse-proxy.py in wisski-base-image.
Environment variable¶
| Value | Meaning |
|---|---|
auto |
Detect CIDRs from container IPv4 interfaces (recommended on SCS) |
none |
No reverse proxy configuration |
172.20.0.0/16\|192.168.64.0/20 |
Explicit pipe-separated trusted proxy CIDRs |
Set on the Portainer stack as DRUPAL_PROXY_ADDRESSES. SCS Manager default: auto (see WissKI settings in SCS Manager).
Snippet appended to settings.php¶
/**
* Reverse proxy configuration.
* Auto-configured by entrypoint.
*/
$settings["reverse_proxy"] = TRUE;
$settings["reverse_proxy_trusted_headers"] = \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR
| \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_HOST
| \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PORT
| \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO;
$settings['omit_vary_cookie'] = TRUE;
$settings['reverse_proxy_addresses'] = ["172.20.0.42/16", "192.168.64.3/20"];
The last line is an example from auto detection; actual CIDRs depend on the stack’s Docker networks.
Setting reference¶
| Key | Purpose |
|---|---|
reverse_proxy |
Enable Symfony reverse proxy middleware |
reverse_proxy_trusted_headers |
Which X-Forwarded-* headers Drupal may use |
omit_vary_cookie |
Avoid Vary: Cookie issues behind Varnish |
reverse_proxy_addresses |
CIDRs of direct HTTP peers of Nginx (Varnish on main path, Traefik on raw.* path) |
What belongs in reverse_proxy_addresses¶
| IP / network | Trust? |
|---|---|
Varnish on internal network |
Yes (main URL) |
Traefik on reverse-proxy |
Yes (raw.* URL) |
| Client public IP | No |
Random 172.18.0.0/16 if stack uses 172.20.0.0/16 |
No — headers ignored, URLs stay http:// |
REMOTE_ADDR at PHP is always the IP of whoever connected to Nginx:80 (Varnish or Traefik), not Nginx itself (PHP-FPM uses a Unix socket).
Symptoms when misconfigured¶
| Symptom | Likely cause |
|---|---|
Links use http:// |
reverse_proxy_addresses does not include Varnish/Traefik CIDR |
| Wrong domain in URLs | Missing/wrong X-Forwarded-Host (check Traefik/Varnish) |
Client IP = 172.x / 192.168.x in Drupal |
reverse_proxy off or addresses wrong |
| Settings not updating after env change | Old image without sync-reverse-proxy.sh; recreate container |