BlogTutorialsSelf-Host Plausible Analytics on VPS: Complete Setup Guide (2025)

Self-Host Plausible Analytics on VPS: Complete Setup Guide (2025)

Adrian Silaghi
Adrian Silaghi
January 17, 2026
18 min read
12 views
#plausible #analytics #self-hosted #vps #google analytics alternative #privacy #gdpr #docker #open source
Self-Host Plausible Analytics on VPS: Complete Setup Guide (2025)

Google Analytics is powerful, but it comes with baggage: privacy concerns, GDPR compliance headaches, cookie banners, and the nagging feeling that you're feeding Google even more data about your users.

Plausible Analytics is the antidote. It's lightweight (< 1KB script), privacy-focused, GDPR/CCPA/PECR compliant by design, and—best of all—you can self-host it on your own VPS for complete data ownership.

This guide walks you through setting up Plausible Analytics on a VPS from scratch, including Docker deployment, SSL certificates, PostgreSQL + ClickHouse configuration, and automated backups.

Why Self-Host Plausible?

Feature Google Analytics Plausible Cloud Plausible Self-Hosted
Monthly Cost Free (you are the product) $9-$99+/mo ~$5-10/mo (VPS cost)
Data Ownership Google owns it Plausible hosts it You own everything
GDPR Compliant Requires consent No consent needed No consent needed
Cookie Banner Required Not needed Not needed
Script Size ~45KB < 1KB < 1KB
Unlimited Sites Yes Plan-dependent Yes
Data Retention 14 months default Unlimited Unlimited (your storage)

Requirements

To self-host Plausible, you'll need:

  • VPS with 2+ GB RAM (ClickHouse needs memory)
  • 20+ GB storage (grows with traffic)
  • Docker and Docker Compose
  • Domain name (e.g., analytics.yourdomain.com)
  • Basic Linux knowledge

Recommended VPS Specs

Traffic Level Monthly Pageviews Recommended VPS DanubeData Plan
Small < 100K 2 vCPU, 2GB RAM, 40GB Starter (€4.49/mo)
Medium 100K - 1M 2 vCPU, 4GB RAM, 80GB Standard (€8.99/mo)
Large 1M - 10M 4 vCPU, 8GB RAM, 160GB Performance (€17.99/mo)
Enterprise 10M+ Dedicated CPU, 16GB+ RAM Dedicated plans

Step 1: Provision Your VPS

  1. Create a VPS on DanubeData
  2. Choose Ubuntu 24.04 LTS
  3. Select at least the Standard plan (4GB RAM recommended)
  4. Note your server IP address

Initial Server Setup

# SSH into your server
ssh root@YOUR_SERVER_IP

# Update system
apt update && apt upgrade -y

# Install essential tools
apt install -y curl wget git ufw

# Set up firewall
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

# Set hostname
hostnamectl set-hostname plausible

Step 2: Install Docker

# Install Docker
curl -fsSL https://get.docker.com | sh

# Install Docker Compose
apt install -y docker-compose-plugin

# Verify installation
docker --version
docker compose version

# Enable Docker to start on boot
systemctl enable docker

Step 3: Configure DNS

Point your domain to your VPS. Create an A record:

# DNS Configuration
Type: A
Name: analytics (or @ for root domain)
Value: YOUR_SERVER_IP
TTL: 300

Wait for DNS propagation (usually 5-15 minutes):

# Verify DNS
dig analytics.yourdomain.com +short
# Should return your server IP

Step 4: Download Plausible

# Create directory
mkdir -p /opt/plausible
cd /opt/plausible

# Download Plausible hosting files
git clone https://github.com/plausible/community-edition.git .

# Or download directly
curl -L https://github.com/plausible/community-edition/archive/refs/heads/master.tar.gz | tar xz --strip-components=1

Step 5: Configure Plausible

Generate Secret Key

# Generate a secure secret key
openssl rand -base64 48
# Save this output - you'll need it

Create Configuration File

# Create plausible-conf.env
cat > plausible-conf.env << 'EOF'
# Required: Base URL where Plausible will be accessible
BASE_URL=https://analytics.yourdomain.com

# Required: Secret key for encryption (generated above)
SECRET_KEY_BASE=YOUR_GENERATED_SECRET_KEY_HERE

# Optional: Disable registration after creating your account
DISABLE_REGISTRATION=invite_only

# Optional: Maximum login attempts before lockout
MAX_MIND_LICENSE_KEY=

# Database URLs (using Docker service names)
DATABASE_URL=postgres://postgres:postgres@plausible_db:5432/plausible_db
CLICKHOUSE_DATABASE_URL=http://plausible_events_db:8123/plausible_events_db

# SMTP Configuration (optional but recommended)
# MAILER_EMAIL=analytics@yourdomain.com
# SMTP_HOST_ADDR=smtp.yourdomain.com
# SMTP_HOST_PORT=587
# SMTP_USER_NAME=your_smtp_user
# SMTP_USER_PWD=your_smtp_password
# SMTP_HOST_SSL_ENABLED=true

# Google Search Console Integration (optional)
# GOOGLE_CLIENT_ID=
# GOOGLE_CLIENT_SECRET=

# IP Geolocation (optional - for country/city data)
# Sign up at https://www.maxmind.com/en/geolite2/signup
# MAXMIND_LICENSE_KEY=your_license_key
# MAXMIND_EDITION=GeoLite2-City

# Log level
LOG_LEVEL=warn
EOF

Important: Replace YOUR_GENERATED_SECRET_KEY_HERE with the key you generated, and update analytics.yourdomain.com with your actual domain.

Review Docker Compose Configuration

# View the default docker-compose.yml
cat docker-compose.yml

The default configuration includes:

  • plausible: Main Plausible application
  • plausible_db: PostgreSQL for user data
  • plausible_events_db: ClickHouse for analytics data

Step 6: Set Up Reverse Proxy with Caddy

Caddy provides automatic HTTPS with Let's Encrypt:

# Create Caddy configuration
cat > Caddyfile << 'EOF'
analytics.yourdomain.com {
    reverse_proxy plausible:8000

    # Security headers
    header {
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        Referrer-Policy strict-origin-when-cross-origin
    }

    # Gzip compression
    encode gzip

    # Logging
    log {
        output file /var/log/caddy/access.log
    }
}
EOF

# Update docker-compose.yml to include Caddy
cat > docker-compose.yml << 'EOF'
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-alpine
    restart: always
    volumes:
      - event-data:/var/lib/clickhouse
      - event-logs:/var/log/clickhouse-server
      - ./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
    env_file:
      - plausible-conf.env

  caddy:
    image: caddy:2-alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy-data:/data
      - caddy-config:/config
      - caddy-logs:/var/log/caddy
    depends_on:
      - plausible

volumes:
  db-data:
  event-data:
  event-logs:
  caddy-data:
  caddy-config:
  caddy-logs:
EOF

Create ClickHouse Config Files

# Create ClickHouse config directory
mkdir -p clickhouse

# ClickHouse logging config
cat > clickhouse/clickhouse-config.xml << 'EOF'

    
        warning
        true
    
    
    
    
    
    
    
    
    

EOF

cat > clickhouse/clickhouse-user-config.xml << 'EOF'

    
        
            0
            0
        
    

EOF

Step 7: Launch Plausible

# Start all services
docker compose up -d

# Watch the logs
docker compose logs -f

# Wait for "Starting Plausible server..." message
# Then press Ctrl+C to exit logs

Verify Services Are Running

# Check all containers
docker compose ps

# Expected output:
# NAME                    STATUS
# plausible-caddy-1       Up
# plausible-plausible-1   Up
# plausible-plausible_db-1        Up
# plausible-plausible_events_db-1 Up

Step 8: Create Your Account

  1. Visit https://analytics.yourdomain.com
  2. Click "Register" to create your admin account
  3. Verify your email (if SMTP is configured)
  4. Add your first website

Disable Public Registration

After creating your account, disable registration to prevent others from signing up:

# Edit configuration
nano plausible-conf.env

# Change to:
DISABLE_REGISTRATION=true

# Restart Plausible
docker compose restart plausible

Step 9: Add Tracking Script to Your Website

After adding your site in Plausible, add this script to your website:

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

Script Variants

<!-- Track outbound links -->
<script defer data-domain="yourdomain.com" src="https://analytics.yourdomain.com/js/script.outbound-links.js"></script>

<!-- Track file downloads -->
<script defer data-domain="yourdomain.com" src="https://analytics.yourdomain.com/js/script.file-downloads.js"></script>

<!-- Track 404 pages -->
<script defer data-domain="yourdomain.com" src="https://analytics.yourdomain.com/js/script.404.js"></script>

<!-- All features combined -->
<script defer data-domain="yourdomain.com" src="https://analytics.yourdomain.com/js/script.outbound-links.file-downloads.js"></script>

Step 10: Set Up Automated Backups

Protect your analytics data with automated backups to S3:

#!/bin/bash
# /opt/plausible/backup.sh

set -e

BACKUP_DIR="/opt/plausible/backups"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
S3_BUCKET="your-backup-bucket"

mkdir -p $BACKUP_DIR

echo "=== Plausible Backup: $DATE ==="

# Backup PostgreSQL
echo "Backing up PostgreSQL..."
docker compose exec -T plausible_db pg_dump -U postgres plausible_db | gzip > "$BACKUP_DIR/postgres_$DATE.sql.gz"

# Backup ClickHouse
echo "Backing up ClickHouse..."
docker compose exec -T plausible_events_db clickhouse-client --query="SELECT * FROM plausible_events_db.events FORMAT Native" | gzip > "$BACKUP_DIR/clickhouse_events_$DATE.native.gz"

# Backup configuration
echo "Backing up configuration..."
cp plausible-conf.env "$BACKUP_DIR/plausible-conf_$DATE.env"
cp docker-compose.yml "$BACKUP_DIR/docker-compose_$DATE.yml"

# Create combined archive
echo "Creating archive..."
tar -czf "$BACKUP_DIR/plausible_backup_$DATE.tar.gz" 
    "$BACKUP_DIR/postgres_$DATE.sql.gz" 
    "$BACKUP_DIR/clickhouse_events_$DATE.native.gz" 
    "$BACKUP_DIR/plausible-conf_$DATE.env" 
    "$BACKUP_DIR/docker-compose_$DATE.yml"

# Upload to S3
echo "Uploading to S3..."
rclone copy "$BACKUP_DIR/plausible_backup_$DATE.tar.gz" "danubedata:$S3_BUCKET/plausible/"

# Cleanup old local backups (keep last 7 days)
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
find $BACKUP_DIR -name "*.sql.gz" -mtime +1 -delete
find $BACKUP_DIR -name "*.native.gz" -mtime +1 -delete
find $BACKUP_DIR -name "*.env" -mtime +1 -delete
find $BACKUP_DIR -name "*.yml" -mtime +1 -delete

echo "=== Backup complete! ==="
# Make executable
chmod +x /opt/plausible/backup.sh

# Test backup
/opt/plausible/backup.sh

# Add to cron (daily at 3 AM)
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/plausible/backup.sh >> /var/log/plausible-backup.log 2>&1") | crontab -

Step 11: Enable GeoIP (Optional)

To see country/city data for visitors:

  1. Sign up for a free MaxMind account at maxmind.com
  2. Generate a license key
  3. Add to your configuration:
# Edit plausible-conf.env
MAXMIND_LICENSE_KEY=your_license_key
MAXMIND_EDITION=GeoLite2-City

# Restart
docker compose restart plausible

Step 12: Monitoring and Maintenance

Check Disk Usage

# Check Docker volumes
docker system df -v

# Check ClickHouse data size
docker compose exec plausible_events_db du -sh /var/lib/clickhouse

View Logs

# All logs
docker compose logs -f

# Specific service
docker compose logs -f plausible
docker compose logs -f plausible_events_db

Update Plausible

# Pull latest image
docker compose pull

# Restart with new version
docker compose up -d

# Check version
docker compose logs plausible | grep "Running Plausible"

Advanced Configuration

Custom Goals and Events

Track custom events in your application:

// JavaScript
plausible('Signup', {props: {plan: 'Premium'}});
plausible('Download', {props: {file: 'whitepaper.pdf'}});
plausible('Purchase', {props: {product: 'Pro Plan', value: '99'}});

API Access

Plausible provides an API for programmatic access:

# Get stats via API
curl "https://analytics.yourdomain.com/api/v1/stats/aggregate" 
  -H "Authorization: Bearer YOUR_API_KEY" 
  -d "site_id=yourdomain.com" 
  -d "period=30d" 
  -d "metrics=visitors,pageviews,bounce_rate"

Shared Links

Create public dashboard links for clients or stakeholders:

  1. Go to Site Settings → Visibility
  2. Enable "Public Dashboard" or create a "Shared Link"
  3. Optionally add password protection

Troubleshooting

Common Issues

# Container won't start
docker compose logs plausible
# Look for database connection errors

# SSL certificate issues
docker compose logs caddy
# Check domain DNS resolution

# High memory usage
# ClickHouse can be memory-hungry
# Consider upgrading VPS or tuning ClickHouse settings

# No data showing
# 1. Check script is loading (browser dev tools)
# 2. Check domain matches exactly
# 3. Check for ad blockers
# 4. Verify Plausible container is healthy

Reset Admin Password

# Access Plausible console
docker compose exec plausible /app/bin/plausible remote

# Reset password
Plausible.Auth.find_user_by(email: "your@email.com") |> Plausible.Auth.User.set_password("new_password") |> Plausible.Repo.update()

Cost Comparison

Let's compare the real costs:

Pageviews/Month Plausible Cloud Self-Hosted (DanubeData) Annual Savings
10K $9/mo ($108/yr) €4.49/mo (~€54/yr) ~$54/yr
100K $19/mo ($228/yr) €4.49/mo (~€54/yr) ~$174/yr
1M $69/mo ($828/yr) €8.99/mo (~€108/yr) ~$720/yr
10M $189/mo ($2,268/yr) €17.99/mo (~€216/yr) ~$2,052/yr

Bottom line: Self-hosting Plausible saves $174-$2,000+/year depending on traffic, plus you get unlimited sites, unlimited data retention, and complete data ownership.

Get Started Today

Ready to take control of your analytics?

  1. Create a VPS on DanubeData (€4.49/mo for small sites)
  2. Follow this guide to deploy Plausible
  3. Add the tracking script to your sites
  4. Enjoy privacy-friendly, GDPR-compliant analytics

DanubeData VPS for Plausible:

  • €4.49/mo Starter plan handles most small-medium sites
  • €8.99/mo Standard plan for higher traffic
  • NVMe storage for fast ClickHouse queries
  • German data center (GDPR-friendly)
  • 20TB included traffic

👉 Create Your Plausible VPS

Need help setting up Plausible? Contact our team—we're happy to help.

Share this article

Ready to Get Started?

Deploy your infrastructure in minutes with DanubeData's managed services.