Deploy Plausible Analytics
This guide explains how to deploy Plausible Analytics self-hosted on a Linux server (Ubuntu 24.04 LTS). Plausible is an open-source web analytics solution focused on simplicity and privacy: traffic measurement without cookies or personal tracking, suited for sites that want statistics while respecting visitors' privacy.
Deployment uses Docker and Docker Compose, with Nginx as reverse proxy and Let's Encrypt for HTTPS.
Order a Server
To host your Plausible instance, HostMyServers offers several suitable options:
- Performance VPS - Ideal for one or more sites
- NVMe VPS - Excellent value for money
- Eco Dedicated Servers - For high analytics traffic
- Performance Dedicated Servers - Maximum performance
Prerequisites
- SSH access as root or user with sudo
- Ubuntu 24.04 LTS (or Debian / Fedora)
- Docker and Docker Compose installed
- A domain name (e.g.
plausible.yourdomain.com) with an A record pointing to the server's public IP - Ports 80 (HTTP) and 443 (HTTPS) accessible
Required Configuration
| Component | Minimum | Recommended |
|---|---|---|
| RAM | 2 GB | 4 GB |
| CPU | 2 cores | 2-4 cores |
| Storage | 10 GB | 20 GB |
| Network | 100 Mbps | 1 Gbps |
If Docker is not yet installed, follow the official Docker documentation for Ubuntu.
Connect to the Server
Connect via SSH to your server:
ssh user@server_ip_address
System Update
Update the package list before starting:
sudo apt update
sudo apt upgrade -y
Plausible Environment Configuration
Plausible uses environment variables for base URL, admin account, and app settings (PostgreSQL, ClickHouse). Create a dedicated directory, clone the Community Edition repo, and prepare the .env file.
Create directory and clone repo
mkdir -p ~/plausible
cd ~/plausible
git clone https://github.com/plausible/community-edition.git
cd community-edition
Generate a secret key
Plausible requires a secret key (SECRET_KEY_BASE) for signing sessions. Generate one:
openssl rand -base64 64 | tr -d '\n'
Copy the output; you will use it in the .env file in the next step.
Create .env file
Create the .env file at the project root (inside community-edition):
nano .env
Add the following configuration, replacing values with your own:
ADMIN_USER_EMAIL=admin@example.com
ADMIN_USER_NAME=admin
ADMIN_USER_PWD=YOUR_ADMIN_PASSWORD
BASE_URL=https://plausible.yourdomain.com
SECRET_KEY_BASE=YOUR_GENERATED_SECRET_KEY
DATABASE_URL=postgres://postgres:postgres@plausible_db:5432/plausible_db
CLICKHOUSE_DATABASE_URL=http://plausible_events_db:8123/plausible_events_db
| Variable | Description |
|---|---|
ADMIN_USER_EMAIL | Plausible admin account email |
ADMIN_USER_NAME | Admin display name |
ADMIN_USER_PWD | Admin account password (use a strong password) |
BASE_URL | Public Plausible URL (HTTPS, your domain) |
SECRET_KEY_BASE | Key generated in the previous step |
DATABASE_URL | PostgreSQL connection (do not change unless customizing) |
CLICKHOUSE_DATABASE_URL | ClickHouse connection for events (do not change) |
Adapt admin@example.com, YOUR_ADMIN_PASSWORD, plausible.yourdomain.com and YOUR_GENERATED_SECRET_KEY to your environment.
Expose application port (Docker Compose override)
Plausible listens internally on port 8000. So Nginx can reach it, expose this port locally only via an override file:
nano compose.override.yaml
Content:
services:
plausible:
ports:
- 127.0.0.1:8000:8000
Save and exit. Docker Compose will merge this file with compose.yml on startup.
Deploy Plausible Containers
With the environment configured, start all services (app, PostgreSQL, ClickHouse) with Docker Compose:
cd ~/plausible/community-edition
docker compose up -d
Verify all containers are running:
docker compose ps
All services (plausible, plausible_db, plausible_events_db, etc.) should be "Up". On error, check logs: docker compose logs -f.
Nginx Reverse Proxy and HTTPS (Let's Encrypt)
To expose Plausible over the internet with HTTPS, install Nginx as reverse proxy in front of port 8000, then Certbot to obtain a Let's Encrypt certificate and configure HTTPS automatically.
Install Nginx
sudo apt update
sudo apt install -y nginx
Create Nginx configuration for Plausible
Create a dedicated virtual host (replace plausible.yourdomain.com with your domain):
sudo nano /etc/nginx/sites-available/plausible.conf
Content:
server {
listen 80;
listen [::]:80;
server_name plausible.yourdomain.com;
access_log /var/log/nginx/plausible.access.log;
error_log /var/log/nginx/plausible.error.log;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
Enable the site and test configuration:
sudo ln -s /etc/nginx/sites-available/plausible.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Open ports 80 and 443 in firewall
Port 80 is needed for ACME validation (Let's Encrypt), 443 for HTTPS access:
sudo ufw allow 80,443/tcp
sudo ufw reload
Obtain TLS certificate with Certbot
Install Certbot and the Nginx plugin, then request a certificate for your domain (replace email and domain):
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d plausible.yourdomain.com -m admin@example.com --agree-tos --no-eff-email
Certbot automatically configures Nginx for HTTPS and sets up certificate renewal.
Let's Encrypt certificates are renewed automatically via a cron/systemd task provided by the certbot package.
Access and Initial Setup
Once Nginx and HTTPS are in place, you can create the admin account and add sites to track.
Create admin account
- Open a browser and go to:
https://plausible.yourdomain.com/register - Enter name, email and password, then click Create my account.
If you set ADMIN_USER_EMAIL and ADMIN_USER_PWD in .env, the first account may already exist; in that case log in with those credentials on /login.
Add a site to analyze
- In the dashboard, click Add a website (or equivalent).
- Enter the domain to track (e.g.
yoursite.com), choose the reporting timezone, then click Install Plausible. - Plausible shows a tracking script (JavaScript). Copy it and add it to the
<head>of your pages (see Plausible installation docs). - Click Verify script installation once the script is deployed on your site.
- After a few page views, the dashboard shows statistics (visitors, page views, etc.).
Useful Commands
| Command | Description |
|---|---|
docker compose ps | Plausible container status |
docker compose logs -f plausible | Follow application logs |
docker compose down | Stop all containers |
docker compose up -d | Restart containers in background |
sudo systemctl reload nginx | Reload Nginx configuration |
Directory Structure
| Path | Description |
|---|---|
~/plausible/community-edition/ | Plausible Community Edition repo |
~/plausible/community-edition/.env | Environment variables (secrets, URL, admin) |
~/plausible/community-edition/compose.override.yaml | Port 8000 exposure for Nginx |
/etc/nginx/sites-available/plausible.conf | Nginx configuration (reverse proxy) |
Troubleshooting
Containers won't start
- Check logs:
docker compose logs - Ensure
.envis at the root ofcommunity-editionandSECRET_KEY_BASEandBASE_URLare set. - Check disk space and memory:
df -handfree -h
502 Bad Gateway in browser
- Verify containers are running:
docker compose ps - Verify Plausible is listening on 8000:
curl -I http://127.0.0.1:8000 - Check Nginx logs:
sudo tail -f /var/log/nginx/plausible.error.log
Tracking script doesn't detect visits
- Ensure the script is in the
<head>of your pages. - Ensure the domain configured in Plausible matches the site domain exactly (no subdomain unless configured).
- Wait a few minutes and refresh the dashboard; events may take a moment to appear.
Certificate renewal
- Test renewal:
sudo certbot renew --dry-run - On failure, ensure port 80 is reachable from the internet and the Nginx virtual host for the domain is enabled.