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 docker

Verify the installation:

docker --version
docker compose version

Then configure UFW to allow SSH, HTTP, and HTTPS:

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable

Step 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.yml

docker-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: local

Environment File (plausible-conf.env)

Generate a strong secret key first:

openssl rand -base64 48

Then 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_events

Set 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-nginx

Create the Nginx site configuration:

nano /etc/nginx/sites-available/plausible
server {
    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 --redirect

Certbot will automatically modify your Nginx config to handle HTTPS and set up auto-renewal via a systemd timer. Verify renewal works:

certbot renew --dry-run

Step 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=2

Use 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 plausible

Step 5 — Launch Plausible and First Login

Start the full stack in detached mode:

cd /opt/plausible
docker compose up -d

Watch the logs until the app reports it's listening:

docker compose logs -f plausible

Look 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 plausible

Add 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.gz

Create the backup directory first:

mkdir -p /opt/backups

Add 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-backup

ClickHouse 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 -d

Always 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 plausible and 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_URL in plausible-conf.env matches your exact domain including the https:// 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.

Read more