How to Deploy Plausible Analytics on Your VPS
If you're running a website and want to understand your visitors without sacrificing their privacy — or your own independence — Google Analytics is no longer the only game in town. Plausible Analytics is a lightweight, open-source alternative that respects GDPR out of the box, loads in under 1 KB, and gives you clean, actionable data without the surveillance baggage. This guide walks you through a complete self-hosted Plausible Community Edition deployment on Ubuntu 24.04, from a fresh VPS to a fully secured, production-ready analytics dashboard.
We'll cover everything in order: server preparation, Docker setup, Plausible configuration, Nginx reverse proxy with free SSL, SMTP email, and automated backups. By the end you'll have a privacy-first analytics platform running entirely on infrastructure you control.
What Is Plausible Analytics?
Plausible Analytics is an open-source web analytics tool built as a privacy-friendly replacement for Google Analytics. It collects only the metrics you actually need — pageviews, referrers, devices, countries — stores nothing personally identifiable, and requires no cookie banner under GDPR. The Community Edition (CE) is free to self-host, and the entire tracking script weighs less than 1 KB, meaning zero measurable impact on your page load times.
Prerequisites
- A VPS running Ubuntu 24.04 LTS (a Ryzen VPS with 2 vCPU / 2 GB RAM is more than enough)
- A domain name you control (e.g. analytics.yourdomain.com) with an A record pointing to your server IP
- Root or sudo access via SSH
- Ports 80 and 443 open in your firewall
- Basic comfort with the Linux command line
Step 1 — Prepare the Server and Install Docker
Start with a clean system update, then install Docker Engine and the Compose plugin directly from Docker's official repository.
apt update && apt upgrade -y
apt install -y ca-certificates curl gnupg lsb-release ufw
# Add Docker's GPG key and repository
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now dockerVerify the installation:
docker --version
docker compose versionThen configure UFW to allow SSH, HTTP, and HTTPS:
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enableStep 2 — Configure Plausible
Create a dedicated directory and pull the official Plausible CE configuration:
mkdir -p /opt/plausible && cd /opt/plausible
curl -L https://raw.githubusercontent.com/plausible/community-edition/main/docker-compose.yml \
-o docker-compose.ymldocker-compose.yml
The file pulled from the official repo is production-ready. It spins up three services: plausible (the Elixir app), plausible_db (PostgreSQL), and plausible_events_db (ClickHouse). Below is the canonical version — do not modify service names or internal ports:
version: "3.8"
services:
plausible_db:
image: postgres:16-alpine
restart: always
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=postgres
plausible_events_db:
image: clickhouse/clickhouse-server:24.3.3.102-alpine
restart: always
volumes:
- event-data:/var/lib/clickhouse
- ./clickhouse/clickhouse-config.xml:/etc/clickhouse-server/config.d/logging.xml:ro
- ./clickhouse/clickhouse-user-config.xml:/etc/clickhouse-server/users.d/logging.xml:ro
ulimits:
nofile:
soft: 262144
hard: 262144
plausible:
image: ghcr.io/plausible/community-edition:v2.1.4
restart: always
command: sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"
depends_on:
- plausible_db
- plausible_events_db
ports:
- 127.0.0.1:8000:8000
env_file:
- plausible-conf.env
volumes:
db-data:
driver: local
event-data:
driver: localEnvironment File (plausible-conf.env)
Generate a strong secret key first:
openssl rand -base64 48Then create /opt/plausible/plausible-conf.env and paste the output as your SECRET_KEY_BASE:
BASE_URL=https://analytics.yourdomain.com
SECRET_KEY_BASE=PASTE_YOUR_GENERATED_KEY_HERE
DISABLE_REGISTRATION=true
# Database connections (match compose service names)
DATABASE_URL=postgres://postgres:postgres@plausible_db:5432/plausible_db
CLICKHOUSE_DATABASE_URL=http://plausible_events_db:8123/plausible_eventsSet DISABLE_REGISTRATION=true after your first login to prevent unauthorized signups on your public instance.
Step 3 — Nginx Reverse Proxy and SSL
Install Nginx and Certbot:
apt install -y nginx certbot python3-certbot-nginxCreate the Nginx site configuration:
nano /etc/nginx/sites-available/plausibleserver {
listen 80;
listen [::]:80;
server_name analytics.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_buffering off;
}
}
Enable the site and obtain your SSL certificate:
ln -s /etc/nginx/sites-available/plausible /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d analytics.yourdomain.com --non-interactive \
--agree-tos -m you@yourdomain.com --redirectCertbot will automatically modify your Nginx config to handle HTTPS and set up auto-renewal via a systemd timer. Verify renewal works:
certbot renew --dry-runStep 4 — Configure SMTP Email
Plausible uses email for account creation and password resets. Add the following variables to your plausible-conf.env file, filling in your SMTP provider's credentials:
MAILER_EMAIL=plausible@yourdomain.com
SMTP_HOST_ADDR=smtp.yourmailprovider.com
SMTP_HOST_PORT=587
SMTP_USER_NAME=plausible@yourdomain.com
SMTP_USER_PWD=your_smtp_password
SMTP_HOST_SSL_ENABLED=false
SMTP_RETRIES=2Use port 587 with STARTTLS (set SMTP_HOST_SSL_ENABLED=false) for most providers including Mailgun, Postmark, and Amazon SES. Use port 465 and set SMTP_HOST_SSL_ENABLED=true for implicit TLS. After editing the env file, restart the stack to apply changes:
cd /opt/plausible && docker compose restart plausibleStep 5 — Launch Plausible and First Login
Start the full stack in detached mode:
cd /opt/plausible
docker compose up -dWatch the logs until the app reports it's listening:
docker compose logs -f plausibleLook for a line like Access PlausibleWeb.Endpoint at https://analytics.yourdomain.com. Once it appears, open your browser and navigate to https://analytics.yourdomain.com. Create your admin account, then immediately open plausible-conf.env, set DISABLE_REGISTRATION=true, and restart:
docker compose restart plausibleAdd your first site from the dashboard and copy the tracking snippet into the <head> of your website. Data will start flowing within minutes.
Step 6 — Backups and Upgrades
Database Backups
Back up the PostgreSQL database with a single command. Run this on a cron schedule (daily is recommended):
docker exec plausible_db pg_dump -U postgres plausible_db \
| gzip > /opt/backups/plausible-$(date +%F).sql.gzCreate the backup directory first:
mkdir -p /opt/backupsAdd to cron for daily 2 AM execution:
echo "0 2 * * * root docker exec plausible_db pg_dump -U postgres plausible_db | gzip > /opt/backups/plausible-\$(date +\%F).sql.gz" \
>> /etc/cron.d/plausible-backupClickHouse data is stored in the event-data Docker volume. For a full backup, you can also snapshot that volume or use docker run to archive it to a tar file.
Upgrading Plausible
To upgrade to a new release, update the image tag in docker-compose.yml, then pull and recreate:
cd /opt/plausible
# Edit docker-compose.yml and bump the image tag, then:
docker compose pull
docker compose up -dAlways check the Plausible CE release notes for migration steps before upgrading — some versions require running database migrations explicitly.
Troubleshooting Quick Reference
- 502 Bad Gateway: Plausible hasn't finished starting yet — run
docker compose logs -f plausibleand wait for the ready message before reloading Nginx. - Emails not arriving: Double-check your SMTP credentials and confirm port 587 is not blocked by your VPS provider's outbound firewall rules.
- Tracking script not loading: Make sure the
BASE_URLin plausible-conf.env matches your exact domain including thehttps://prefix — no trailing slash.
Conclusion
You now have a fully self-hosted Plausible Analytics instance running behind Nginx with automatic HTTPS, isolated Docker services, and daily database backups — all on infrastructure you own and control. The entire stack is lightweight enough to run comfortably on an entry-level server. At ByteHosting, our Ryzen VPS plans start at just €7.99/month, hosted in Frankfurt with NVMe storage and unmetered bandwidth — a perfect fit for self-hosted tools like Plausible. If you need more compute headroom for additional services, check out our Xeon VPS options or browse all of our affordable VPS plans to find the right size for your stack.