Dealing with websockets in Caddy 2

1. The problem I’m having:

I’m trying to forward websocket requests to a websocket server. But whatever I do I’m not able to. I have the FrankenPHP plugin in my caddy server as well.

My caddyfile is like so:

{
	auto_https off
	admin off
	servers {
		trusted_proxies static private_ranges
		protocols h1 h2
	}
	{$CADDY_GLOBAL_OPTIONS}

	frankenphp {
		#worker /path/to/your/worker.php
		{$FRANKENPHP_CONFIG}
	}

	order mercure after encode
	order vulcain after reverse_proxy
	order reverse_proxy before php_server
	order php_server before file_server
	order php before file_server

	log {
		output stdout
		format console
	}
}

(cors) {
	@origin_localhost_http header Origin http://localhost*
	@origin_localhost_https header Origin https://localhost*
	@origin_docker_http header Origin http://*.docker.local
	@origin_docker_https header Origin https://*.docker.local
	@origin_127_http header Origin http://127.0.0.1*
	@origin_127_https header Origin https://127.0.0.1*
	@origin_front header Origin https://front.example.com
	@origin_development header Origin https://example-api.docker.local

	header @origin_localhost_http Access-Control-Allow-Origin "{header.Origin}"
	header @origin_localhost_https Access-Control-Allow-Origin "{header.Origin}"
	header @origin_docker_http Access-Control-Allow-Origin "{header.Origin}"
	header @origin_docker_https Access-Control-Allow-Origin "{header.Origin}"
	header @origin_127_http Access-Control-Allow-Origin "{header.Origin}"
	header @origin_127_https Access-Control-Allow-Origin "{header.Origin}"
	header @origin_front Access-Control-Allow-Origin "https://front.example.com"
	header @origin_development Access-Control-Allow-Origin "https://example-api.docker.local"
	header {
		Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
		Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
		Access-Control-Allow-Credentials true
		Access-Control-Max-Age "3600"
		defer
	}
}

{$CADDY_EXTRA_CONFIG} 

{$SERVER_NAME:localhost} {
	import cors

	@forwarded_ssl {
		header X-Forwarded-Proto https
	}
	@forwarded_ws {
		header X-Forwarded-Proto wss
	}

	# Handle OPTIONS requests
	@options {
		method OPTIONS
	}
	handle @options {
		respond 204
	}

	@websockets {
		header Connection *Upgrade*
		header Upgrade websocket
		path /app/*
	}

	reverse_proxy @websockets localhost:6001 {
		transport http {
			keepalive 2m
		}
	}

	root * {$DOCUMENT_ROOT:/var/www/html/public}
	encode zstd br gzip 

	{$CADDY_SERVER_EXTRA_DIRECTIVES}

	php_server
	log {
		output stdout
		format console
		level DEBUG
	}
}

I try to do requests like: ws://api.lexample.com/app/app-key?protocol=7&client=js&version=8.3.0&flash=false

The server interprets this as something it should forward to the PHP server instead, then the PHP server throws a 404 because the route doesn’t exist in it indeed.

Am I missing something obvious?

Thank you in advance and sorry for my (possibly) dumb issue :stuck_out_tongue:

2. Error messages and/or full log output:

3. Caddy version: v2.8.4

{"message":"Uncaught PHP Exception Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException: \"No route found for \"GET https://api.lrgi-sb-brand.com/app/app-key\"\" at RouterListener.php line 127","context":{"exception":{"class":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","message":"No route found for \"GET https://api.example.com/app/app-key\"","code":0,"file":"/var/www/html/vendor/symfony/http-kernel/EventListener/RouterListener.php:127","previous":{"class":"Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException","message":"No routes found for \"/app/app-key/\".","code":0,"file":"/var/www/html/vendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php:70"}}},"level":400,"level_name":"ERROR","channel":"request","datetime":"2025-01-06T16:19:03.569428+00:00","extra":{}}

4. How I installed and ran Caddy:

Running from a Docker container

a. System environment:

Debian Bookworm (on Docker), MacOS 15.2 ARM64

b. Command:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

5. Links to relevant resources: