A docker container and reverse proxy setup to help you track your site's visitor data

Necessary? No. Helpful? Possibly. Plausible? Definitely.

Containers May 25, 2022

As someone who is both security conscious and curious as to how many people visit these articles I write, I've been interested in adding some analytics tracking to my site. I've got Google Analytics working pretty well, but like all home-labbers with a healthy weariness of Google deciding to charge for previously paid for services, I'm trying to remove any dependence on them. Given that they recently announced they'll be sunsetting Universal GA in 2023, this seemed like the perfect time to look for something I can control.

Enter Plausible. This is a fully self-hosted service which uses your domain to provide tracking analytics for your sites, either as full domains or sub-domains. It provides information such as the entry, exit and top pages visited, device info regarding browser and OS, and can also show geographic location of visitors if you enable the geo-ip functionality (note that I won't be including that version below). It puts all this together in a nice, easy-to-view gui.

Let's set it up.


Prerequisites

  1. You need to have Docker and docker-compose installed on your machine
  2. You need to be able to SSH into your machine, or use CLI/terminal
  3. An ability to use the git command, as we'll need to clone the repo
  4. You should have your own website already up and running, and you are able to access the <head> (header) for your site, either in the site itself or through your reverse proxy
  5. You should have your own domain name with a fully functioning reverse proxy (check out my SWAG article, and I recommend Cloudflare as an incredibly feature-packed, not to mention free CDN)
  6. A proxy docker network (either called proxy or something else, this is the network you use for your reverse proxy/SWAG container to communicate with the services it acts as RP for)
  7. SMTP mail credentials, either through your own or hosted SMTP server, or through something like Gmail which supports it (I use a service from https://eforw.com which provides a single domain with unlimited aliases and accounts for $10 per year)
💡
Docker normally ships with docker-compose preinstalled, so if you're installing docker for the first time then please check that first

Setting up the file system

As we're going to clone the repo, this will be pretty straightforward.

  • In your CLI/terminal, navigate to your docker or compose directory
  • Create your plausible folder by typing mkdir plausible and hitting Enter, then open that folder by typing cd plausible
  • Clone the repo by inputting the following command:
git clone https://github.com/plausible/hosting
copy paste this

This will download the repo into your current folder, which should be plausible.

If you now type ls you'll notice that you have one folder called hosting. It's up to you if you keep that, I personally don't like it so I simply cut and pasted everything from hosting directly into the plausible folder. If you want to do that then go ahead, otherwise just cd hosting to get yourself into the right place.


Prepping the container files

We're going to set up two files now which will not only spin up our containers, but will also create some volumes and the dedicate plausible docker network.

If you look through the repo you downloaded, you'll notice a few folders, and a few files. We're interested in docker-compose.yml and plausible-conf.env.

First, open up the docker-compose.yml in a text editor, using something like sudo vim docker-compose.yml (or replace vim with nano if you prefer that instead). You'll notice it's a pre-populated file, however we want to make some changes. So copy paste the following.

version: "3.3"
services:
  mail:
    image: bytemark/smtp
    container_name: plausible-mail
    restart: unless-stopped
    volumes:
      - /etc/localtime:/etc/localtime:ro #delete if necessary
    environment:
      - [email protected] #change
      - SMTP_HOST_ADDR=smtp.example.com #change
      - SMTP_HOST_PORT=587 #change if necessary
      - SMTP_USER_NAME=username #change
      - SMTP_USER_PWD=password #change
      - SMTP_HOST_SSL_ENABLED=true #change if not using TLS or STARTTLS

  plausible_db:
    image: postgres:12
    container_name: plausible-db
    restart: unless-stopped
    volumes:
      - db-data:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro #delete if necessary
    environment:
      - POSTGRES_PASSWORD=postgres

  plausible_events_db:
    image: yandex/clickhouse-server:21.3.2.5
    container_name: plausible-events-db
    restart: unless-stopped
    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
      - /etc/localtime:/etc/localtime:ro #delete if necessary
    ulimits:
      nofile:
        soft: 262144
        hard: 262144

  plausible:
    image: plausible/analytics:latest
    container_name: plausible-app
    restart: unless-stopped
    command: sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh db init-admin && /entrypoint.sh run"
    depends_on:
      - plausible_db
      - plausible_events_db
      - mail
    volumes:
      - /etc/localtime:/etc/localtime:ro #delete if necessary
    environment:
      - DISABLE_REGISTRATION=false
    ports:
      - 8000:8000 #change before the `:` if you've already mapped another service to port 8000
    env_file:
      - plausible-conf.env
    networks: 
      - default
      - proxy #rename if necessary

networks:
  default:
    name: plausible
    ipam:
      config:
        - subnet: 172.XX.0.0/28 #change `XX` as necessary
  proxy: #rename to your existing proxy network
    external: true

volumes:
  db-data:
    driver: local
  event-data:
    driver: local
pay attention to which lines require you to change/add your own info after the variable

Save the file.

The above does a few things. It creates 4 containers required to run Plausible, it creates 2 volumes, it creates one network (plausible) and references another (proxy), it assigns the plausible-conf.env file as the env_file for the app (more on that in a moment) and it specifically allows for registration.

Next, open and edit the plausible-conf.env file. Again it's prepopulated, delete that and copy in the following:

[email protected]
ADMIN_USER_NAME=AdminUser
ADMIN_USER_PWD=a strong password
BASE_URL=https://plausible.yourdomain.com
SECRET_KEY_BASE=generate the secret key base
CLICKHOUSE_DATABASE_USER=username
CLICKHOUSE_DATABASE_PASSWORD=password
Modify to use your own credentials and info on all lines

To generate the SECRET_KEY_BASE simply input the following into your CLI/terminal, and copy the output which should be a long randomized string of characters:

openssl rand -base64 64 | tr -d '\n' ; echo
copy paste exactly

Once you've completed that, save the file. You can check out additional configuration options here if you want, but I won't be covering them as they don't suit the purposes of this walkthrough.

We're now ready to create the containers.


Creating the containers

Type in docker-compose -p "plausible" up -d and hit Enter. This will create a stack called 'plausible' with the above containers. If you use Portainer to view/manage your containers, then your stack should look something like this:

Plausible stack as viewed in Portainer
Click to zoom

Click through the logs to check that everything's running, and if so then you should be able to access your instance at http://localhost:8000.

  • Create a new account by signing up with an email and password
  • Log out
  • Now go back to your docker-compose.yml file and locate the variablein the plausible service block which reads DISABLE_REGISTRATION
  • Change this variable to true to prevent additional user registration
  • Now recreate the container by typing
docker-compose -p "plausible" up -d plausible
This will only recreate the plausible container

STOP

You need to set up your CDN and reverse proxy NOW before going any further

The reason for this is that when you set up the sites you want to track inside Plausible, it gives you a code snippet to insert into the header of said site(s). If you do that while accessing it via localhost, then the snippet will give you an URL which uses your machine's IP address. This won't work, and so we need to access it via your domain.


Accessing Plausible

Assuming you've set it up correctly, you should now be able to access your Plausible instance through https://plausible.yourdomain.com or something like it. Go ahead and do that, then log in.

You should then be able to click + Add a website as per the below:

The landing page which displays the sites you're tracking

On the following page, add in the URL of the site or page you'd like to track, the timezone, then click Add snippet -->:

Set up your site

You'll then see your code snippet displayed, along with a copy button and an instruction to paste it into the <head> of your website. Go ahead and do that, then click Start collecting data:

Your tracking code snippet

Until you get your first visitor to your website, you'll see something like this:

But once traffic starts to flow, the data will start to be collected.


A note on CSP (Content-Security-Policy)

If you have CSP enabled on your website (generally recommended to avoid malicious script injections) you may need to modify it otherwise it could block Plausible from tracking. Dependent on how your site is set up, and what code you have running on it from other sites, you'll need to research and test what works well for you. I tend to run CSP with minimal rules, but I do use other, stricter policies to supplement it. Each use case will be different, so I encourage you to research and find out what works best for you.

Similarly, various browser adblockers or fingerprint protectors may also prevent Plausible from tracking them. There's not much you can do about this however, so be aware.


Related posts

Swag, Authelia and Reverse Proxies
A step-by-step walkthrough to self-host your Reverse Proxy with SWAG, and providing SSO and 2FA security using Authelia, all in docker
Adding Commento++ To Your Blog - Easy Commenting Tool
Encourage community and engagement on your self-hosted site by adding a lightweight and easy-to-use commenting service - also self-hosted!
Portainer - Easy Container Management for Docker
A step-by-step docker walkthrough to installing and configuring Portainer, your one-stop container-management resource

PTS

PTS fell down the selfhosted rabbit hole after buying his first NAS in October 2020, only intending to use it as a Plex server. Find him on the Synology discord channel https://discord.gg/vgSq5pcT

Have some feedback or something to add? Comments are welcome!

Please note comments should be respectful, and may be moderated