Nginx Proxy

August 8, 2026 ยท View on GitHub

Instead of using xpra's builtin proxy server, the apache http server can be configured as a single point of entry, on a single port.
Just like xpra's proxy, the apache proxy can provide multiple sessions, potentially on multiple remote backend servers.

This works well with both the html5 client and the regular xpra client with ws:// and wss:// URLs.

SSL

In these examples, it may be useful to have SSL certificates ready to use.
Having mkcert installed can help to ensure that the certificates generated are trusted locally.
If your package manager did not create any certificates when you installed the xpra server, you can do so now:

sudo /usr/bin/xpra setup-ssl

This command will not overwrite any existing certificates.


show

Create the config

cat > /usr/share/nginx/xpra-basic.conf << EOF
events {
}

http {

	map $http_upgrade $connection_upgrade {
		default upgrade;
		''	  close;
	}

	server {
		listen 443 ssl;
		listen 80;

		root /usr/share/xpra/www;

		ssl_certificate /etc/xpra/ssl/ssl-cert.pem;
		ssl_certificate_key /etc/xpra/ssl/key.pem;

		location / {
			proxy_pass http://127.0.0.1:10000;

			proxy_http_version 1.1;
			proxy_buffering off;
			proxy_cache_bypass $http_upgrade;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection "Upgrade";
			proxy_set_header Host $host;
		}
	}
}
EOF

Start nginx:

sudo nginx -c xpra-basic.conf

Xpra server

Start an xpra server on port 10000:

xpra seamless --bind-tcp=0.0.0.0:10000 --start=xterm

(beware: authentication is turned off for simplicity)

Then you can simply open your browser to connect to the session via the nginx proxy:

xdg-open http://localhost/

Or even via https if the certificates are configured correctly:

xdg-open https://localhost/

show

This example configuration maps different URLs to servers on different ports.

http {

	map $http_upgrade $connection_upgrade {
		default upgrade;
		''	  close;
	}

	server {
		listen 443 ssl;
		listen 80;

		root /usr/share/xpra/www;

		ssl_certificate /etc/xpra/ssl/ssl-cert.pem;
		ssl_certificate_key /etc/xpra/ssl/key.pem;

		proxy_redirect off;
		proxy_http_version 1.1;
		proxy_buffering off;
		proxy_cache_bypass $http_upgrade;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "Upgrade";
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;

		location /xpra1 {
			rewrite /xpra1/(.*) /\$1 break;
			proxy_pass http://127.0.0.1:10000;
		}
		location /xpra2 {
			rewrite /xpra2/(.*) /\$1 break;
			proxy_pass http://127.0.0.1:10001;
		}
	}
}
show

Most of the options below can make the connection more robust and should be applied to the location matching the xpra server being proxied for.
However, increasing the timeouts should not be necessary as the xpra protocol already includes its own ping packets every few seconds, which should ensure that the connection is kept alive.

These options may even introduce new issues, by making it harder for nginx to detect broken connections.

OptionRecommended valuePurpose
proxy_connect_timeoutunchangeda lower value can be used to fail faster when xpra servers are already started and initial connections should be fast
proxy_read_timeout10dor more, increase this option to prevent unexpected disconnections
proxy_send_timeout10dsame as proxy_read_timeout
limit_exceptlimit_except GET POST { deny all; }prevent unwanted http requests from reaching xpra's http server
proxy_socket_keepaliveunchangedshould not be needed, can be enabled
tcp_nodelayonkeep the latency low, this should already be enabled automatically for WebSocket connections
tcp_nopushoffmay introduce unwanted latency
proxy_no_cache1prevent caching of the xpra-html5 client
proxy_cache_bypass1prevent caching of the xpra-html5 client

The following options should not need to be modified: