Privacy-focused analytics tools like Plausible are becoming increasingly popular as companies and individuals prioritize data sovereignty and privacy. Plausible Analytics is a lightweight, open-source, privacy-friendly alternative to Google Analytics. Hosting it yourself ensures that your analytics data remains entirely within your control, keeping your information secure and private.

plausible

The Plausible.io logo

Why run Plausible locally?

There are good reasons to host Plausible locally on your own infrastructure:

  • Privacy and Data Sovereignty: Keep all analytics data within your infrastructure—no external data transfers.
  • Unlimited Data Retention: Avoid restrictions imposed by third-party services—store and retain your data indefinitely.
  • Lightweight for lightweight applications: Run it cheaply - on less than 1 GB RAM and negligible CPU for small setups.

Additionally, with Plausible you get:

  • Cookie-Free Analytics: Plausible does not use cookies, eliminating intrusive cookie banners and simplifying compliance with privacy regulations. However, always verify local regulations.
  • Versatility: Suitable for websites, apps, intranets, and internal company tools.

If these benefits appeal to you, let’s dive into the setup process.

Setting up Plausible with Docker Compose and Traefik

This guide provides a minimal example of how to set up Plausible Analytics using Docker Compose and Traefik. This is not a general guide on Docker Compose or Traefik, so basic familiarity with these tools is assumed. If you prefer using Nginx or other web proxies, adapting this setup should be straightforward.

Prerequisites

Before proceeding, ensure you have the following:

  • Docker and Docker Compose installed
  • A running instance of Traefik (or another ingress proxy)
  • A domain correctly configured to point to your Traefik setup

Docker Compose configuration

The following example docker-compose.yml file provides a basic setup for running Plausible with Traefik. It utilizes Docker labels to handle routing and SSL certificate generation - and requires a .env-file in the same directory as the docker-compose.yml.

Example Docker Compose snippet:


  plausible_db:
    image: postgres:16-alpine
    restart: always
    volumes:
      - ${DATA_DIR}/plausible/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - TZ=${DOCKER_TZ}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      start_period: 1m

  plausible_events_db:
    image: clickhouse/clickhouse-server:24.3.3.102-alpine
    restart: always
    volumes:
      - ${DATA_DIR}/plausible/event-data:/var/lib/clickhouse
      - ${DATA_DIR}/plausible/event-logs:/var/log/clickhouse-server
      - ${CONFIG_DIR}/plausible/logs.xml:/etc/clickhouse-server/config.d/logs.xml:ro
      - ${CONFIG_DIR}/plausible/ipv4-only.xml:/etc/clickhouse-server/config.d/ipv4-only.xml:ro
      - ${CONFIG_DIR}/plausible/low-resources.xml:/etc/clickhouse-server/config.d/low-resources.xml:ro
      - ${CONFIG_DIR}/plausible/override-config.xml:/etc/clickhouse-server/config.d/override-config.xml:ro
    ulimits:
      nofile:
        soft: 262144
        hard: 262144
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 -O - http://127.0.0.1:8123/ping || exit 1"]
      start_period: 1m
    environment:
      - TZ=${DOCKER_TZ}

  plausible:
    image: ghcr.io/plausible/community-edition:v2.1.4
    restart: always
    command: sh -c "/entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"
    container_name: plausible
    depends_on:
      plausible_db:
        condition: service_healthy
      plausible_events_db:
        condition: service_healthy
    volumes:
      - ${DATA_DIR}/plausible/data:/var/lib/plausible
    ulimits:
      nofile:
        soft: 65535
        hard: 65535
    ports:
      - "8000:8000"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.plausible.rule=Host(`${PLAUSIBLE_DOMAIN}`)"
      - "traefik.http.routers.plausible.entrypoints=web,websecure"
      - "traefik.http.routers.plausible.tls.certresolver=zerosslCloudflare"
      - "traefik.http.routers.plausible.tls.domains[0].main=${PLAUSIBLE_DOMAIN}"    
    environment:
      - TMPDIR=/var/lib/plausible/tmp
      - BASE_URL=https://${PLAUSIBLE_DOMAIN}
      - SECRET_KEY_BASE=${PLAUSIBLE_SECRET_KEY_BASE}
      - DATABASE_URL=postgres://postgres:${POSTGRES_PASSWORD}@plausible_db:5432/plausible_db
      - GOOGLE_CLIENT_ID=${PLAUSIBLE_GOOGLE_CLIENT_ID}
      - GOOGLE_CLIENT_SECRET=${PLAUSIBLE_GOOGLE_CLIENT_SECRET}
      - MAILER_EMAIL=${PLAUSIBLE_SENDER_EMAIL}
      - MAILER_NAME=${PLAUSIBLE_SENDER_NAME}
      - SMTP_HOST_ADDR=${PLAUSIBLE_SMTP_HOST}
      - SMTP_HOST_PORT=${PLAUSIBLE_SMTP_PORT}
      - SMTP_USER_NAME=${PLAUSIBLE_SMTP_USERNAME}
      - SMTP_USER_PWD=${PLAUSIBLE_SMTP_PASSWORD}
      - TZ=${DOCKER_TZ}

Understanding the components

This setup consists of three primary components:

Plausible database

  • Stores user credentials, site configurations, and tracking settings.
  • Uses PostgreSQL with a default user (postgres).
  • Once initialized, the database password should not be changed directly in docker-compose.yml—update it within PostgreSQL first.

ClickHouse (analytics data storage)

  • Serves as the analytics data warehouse.
  • Can be resource-intensive; optimizations like restricting resource usage and enabling IPv4-only mode are recommended.
  • Requires specific XML configurations (logs.xml, ipv4-only.xml, low-resources.xml, override-config.xml) to optimize performance and reliability. These should be placed in your local directory ${CONFIG_DIR}/plausible/.

Plausible front-end

  • Provides the user interface, tracking script and API.
  • Integrated with Traefik for routing and SSL certificate management.
  • Uses environment variables to enable features like Google Analytics import and email notifications.
  • Plausible defaults to disabling self-registration and requiring email verification for invitations. A correctly configured SMTP server (such as Gmail’s SMTP) is necessary for email functionality.

Additional configuration needed

For the above setup to work, you need to do some additional configuration.

SMTP server

You need to make sure you have a TLS enabled SMTP server that accepts connections from your server. Plausible doesn't send a lot of emails. For a simple and low cost solution, check out Option 2: Send email with the Gmail SMTP server at Google support, which will work fine for most cases as long as you accept that the sending email is a Gmail account.

Google analytics data migration and Google search console integration

The GOOGLE_CLIENT_ID and the GOOGLE_CLIENT_SECRET are needed to make the Google integrations work. But how you do get these values? There is a brilliant walktrough here. It will help you with setting up both the data migration and the search console integration.

  • The data migration will fetch Google Analytics historic data and put them into Plausible
  • The search console integration will put search console into Plausible, so you can see how people find your pages through Google search.

Troubleshooting

When setting up the directory structure for Clickhouse and the Postgres database, make sure the directory permissions are correct. The original Plausible documentation doesn't use bind mounts as I do; instead they use docker volumes. When using bind mounts, you get better visibility to the files, but there are other disadvantages, so you should consider using docker volumes for a production environment. If you use bind mounts, make sure that:

  • the db directory is owned by uid 70 (chown 70:root -R db)
  • the data directory is owned by uid 999 (chown 999:nogroup -R data)
  • the event-data and event-logs are owned by syslog (chown syslog:crontasb -R event-data and event-logs)

If permissions are wrong, you may get stuck in a reboot loop because the database is never properly created, and you may get strange "timezone" warnings because Plausible can't create a timezone directory within the data directory as part of the bootstrapping process.

The correct permission settings may differ, but this is what worked for me. If you have problems with the installation not finishing - just use docker volumes. Just make sure you back up the volumes securely.

Wrapping up

By running Plausible behind Traefik, you gain insightful analytics while maintaining complete control over your data. This setup ensures privacy, flexibility, and security, making it an excellent alternative to third-party analytics providers.

Additional resources

Previous Post