Apache
Run FeatherPanel behind Apache 2 as a reverse proxy. The installer template, the modules it needs and corrections for WebSockets and headers.
On this page
When you pick the Apache access method, the installer runs a2enmod ssl proxy proxy_http proxy_wstunnel rewrite, renders
the template into /etc/apache2/sites-available/featherpanel.conf and runs a2ensite featherpanel.
Template shipped with the panel
.github/docker/ssl/apache2.conf:
<VirtualHost *:80>
ServerName your-domain.com
Redirect permanent / https://your-domain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName your-domain.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
ProxyPreserveHost On
RequestHeader set X-Real-IP "%{REMOTE_ADDR}s"
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ProxyPass / http://localhost:4831/
ProxyPassReverse / http://localhost:4831/
# WebSocket support
ProxyPass /ws/ ws://localhost:4831/ws/
ProxyPassReverse /ws/ ws://localhost:4831/ws/
</VirtualHost>
Things to check
The template has three gaps you should fix by hand:
RequestHeadercomes frommod_headers, which the installer does not enable. Runa2enmod headers, or Apache refuses to start with “Invalid command ‘RequestHeader’”.- Apache matches
ProxyPassrules in the order they appear, soProxyPass /catches/ws/before the WebSocket rule is reached. Useupgrade=websocketon the main rule (Apache 2.4.47 and later) instead of a separate/ws/rule. - Nothing raises the timeouts for long-lived connections. Add
ProxyTimeout 3600.
A corrected virtual host:
<VirtualHost *:443>
ServerName your-domain.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
ProxyPreserveHost On
ProxyTimeout 3600
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ProxyPass / http://127.0.0.1:4831/ upgrade=websocket
ProxyPassReverse / http://127.0.0.1:4831/
</VirtualHost>
mod_proxy adds X-Forwarded-For itself, so the corrected file does not set it.
sudo a2enmod ssl proxy proxy_http proxy_wstunnel headers rewrite
sudo a2ensite featherpanel
sudo apachectl configtest && sudo systemctl reload apache2
The plain HTTP template (.github/docker/plaintext/apache2.conf) is the same proxy block in a *:80 virtual host with
X-Forwarded-Proto "http".