I have a .app domain which I started hosting via Laravel Forge & Hetzner due to my main domain being a php-based app. Now, I want to host the self-hostable version of Plausible, plausible-ce so I've followed the guide seen in the link. I cloned the repo, updated the .env
to include the secret, BASE_URL pointing to my sub.domain.app and HTTP_PORT=8000
HTTPS_PORT=443. I also added the compose.override.yml
:
services:
plausible:
ports:
- 8000:${HTTP_PORT}
I've seen some videos of people hosting it directly through Forge (which also does the certificate handling & nginx config), but I want to try to make it work directly on the server. I installed certbot and set-up the SSL certificates for the domain and all seemed to work fine. Furthermore, I created a plausible config for nginx in /etc/nginx/
named plausible
, which contains:
server {
server_name sub.domain.app;
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";
}
}
As per plausible's documentation on reverse proxies I created a symbolic link in the sites-enabled directory and restarted nginx. Then I run docker compose up -d
and the containers seem to be fine initially, but the page is still inaccessible.
Navigating to sub.domain.app leads to ERR_TOO_MANY_REDIRECTS and after taking a peek into the plausible-ce container's logs I see:
Loading plausible..
Starting dependencies..
Starting repos.. Plausible.Repo database already exists
Plausible.IngestRepo database already exists Creation of Db successful!
Loading plausible..
Starting dependencies..
Starting repos..
15:47:40.197 [notice] Certificate for sub.domain.app is valid until 2025-07-12. Next renewal is scheduled for 2025-06-12.
So to me, it all looks fine so far, but when I try to reach the site, the docker logs this:
Request: GET /.well-known/acme-challenge/
** (exit) an exception was raised:
** (File.Error) could not read file "/var/lib/plausible/site_encrypt/certbot/acme-v02.api.letsencrypt.org/webroot/.well-known/acme-challenge": no such file or directory
(elixir 1.18.3) lib/file.ex:385: File.read!/1
(site_encrypt 0.6.0) lib/site_encrypt/acme_challenge.ex:12: SiteEncrypt.AcmeChallenge.call/2
(plausible 0.0.1) lib/plausible_web/endpoint.ex:1: PlausibleWeb.Endpoint.plug_builder_call/2
(plausible 0.0.1) lib/plausible_web/endpoint.ex:1: PlausibleWeb.Endpoint."call (overridable 3)"/2
(plausible 0.0.1) lib/plausible_web/endpoint.ex:1: PlausibleWeb.Endpoint.call/2
(plug_cowboy 2.7.3) lib/plug/cowboy/handler.ex:11: Plug.Cowboy.Handler.init/2
(cowboy 2.13.0) /app/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
(cowboy 2.13.0) /app/deps/cowboy/src/cowboy_stream_h.erl:310: :cowboy_stream_h.execute/3
Does this mean that the SSL certificate and the respective challenge aren't accessible from the container's volumes?
I also have this conf file in /etc/nginx/sites-enabled/plausible
:
server {
listen 80;
listen [::]:80;
server_name sub.domain.app;
location /.well-known/acme-challenge/ {
root /var/lib/plausible/site_encrypt/certbot/acme-v02.api.letsencrypt.org/webroot/;
try_files $uri =404;
}
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl ipv6only=on;
server_name sub.domain.app;
# SSL configuration (handled by Certbot)
ssl_certificate /etc/letsencrypt/live/sub.domain.app/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sub.domain.app/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Main proxy pass for Plausible
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Websocket support
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";
} }
Could it maybe be an issue due to the network plausible containers use and the network that forge created?
** (File.Error) could not read file "/var/lib/plausible/site_encrypt/certbot/..."
That file path only makes sense if Plausible was in charge of the SSL challenge, but you're handling certs manually (correctly) through Nginx + Certbot, so your app is so confused it doesn't even know how to start.
You're double-managing HTTPS , once via Nginx/Certbot, and again via Plausible's site_encrypt.
Stop the second security mechanism. Edit your .env
from plausible-ce
and add:
DISABLE_SSL=true