Using Fathom with Postgres and Docker

Update 2019-05-27: changes to work with the latest version of Fathom (1.2.1).

I recently replaced Google Analytics with Fathom, a new self-hosted website analytics service with a huge focus on privacy and owning your own data.

They offer a Docker image but the documentation on setting it up is a bit sparse. Here are the steps I took to get it up and running with data persistence.

Initial Run

The simplest way to get Fathom running is to run this command:

docker run -d --name=fathom -p 8080:8080 usefathom/fathom:latest

That’s all well and good, but what if you want to persist the data?

Persisting the SQLite Database

Figuring out how to persist the data was a little tricky because of how it’s stored in the image. If you run were to run ls in a running fathom container, you would see this:

$ docker exec -it fathom /bin/sh
/app # ls
fathom    fathom.db

The working directory of the container is /app which holds both the fathom executable and the SQLite database. This means that you simply can’t mount a volume from the host initially because mounted volumes from the host overwrite the path inside the container. Meaning, if you were to mount a volume from your host to /app, the executable would no longer exist and as such fathom would not be able to run.

Using a Docker Volume

You can, however, use a Docker volume instead of mounting a host path. This works because Docker volumes behave a bit differently than mounted host volumes, as they do not overwrite the path within the container.

To use a Docker volume, create a new one named fathom and mount it to /app:

$ docker volume create fathom
$ docker run -d --name=fathom -p 8080:8080 -v fathom:/app usefathom/fathom:latest

Using a Host Volume

What if you’d rather have the database live on the host and not in a Docker volume? That can be achieved by copying the database to the host using docker cp and then re-running the docker run command with a volume pointing to only the database.

For these examples, I’ll be using /host/fathom as the fathom volume path on the host machine.

docker cp fathom:/app/fathom.db /host/fathom/fathom.db

Now you can stop the running container and start it up again with the volume:

$ docker stop fathom
$ docker rm fathom
$ docker run -d --name=fathom -p 8080:8080 -v /host/fathom/fathom.db:/app/fathom.db usefathom/fathom:latest

Docker Compose

If you prefer to use a Docker compose file:

version: '3'

services:
  fathom:
    image: usefathom/fathom:latest
    volumes:
      - /host/fathom/fathom.db:/app/fathom.db
    ports:
      - 8080:8080

Using Postgres

To use Postgres instead of SQLite, modify your compose file to include a postgres container with your own credentials. Additionally, you’ll need to add some extra environment variables to the fathom container so the app will use your postgres database:

Note: Fathom expects a database named fathom.db.

version: '3'

services:
  fathom:
    image: usefathom/fathom:latest
    environment:
      FATHOM_DATABASE_DRIVER: postgres
      FATHOM_DATABASE_HOST: postgres
      FATHOM_DATABASE_PASSWORD: password123
      FATHOM_DATABASE_USER: fathom
      FATHOM_DATABASE_SSLMODE: disable
    depends_on:
      - postgres
    ports:
      - 8080:8080

  postgres:
    image: postgres:latest
    volumes:
      - /host/fathom/data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: "fathom.db"
      POSTGRES_USER: fathom
      POSTGRES_PASSWORD: password123

Logging in

Before you can login to the UI, create an account by running this command:

$ docker exec fathom ./fathom user add --email="[email protected]" --password="yourpassword"

The last step is to include the tracking snippet on your site and you’re ready to go!