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

DateChange
2026-03-11Initial 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.
  • sudo or root access.
  • git and the openssl utility (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 plausible

The 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 compose.yml includes battle-tested ClickHouse configuration, proper healthchecks, and sensible defaults. Building a custom Compose file from scratch is error-prone and makes updates harder. Instead, we use a compose.override.yml to add only our Traefik-specific configuration โ€” Docker Compose merges both files automatically.

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 .env file in the next step.

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 BASE_URL must match your public URL exactly, including https://. A mismatch will cause tracking scripts to fail and break the dashboard.

๐Ÿ’ก REGISTRATION POLICY

The DISABLE_REGISTRATION=invite_only setting means that only you (the admin) can invite new users. This is the recommended setting for personal instances. Set it to true to completely disable new signups, or remove the line entirely to allow open registration.

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?

BASE_URL in .env tells Plausible which URL it runs under โ€” for generating correct links, cookies, and tracking scripts. The Traefik Host() label in compose.override.yml tells Traefik which incoming requests to route to the Plausible container. These are two independent systems that donโ€™t read each otherโ€™s configuration, so both need the domain separately.

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.

  1. Domain Name: In .env (BASE_URL) and compose.override.yml (Traefik Host label), replace plausible.your-domain.com with your actual domain.
  2. Secrets: In .env, paste the SECRET_KEY_BASE and TOTP_VAULT_KEY you generated in step 3.1.
  3. 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 -d

The 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 -f

Press 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

  1. Check Running Containers:

    docker ps --format '{{.Names}}'

    You should see three containers running: plausible-plausible-1, plausible-plausible_db-1 (PostgreSQL), and plausible-plausible_events_db-1 (ClickHouse).

  2. Access the Dashboard: Open a web browser and navigate to https://plausible.your-domain.com. You should see the Plausible registration page.

  3. 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: sudo docker compose exec plausible_db psql -U postgres -h localhost -d plausible_db -c "UPDATE users SET email_verified = true;"

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 script.js snippets from older versions will continue to work, but new sites will receive the dynamic format. You can configure tracking options (outbound links, file downloads, tagged events, etc.) directly in the site settings without changing the script URL.

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 .env or introduce new configuration options.

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 plausible

Conclusion

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.

๐Ÿ“šPLAUSIBLE SELF-HOSTING DOCS ๐Ÿ“ฆPLAUSIBLE CE ON GITHUB