Technology Encyclopedia Home >Deploy Plausible Analytics on a VPS — Privacy-Friendly Website Analytics Without Sharing Your Data

Deploy Plausible Analytics on a VPS — Privacy-Friendly Website Analytics Without Sharing Your Data

I used Google Analytics on my sites for years. It worked, but I increasingly felt uncomfortable about what I was handing over: visitor data going to Google, cookie consent banners required by GDPR, and no real understanding of where that data ended up.

Plausible Analytics is the open-source alternative. It's lightweight (the tracking script is under 1 KB — versus GA's 45 KB), cookie-free, GDPR-compliant by design, and you can self-host it so the data never leaves your server.

I run Plausible on Tencent Cloud Lighthouse. The 2 GB RAM / 2 vCPU plan handles Plausible comfortably for sites with moderate traffic; 4 GB for millions of monthly pageviews. Running Plausible on Lighthouse means your visitor analytics data stays on your server — not processed by any third party. As event volume grows, Plausible's ClickHouse database can grow significantly, and CBS cloud disk expansion lets you increase storage without migrating the analytics database. The snapshot feature also protects months of historical analytics data.


Table of Contents

  1. Why Self-Host Plausible?
  2. What You Need
  3. Part 1: Set Up Prerequisites
  4. Part 2: Deploy Plausible with Docker Compose
  5. Part 3: Configure Nginx with HTTPS
  6. Part 4: Add Your Website to Plausible
  7. Part 5: Integrate the Tracking Script
  8. Part 6: Email Reports and Alerts
  9. The Thing That Tripped Me Up
  10. Troubleshooting
  11. Summary

  • Key Takeaways
  • Use the appropriate Lighthouse application image to skip manual installation steps where available
  • Lighthouse snapshots provide one-click full-server backup before major changes
  • OrcaTerm browser terminal lets you manage the server from any device
  • CBS cloud disk expansion handles growing storage needs without server migration
  • Console-level firewall + UFW = two independent protection layers

Why Self-Host Plausible? {#why}

Self-hosted Plausible gives you:

  • No third-party data sharing — all analytics data stays on your server
  • No cookies — no cookie consent banners needed
  • GDPR/CCPA compliant by design — doesn't collect personal data
  • Lightweight tracking script — ~1 KB vs GA's 45 KB, no page load impact
  • Clean, focused dashboard — pageviews, unique visitors, sources, top pages, devices
  • Ad blocker resistant — serve the script from your own domain
  • Unlimited sites — one instance for all your projects
  • No data sampling — see 100% of your traffic, not a sample

The trade-off versus paid Plausible Cloud: you manage the server, handle updates, and monitor disk usage as data accumulates.


What You Need {#prerequisites}

Requirement Details
Server Ubuntu 22.04, 2 GB+ RAM
Docker + Docker Compose Installed
Domain Required — Plausible needs a domain
Email (optional) For reports and account registration

Part 1: Set Up Prerequisites {#part-1}

1.1 — Install Docker

curl -fsSL https://get.docker.com | sh
sudo systemctl enable docker
sudo usermod -aG docker $USER
newgrp docker

1.2 — Create Project Directory

mkdir -p /opt/plausible
cd /opt/plausible

1.3 — Generate a Secret Key

openssl rand -base64 64 | tr -d '\n'
# Save this output — you'll need it in the next step

Part 2: Deploy Plausible with Docker Compose {#part-2}

2.1 — Create the Environment File

nano /opt/plausible/plausible-conf.env
# Required — replace with your values
ADMIN_USER_EMAIL=you@example.com
ADMIN_USER_NAME=Admin
ADMIN_USER_PWD=your-secure-admin-password

BASE_URL=https://analytics.yourdomain.com
SECRET_KEY_BASE=YOUR_GENERATED_SECRET_KEY_HERE

# Disable registration for private instances
DISABLE_REGISTRATION=true

# Optional — for email reports
MAILER_EMAIL=plausible@yourdomain.com
SMTP_HOST_ADDR=smtp.sendgrid.net
SMTP_HOST_PORT=587
SMTP_USER_NAME=apikey
SMTP_USER_PWD=YOUR_SENDGRID_API_KEY
SMTP_HOST_SSL_ENABLED=false

Important: Set DISABLE_REGISTRATION=true if this is a private instance. Otherwise anyone who reaches the URL can create an account.

2.2 — Create docker-compose.yml

nano /opt/plausible/docker-compose.yml
version: "3.3"

services:
  mail:
    image: bytemark/smtp
    restart: always

  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:23.3.7.5-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
    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

2.3 — Create ClickHouse Configuration Files

Plausible uses ClickHouse for event storage. Configure it to reduce logging:

mkdir -p /opt/plausible/clickhouse

nano /opt/plausible/clickhouse/clickhouse-config.xml
<clickhouse>
  <logger>
    <level>warning</level>
    <console>true</console>
  </logger>
  <query_thread_log remove="remove"/>
  <query_log remove="remove"/>
  <text_log remove="remove"/>
  <trace_log remove="remove"/>
  <metric_log remove="remove"/>
  <asynchronous_metric_log remove="remove"/>
  <session_log remove="remove"/>
  <part_log remove="remove"/>
</clickhouse>
nano /opt/plausible/clickhouse/clickhouse-user-config.xml
<clickhouse>
  <profiles>
    <default>
      <log_queries>0</log_queries>
      <log_query_threads>0</log_query_threads>
    </default>
  </profiles>
</clickhouse>

2.4 — Start Plausible

cd /opt/plausible
docker compose up -d
docker compose logs -f

Wait until you see Access PlausibleWeb.Endpoint at http://localhost:8000. The first startup takes about 30–60 seconds as the database initializes.


Part 3: Configure Nginx with HTTPS {#part-3}

3.1 — Install Nginx and Certbot

sudo apt install -y nginx certbot python3-certbot-nginx

3.2 — Create Nginx Site

sudo nano /etc/nginx/sites-available/plausible
server {
    listen 80;
    server_name analytics.yourdomain.com;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}
sudo ln -s /etc/nginx/sites-available/plausible /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d analytics.yourdomain.com

3.3 — Access Plausible

Navigate to https://analytics.yourdomain.com and log in with your admin credentials from plausible-conf.env.


Part 4: Add Your Website to Plausible {#part-4}

4.1 — Create a New Site

After logging in:

  1. Click + Add Website
  2. Enter your website's domain (e.g., myblog.com)
  3. Choose your timezone
  4. Click Add snippet to continue

4.2 — Get the Tracking Script

Plausible provides a JavaScript snippet. Copy it — you'll add it to your website in the next step.


Part 5: Integrate the Tracking Script {#part-5}

Standard Integration

Add to your website's <head> section:

<script defer data-domain="myblog.com" 
        src="https://analytics.yourdomain.com/js/script.js">
</script>

Custom Script Path (Ad Blocker Resistance)

Plausible can be accessed via a custom path to avoid ad blocker detection. In Plausible: Settings → Custom domain / proxy.

Add to Nginx:

# Proxy the Plausible script through your own domain
location = /analytics.js {
    proxy_pass https://analytics.yourdomain.com/js/script.js;
    proxy_set_header Host analytics.yourdomain.com;
}

location /api/event {
    proxy_pass https://analytics.yourdomain.com/api/event;
    proxy_set_header Host analytics.yourdomain.com;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Then update the script tag to load from your own domain:

<script defer data-domain="myblog.com"
        data-api="/api/event"
        src="/analytics.js">
</script>

WordPress Integration

Install the Plausible Analytics WordPress plugin. Configure it to use your self-hosted instance:

  • Plugin Settings → Your Plausible domain → analytics.yourdomain.com

React / Next.js Integration

npm install next-plausible

In _app.js:

import PlausibleProvider from 'next-plausible'

export default function MyApp({ Component, pageProps }) {
  return (
    <PlausibleProvider domain="myblog.com" customDomain="https://analytics.yourdomain.com">
      <Component {...pageProps} />
    </PlausibleProvider>
  )
}

Hugo / Jekyll / Static Sites

Add the script tag to your layout template (usually in layouts/_default/baseof.html for Hugo or _includes/head.html for Jekyll).


Part 6: Email Reports and Alerts {#part-6}

Weekly Reports

In Plausible dashboard → Site Settings → Email reports:

  • Enable weekly email reports
  • Reports show pageviews, unique visitors, top pages, and top referrers

Spike Alerts

Set up traffic spike notifications:

  • Site Settings → Goals → Traffic spike notifications
  • Get an email when your site exceeds a traffic threshold

The Thing That Tripped Me Up {#gotcha}

After a few weeks, Plausible was reporting numbers much lower than expected — about 60% less than my previous analytics.

I thought something was wrong with the tracking script. After digging into the browser console, I found many visitors' requests to /api/event were being blocked by their ad blockers (uBlock Origin, Brave, etc.). Even though Plausible itself is privacy-friendly, the common ad blocking lists include patterns that match /api/event on unknown domains.

The fix: Set up the reverse proxy on your own website's domain (as described in Part 5 under "Custom Script Path"):

# Add to your website's Nginx config (not Plausible's Nginx)
location = /analytics.js {
    proxy_pass https://analytics.yourdomain.com/js/script.js;
}

location /api/event {
    proxy_pass https://analytics.yourdomain.com/api/event;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

By loading the script from your own domain and sending events to your own domain, it's effectively invisible to blockers. After this change, tracking accuracy improved significantly.


Troubleshooting {#troubleshooting}

Issue Likely Cause Fix
Plausible not starting Database init taking time Wait 60 seconds; check docker compose logs
No data appearing Script not loading Check browser console for script errors
"Domain mismatch" error Wrong domain in script tag Verify data-domain matches what's in Plausible
Low pageview counts Ad blockers filtering Use reverse proxy from your own domain (Part 5)
ClickHouse using too much disk Normal data accumulation Set data retention in Settings → Billing
Can't log in Wrong credentials Check plausible-conf.env for admin email/password
502 from Nginx Plausible not running docker compose ps and check docker compose up -d
SMTP email not working Config error Test SMTP credentials with a standalone mail test

Summary {#verdict}

What you built:

  • Plausible Analytics running on your cloud server
  • PostgreSQL (metadata) + ClickHouse (events) database stack
  • HTTPS dashboard at https://analytics.yourdomain.com
  • Tracking script added to your website
  • Optional: custom proxy path for ad blocker resistance
  • Email reports for traffic summaries
  • Registration disabled for private single-user use

Every website you add costs nothing extra — one Plausible instance handles all your sites. The data stays on your server, there are no GDPR cookie consent hoops, and the dashboard is refreshingly simple.

Frequently Asked Questions {#faq}

Is self-hosted Plausible Analytics GDPR compliant?
Self-hosted Plausible Analytics can be configured to be GDPR compliant — no data leaves your server, and many configurations don't require cookie consent banners because no personally identifiable data is collected.

How accurate is self-hosted analytics compared to other services?
Self-hosted analytics that serves tracking scripts from your own domain (avoiding ad blocker detection) often measures more accurately than third-party scripts that are commonly blocked.

How do I add tracking to multiple websites?
Most self-hosted analytics tools support multiple sites from a single installation. Add each site in the admin panel and get a separate tracking code for each.

How much server resource does Plausible Analytics need?
Analytics databases grow over time. The 2 vCPU / 4 GB RAM plan handles millions of monthly pageviews. Use CBS cloud disk expansion as the database grows.

Can I import historical data from Google Analytics?
Most analytics tools have import functionality for Google Analytics data. Check the tool's documentation for the specific import format and process.

👉 Get started with Tencent Cloud Lighthouse
👉 View current pricing and launch promotions
👉 Explore all active deals and offers