My setup consists in a headless Chrome instance running on http://localhost:9222. It works if I connect to it directly through a WebSocket client.
I would like to put a Nginx server block as a proxy in front of it (I'll add authentication, etc, later).
My configuration is:
server {
# Logic configuration
server_name chrome.example.eu;
access_log /opt/chrome/access.log;
error_log /opt/chrome/error.log;
location / {
proxy_pass http://127.0.0.1:9222;
proxy_http_version 1.1;
proxy_set_header Host $host;
location /devtools/page/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}
# Networking
listen 80;
}
The HTTP part works fine. The Chrome devtools' UI is displaying if I open http://chrome.mydomain.eu. However, the websocket connection can't be established.
The browser tries to connect to ws://chrome.example.eu/devtools/page/6877e641-fc1e-4196-bb55-0c3e1608af4a
but the server does not upgrade to a WebSocket connection. Nginx sends back a 404 response, and the error.log contains a line that I can't understand:
*690 open() "/usr/share/nginx/html/devtools/page/6877e641-fc1e-4196-bb55-0c3e1608af4a" failed (2: No such file or directory), client: 130.79.192.16, server: chrome.example.eu, request: "GET /devtools/page/6877e641-fc1e-4196-bb55-0c3e1608af4a HTTP/1.1", host: "chrome.example.eu"
Why would nginx try to open a static file as there is no try_files
? And why nginx isn't letting the Chrome instance handle that request (and it works in the parent location block)?
I feel I'm missing something simple, but I tried lots of little variations without success.
Subsidiary question: also, can I get rid of the child location block when the browser asks for a ws:// stream? (that is, automatic protocol upgrade without having to hardcode the WebSocket URL) — And don't hesitate if you have any other kind of recommendation.
Best Answer
Have you tried setting the proxy_pass for your child location? As far as I know, content handlers are not inherited.