This guide outlines how to set up a reverse proxy for Plausible CE using Caddy, Nginx, or Apache. It assumes you arrived here from the [quickstart guide.](https://github.com/plausible/community-edition/tree/v2.1.3#quick-start) **Note**: Starting from version [2.1.2](https://github.com/plausible/analytics/discussions/4618) a reverse proxy is no longer necessary since Plausible CE can handle HTTPS and automatic Let's Encrypt certificates as outlined in the quickstart. The Nginx and Apache configurations provided here have been contributed by the community and have not been tested by the maintainers. ## Expose Plausible To allow the reverse proxy to communicate with Plausible, set the HTTP port on which you want Plausible to listen: ```console $ echo "HTTP_PORT=8000" >> .env $ cat .env BASE_URL=https://plausible.example.com SECRET_KEY_BASE=As0fZsJlUpuFYSthRjT5Yflg/NlxkFKPRro72xMLXF8yInZ60s6xGGXYVqml+XN1 HTTP_PORT=8000 ``` And modify [compose.override.yml](compose-override) to expose that port to the host: ```sh $ cat > compose.override.yml << EOF services: plausible: ports: - 127.0.0.1:8000:${HTTP_PORT} EOF ``` Then launch and sanity-check it: ```console $ docker compose up -d $ curl --head http://localhost:8000 HTTP/1.1 200 OK ... ``` ## Caddy Caddy automatically manages HTTPS and WebSockets with minimal configuration. Here’s a sample Caddyfile setup: ```caddyfile plausible.example.com { reverse_proxy localhost:8000 } ``` Replace `plausible.example.com` with your actual domain name, which should match the [$BASE_URL](configuration#base_url) Save this configuration in a file named `Caddyfile`, and then run Caddy with: ```shell $ caddy run --config /path/to/Caddyfile ``` ## Nginx For Nginx, use the following server block configuration: ```nginx server { server_name plausible.example.com; listen 80; listen [::]:80; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /live/websocket { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } } ``` Replace `plausible.example.com` with your actual domain name, matching the [$BASE_URL](configuration#base_url) To enable this configuration: 1. Save the configuration to a file named `plausible` in your Nginx configuration directory. 2. Create a symbolic link in the `sites-enabled` directory: ```shell $ cp /path/to/plausible /etc/nginx/sites-available/ $ ln -s /etc/nginx/sites-available/plausible /etc/nginx/sites-enabled/plausible ``` 3. Restart Nginx: ```shell $ systemctl restart nginx ``` ## Apache For Apache, use the following configuration in your `plausible.conf` file: ```apache ServerAdmin admin@plausible.example.com ServerName plausible.example.com ProxyPreserveHost On ProxyAddHeaders On ProxyPassMatch ^/(live/websocket)$ ws://localhost:8000/$1 ProxyPass / http://localhost:8000/ ProxyPassReverse / http://localhost:8000/ SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" forwarded ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined env=!forwarded CustomLog ${APACHE_LOG_DIR}/access.log forwarded env=forwarded ``` Replace `plausible.example.com` with your actual domain name, which should match the [$BASE_URL](configuration#base_url) Follow these steps to set it up: 1. Enable the necessary Apache modules: ```shell $ a2enmod proxy proxy_http proxy_ajp remoteip headers proxy_wstunnel $ systemctl restart apache2 ``` 2. Copy the configuration to Apache’s configuration folder: ```shell $ cp /path/to/plausible.conf /etc/apache2/sites-available/ $ a2ensite plausible.conf $ systemctl restart apache2 ```