1. Caddy version (caddy version
):
v2.5.1 h1:bAWwslD1jNeCzDa+jDCNwb8M3UJ2tPa8UZFFzPVmGKs=
2. How I run Caddy:
As a reverse proxy and web server for a symfony app
a. System environment:
Docker desktop in WSL 2
Dockerfile
ARG CADDY_VERSION=2
FROM caddy:${CADDY_VERSION}-builder-alpine AS symfony_caddy_builder
RUN xcaddy build \
--with github.com/dunglas/mercure \
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain \
--with github.com/dunglas/vulcain/caddy
FROM caddy:${CADDY_VERSION} AS symfony_caddy
WORKDIR /srv/app
COPY --from=dunglas/mercure:v0.11 /srv/public /srv/mercure-assets/
COPY --from=symfony_caddy_builder /usr/bin/caddy /usr/bin/caddy
COPY --from=symfony_php /srv/app/public public/
COPY docker/caddy/Caddyfile /etc/caddy/Caddyfile
docker-compose.yml
caddy:
build:
context: .
target: symfony_caddy
depends_on:
- php
environment:
SERVER_NAME: ${SERVER_NAME:-localhost}
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeMe!}
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeMe!}
restart: unless-stopped
volumes:
- php_socket:/var/run/php
- caddy_data:/data
- caddy_config:/config
ports:
# HTTP
- target: 80
published: ${HTTP_PORT:-80}
protocol: tcp
# HTTPS
- target: 443
published: ${HTTPS_PORT:-443}
protocol: tcp
# HTTP/3
- target: 443
published: ${HTTP3_PORT:-443}
protocol: udp
b. Command:
none
c. Service/unit/compose file:
Paste full file contents here.
Make sure backticks stay on their own lines,
and the post looks nice in the preview pane.
d. My complete Caddyfile or JSON config:
{
# Debug
{$DEBUG}
# HTTP/3 support
servers {
protocol {
experimental_http3
}
}
}
{$SERVER_NAME}:443 {
log
reverse_proxy {$SERVER_NAME}:80
}
{$SERVER_NAME}:80, caddy:80 {
log
route {
root * /srv/app/public
mercure {
# Transport to use (default to Bolt)
transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db}
# Publisher JWT key
publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
# Subscriber JWT key
subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
# Allow anonymous subscribers (double-check that it's what you want)
anonymous
# Enable the subscription API (double-check that it's what you want)
subscriptions
# Extra directives
{$MERCURE_EXTRA_DIRECTIVES}
}
vulcain
push
php_fastcgi unix//var/run/php/php-fpm.sock
encode zstd gzip
file_server
}
}
3. The problem I’m having:
Caddy send X-Forwarded-Proto
with an http
value to my symfony app.
The web server part of the Caddyfile don’t forward the proto of the reverse proxy section like nginx do.
4. Error messages and/or full log output:
{"level":"info","ts":1657098944.7389662,"logger":"http.log.access","msg":"handled request","request":{"remote_ip":"172.22.0.4","remote_port":"46952","proto":"HTTP/1.1","method":"GET","host":"localhost","uri":"/","headers":{"Sec-Fetch-User":["?1"],"Upgrade-Insecure-Requests":["1"],"X-Forwarded-For":["172.22.0.1"],"X-Forwarded-Proto":["https"],"Accept-Language":["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],"Cache-Control":["max-age=0"],"Sec-Fetch-Site":["cross-site"],"Sec-Fetch-Dest":["document"],"Sec-Gpc":["1"],"X-Forwarded-Host":["localhost"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"Accept-Encoding":["gzip, deflate, br"],"Sec-Fetch-Mode":["navigate"]}},"user_id":"","duration":0.070867548,"size":58191,"status":200,"resp_headers":{"Date":["Wed, 06 Jul 2022 09:15:44 GMT"],"X-Debug-Token":["b39101"],"Content-Type":["text/html; charset=UTF-8"],"Server":["Caddy"],"Cache-Control":["no-cache, private"],"X-Debug-Token-Link":["http://localhost/_profiler/b39101"],"X-Robots-Tag":["noindex"],"Link":["<http://localhost/api/docs.jsonld>; rel=\"http://www.w3.org/ns/hydra/core#apiDocumentation\""],"X-Powered-By":["PHP/8.1.7"]}}
{"level":"info","ts":1657098944.7403917,"logger":"http.log.access","msg":"handled request","request":{"remote_ip":"172.22.0.1","remote_port":"33870","proto":"HTTP/2.0","method":"GET","host":"localhost","uri":"/","headers":{"Cache-Control":["max-age=0"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36"],"Accept-Encoding":["gzip, deflate, br"],"Upgrade-Insecure-Requests":["1"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"Sec-Gpc":["1"],"Sec-Fetch-Site":["cross-site"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-User":["?1"],"Sec-Fetch-Dest":["document"],"Accept-Language":["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"localhost"}},"user_id":"","duration":0.075352902,"size":58191,"status":200,"resp_headers":{"Alt-Svc":["h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"],"Date":["Wed, 06 Jul 2022 09:15:44 GMT"],"Link":["<http://localhost/api/docs.jsonld>; rel=\"http://www.w3.org/ns/hydra/core#apiDocumentation\""],"X-Robots-Tag":["noindex"],"Cache-Control":["no-cache, private"],"Server":["Caddy","Caddy"],"X-Debug-Token-Link":["http://localhost/_profiler/b39101"],"X-Debug-Token":["b39101"],"Content-Type":["text/html; charset=UTF-8"],"X-Powered-By":["PHP/8.1.7"]}}
{"level":"error","ts":1657098945.2216153,"logger":"http.log.access","msg":"handled request","request":{"remote_ip":"172.22.0.1","remote_port":"46794","proto":"HTTP/1.1","method":"OPTIONS","host":"localhost","uri":"/_wdt/b39101","headers":{"Sec-Fetch-Mode":["cors"],"Sec-Fetch-Site":["cross-site"],"Connection":["keep-alive"],"Accept":["*/*"],"Access-Control-Request-Method":["GET"],"Access-Control-Request-Headers":["x-requested-with"],"Origin":["https://localhost"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36"],"Accept-Language":["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],"Sec-Fetch-Dest":["empty"],"Accept-Encoding":["gzip, deflate, br"]}},"user_id":"","duration":0.052704014,"size":36,"status":400,"resp_headers":{"Server":["Caddy"],"X-Debug-Token-Link":["http://localhost/_profiler/413d67"],"X-Powered-By":["PHP/8.1.7"],"Vary":["Origin"],"Access-Control-Allow-Methods":["GET, OPTIONS, POST, PUT, PATCH, DELETE"],"Access-Control-Allow-Origin":["https://localhost"],"X-Debug-Token":["413d67"],"Access-Control-Max-Age":["3600"],"Cache-Control":["no-cache, private"],"Content-Type":["text/html; charset=UTF-8"],"Access-Control-Allow-Headers":["content-type, authorization"],"Date":["Wed, 06 Jul 2022 09:15:45 GMT"],"Status":["400 Bad Request"],"X-Robots-Tag":["noindex"]}}
5. What I already tried:
I already tried to force value with header_up
in the reverse proxy and header
in the web server.