Self-Hosting Plausible Analytics with Docker and Traefik
Table of Contents ๐
This guide walks you through deploying a fully self-hosted Plausible Analytics instance. Plausible is a lightweight, privacy-friendly alternative to Google Analytics โ it doesnโt use cookies, is fully GDPR-compliant, and respects the privacy of your visitors. By self-hosting it, you retain complete ownership of your data while keeping your analytics costs predictable.
We use the official Plausible Community Edition repository as the foundation and integrate it with our existing Traefik v3 reverse proxy via a compose.override.yml. This approach keeps the original compose.yml untouched, making future updates clean and painless.
Changelog
| Date | Change |
|---|---|
| 2026-03-11 | Initial Version: Guide created for self-hosting Plausible CE v3.2.0 behind Traefik v3 with CrowdSec, based on the official repository. |
1. Prerequisites
This guide builds upon a secure Docker environment. Before you begin, you must have a fully functional Traefik v3 and CrowdSec stack.
| โ ๏ธ HARD REQUIREMENT |
The following steps will not work correctly without the Traefik stack running as described in the prerequisite guide.
|
You will also need:
- A dedicated subdomain for your Plausible instance (e.g.,
plausible.your-domain.com) pointed to your serverโs IP address. sudoor root access.gitand theopensslutility (sudo apt install git openssl).
2. Clone the Official Repository
Instead of building our own Docker Compose configuration from scratch, we clone the official Plausible CE repository. It ships with a tested compose.yml and pre-configured ClickHouse settings (including IPv4-only mode and resource-friendly defaults).
cd /opt/containers
sudo git clone -b v3.2.0 --single-branch https://github.com/plausible/community-edition plausible
cd plausibleThe repository contains the following structure:
plausible/
โโโ clickhouse/
โ โโโ default-profile-low-resources-overrides.xml
โ โโโ ipv4-only.xml
โ โโโ logs.xml
โ โโโ low-resources.xml
โโโ compose.yml
โโโ LICENSE
โโโ README.md| โน๏ธ WHY NOT A CUSTOM COMPOSE FILE? |
The official |
3. Configuration
We only need to create two files: an .env file with your settings and a compose.override.yml for Traefik integration.
3.1. Generate Secrets
Plausible requires a secret key base for signing tokens and a TOTP vault key for two-factor authentication.
# Generate the secret key base (at least 64 bytes)
SECRET_KEY_BASE=$(openssl rand -base64 48)
echo "Your Secret Key Base is: $SECRET_KEY_BASE"
# Generate the TOTP vault key
TOTP_VAULT_KEY=$(openssl rand -base64 32)
echo "Your TOTP Vault Key is: $TOTP_VAULT_KEY"| โน๏ธ SAVE THESE SECRETS |
Copy these generated values into a temporary text file. You will need to paste them into the |
3.2. Environment Configuration (.env)
This single file holds all your instance-specific settings. Create it in the repository root:
cat > .env << 'EOF'
# --- Required Settings ---
# Replace with your actual domain, including https://
BASE_URL=https://plausible.your-domain.com
# Paste the secret key base generated in step 3.1
SECRET_KEY_BASE=PASTE-YOUR-SECRET-KEY-BASE-HERE
# Paste the TOTP vault key generated in step 3.1
TOTP_VAULT_KEY=PASTE-YOUR-TOTP-VAULT-KEY-HERE
# --- Registration ---
# "invite_only" = only you can invite users. "true" = no new signups at all.
# Remove this line entirely to allow open registration.
DISABLE_REGISTRATION=invite_only
# --- Email / SMTP (Optional but recommended) ---
# Without SMTP, features like password resets and weekly reports will not work.
# The "From:" address shown in emails sent by Plausible.
# Use your SMTP login address or an alias your mail server accepts.
MAILER_EMAIL=plausible@your-domain.com
# Your SMTP server address, e.g. smtp.mailbox.org or mail.your-domain.com
SMTP_HOST_ADDR=your-mail-server.com
# Your SMTP port: typically 587 (STARTTLS) or 465 (SSL)
SMTP_HOST_PORT=587
# Your SMTP username โ usually your full email address
SMTP_USER_NAME=your-smtp-username
# Your SMTP password
SMTP_USER_PWD=your-smtp-password
# Set to "true" only if your port is 465 (implicit SSL). For port 587, keep "false".
SMTP_HOST_SSL_ENABLED=false
EOF| โ ๏ธ BASE_URL MUST BE CORRECT |
The |
| ๐ก REGISTRATION POLICY |
The |
3.3. Traefik Integration (compose.override.yml)
This file adds the Traefik labels and network connection to the Plausible service. Docker Compose merges it automatically with the official compose.yml โ no need to modify the original file.
cat > compose.override.yml << 'EOF'
services:
plausible:
networks:
- default
- proxy
labels:
- "traefik.enable=true"
# Replace plausible.your-domain.com with your actual domain.
# This tells Traefik which incoming requests to route to this container.
- "traefik.http.routers.plausible.rule=Host(`plausible.your-domain.com`)"
- "traefik.http.routers.plausible.entrypoints=websecure"
- "traefik.http.routers.plausible.tls.certresolver=tls_resolver"
- "traefik.http.routers.plausible.middlewares=security-headers@file,crowdsec-bouncer@docker"
- "traefik.http.services.plausible.loadbalancer.server.port=8000"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
EOF| โน๏ธ WHY DOES THE DOMAIN APPEAR TWICE? |
|
3.4. Update Configuration with Your Values
Replace all placeholders in the two files you just created. Every value that needs your input is marked with inline comments.
- Domain Name: In
.env(BASE_URL) andcompose.override.yml(TraefikHostlabel), replaceplausible.your-domain.comwith your actual domain. - Secrets: In
.env, paste theSECRET_KEY_BASEandTOTP_VAULT_KEYyou generated in step 3.1. - Email Settings: In
.env, update the SMTP section with your mail server details. Each field has an inline comment explaining what to enter.
4. Launch the Stack
With both files in place, start the stack:
# From within the /opt/containers/plausible directory
sudo docker compose up -dThe first launch will take a few minutes as Docker pulls the images and Plausible runs its initial database migrations. You can monitor the progress with:
sudo docker compose logs -fPress CTRL+C to exit the logs view once all services are stable. You should see Plausible report that it is ready.
5. Verify the Installation
Check Running Containers:
docker ps --format '{{.Names}}'You should see three containers running:
plausible-plausible-1,plausible-plausible_db-1(PostgreSQL), andplausible-plausible_events_db-1(ClickHouse).Access the Dashboard: Open a web browser and navigate to
https://plausible.your-domain.com. You should see the Plausible registration page.Create Your Admin Account: Register with your email address and a strong password. Since we set
DISABLE_REGISTRATION=invite_only, this first account becomes the admin. All future registrations will require an invitation from you.
| ๐ก EMAIL VERIFICATION WITHOUT SMTP |
If you skipped the SMTP configuration, you can manually verify your email address by running: |
6. Add Plausible to Your Website
After logging in and creating your first site in the dashboard, Plausible will provide a tracking snippet. Starting with v3, Plausible generates a dynamic, site-specific script for each site you add. Simply copy the snippet from the site settings and add it to the <head> section of your website.
For a Zola-based site, add the provided snippet to your templates/base.html (or equivalent template). It will look something like this:
<!-- Replace both domains: plausible.your-domain.com = your Plausible instance, your-website.com = the site you want to track -->
<script defer src="https://plausible.your-domain.com/js/script.js" data-domain="your-website.com"></script>| โน๏ธ NEW DYNAMIC SNIPPET IN V3 |
Plausible v3 introduced a new, more configurable tracking snippet that is specific to each site. Legacy |
7. Maintenance
Updating Plausible
Since we cloned the official repository, updating involves fetching the new version tag and restarting. Your compose.override.yml and .env remain untouched.
cd /opt/containers/plausible
# Fetch the latest tags from the repository
sudo git fetch --tags
# Check out the new version (replace v3.x.x with the actual new version tag)
sudo git checkout v3.x.x
# Re-apply your override (it's preserved โ just verify it's still there)
cat compose.override.yml
# Pull the new images and restart
sudo docker compose pull
sudo docker compose up -d --remove-orphans| ๐ก CHECK RELEASE NOTES |
Always consult the official Plausible release notes before updating. Major version upgrades may require changes to your |
Backing Up
A complete backup consists of the PostgreSQL database (user data, site settings) and the ClickHouse database (analytics events). Since the official setup uses Docker named volumes, we back up via the running containers.
# From your /opt/containers/plausible directory
# 1. Back up the PostgreSQL database
sudo docker compose exec -T plausible_db pg_dump -U postgres -d plausible_db | gzip > plausible_pg_backup_$(date +%F).sql.gz
# 2. Back up the ClickHouse data via a temporary Alpine container
sudo docker run --rm \
-v plausible_event-data:/data \
-v $(pwd):/backup \
alpine tar -czvf /backup/plausible_clickhouse_backup_$(date +%F).tar.gz -C /data .
echo "Backup complete."| โน๏ธ BACKUP STRATEGY |
For a production instance, consider automating this with a cron job. The PostgreSQL dump can run against the live database without stopping services. For ClickHouse, a file-level backup of the named volume is sufficient for smaller instances. |
Restoring from Backup
To restore your instance from a backup:
cd /opt/containers/plausible
# 1. Stop the main application
sudo docker compose stop plausible
# 2. Restore PostgreSQL
gunzip < plausible_pg_backup_YYYY-MM-DD.sql.gz | sudo docker compose exec -T plausible_db psql -U postgres -d plausible_db
# 3. Restore ClickHouse (stop ClickHouse first)
sudo docker compose stop plausible_events_db
sudo docker run --rm \
-v plausible_event-data:/data \
-v $(pwd):/backup \
alpine sh -c "rm -rf /data/* && tar -xzvf /backup/plausible_clickhouse_backup_YYYY-MM-DD.tar.gz -C /data"
sudo docker compose start plausible_events_db
# 4. Start everything
sudo docker compose start plausibleConclusion
You now have a fully self-hosted, privacy-respecting analytics platform running behind your secure Traefik and CrowdSec stack. By using the official Plausible CE repository as a foundation and adding only a lightweight compose.override.yml for Traefik, your setup is easy to maintain and update โ closely following the upstream project without custom workarounds.
Plausible gives you all the essential web analytics insights โ page views, referrers, locations, devices โ without compromising your visitorsโ privacy or relying on third-party services. Your data stays on your server, under your control.





