Fathom is watching you

January 17, 2019 - 19 min

After a very succesful launch (okay, maybe that’s a bit of an overstatement…), I realised I had no idea how many people actually visited my site and read my first blog article.

In a world dominated by Google, I wanted to stay away from Google Analytics, even though the Gatsby starter I used has a plugin for that out of the box.

It’s overkill for what I need, I would not own the data, and Google would certainly use it to profile my visitors. Yes, you! And I care deeply about your privacy.

Photo by Matthew Henry on Unsplash Lucky you, not everyone has a choice…, Photo by Matthew Henry on Unsplash

After listening to episode 102 Paul Jarvis - Staying Small of Full Stack Radio, I knew which tool I would be using.

Fathom, a privacy oriented website analytics tool

Fathom is an open-source project which was created by Paul Jarvis and Danny van Kooten. The README file on their GitHub repository reads as follows:

Fathom Analytics is a simpler and more privacy-focused alternative to Google Analytics.
Collecting information on the internet is important, but it’s broken. We’ve become complacent in trading information for free access to web services, and then complaining when those web services do crappy things with that data.

And I have to agree with them, we often don’t realise that we’re trading information when, and sadly not limited to, something is offered for free.

This analytics tool also respects people’s wishes not to be tracked if “Do Not Track” is enabled in their browser settings.

Not only it is open-source, but they also provide instructions on how to install Fathom on your own server.

That seemed to be exactly what I needed: an ethical solution to understand how my website is performing!

The power of open-source

After receiving my Hacktoberfest 2018 T-Shirt and stickers, I saw that the coaster provided in the pack had some promo-code to use on Digital Ocean, with some free credit. I’ve always found their write-ups to be useful (some are listed in Resources) and they do support Open Source. Why not use a Droplet to deploy my own analytics then?

The rest of this article will dive into how you can deploy your own instance of Fathom for your website.

Note: I will use Digital Ocean, but most of the following instructions should be applicable to other providers.

1. Creating a Droplet

Go over to Digital Ocean and create an account - no obligation, but you can use the following referral link: it will give you $100 in credit for 60 days, and if you ever spend more than $25 on their platform, I will be rewarded with $25. So it’s a win-win.

Photo by Aaron Burden on Unsplash A Droplet is the cute name Digital Ocean gives to their Virtual Machines, Photo by Aaron Burden on Unsplash

They will first ask you to create a project, which might be useful in the future if you want to regroup resources for a specific …project. You could name it “My Cool and Ethical Analytics with Fathom” but if that is a bit too dull for you, you could get even more creative with it. But don’t waste too much time on it: you could always edit that later in the Settings tab of your project.

Now is the moment you’ve been waiting for: click on the green button Create in the top right corner and select Droplets. You should see the following screen:

Droplet creation

Select Ubuntu 18.10 x64 like I did if you want to live on the edge, but the default Ubuntu 16.04 x64 should be fine too.

Unless you need more performances, I would stick with the default Droplet at $5/mo. It should be more than enough, and it is always possible to resize your Droplet in the future if need be.

I chose to ignore the following sections about adding backups and block storage.

As for the datacentre region, I chose Frankfurt, which sits in Europe. It’s closer to me and there should be better privacy laws here in Europe than in the USA; that is, if you count the UK out of Europe. Oh wait, Brexit! I digress.

Next, I did not select any extra services, but I added an SSH key in the following section. You can use this guide on GitHub to generate a new SSH key. Copy the content of the resulting .pub file in the text input on Digital Ocean.

Leave the number of Droplets to create to 1 and the pre-selected project as “My Cool and Ethical Analytics with Fathom”. Click on Create, wait for the Droplet to be initialised and voilà.

2. Hacker’s time: SSH into the Droplet

Inspect your Droplet and click on the ipv4 address to copy it. Leave your favourite browser aside for now and open a terminal. (You might already have one open if you followed the instructions above to generate a new SSH key.)

Note: lines in code blocks starting with $ or user@machine:~# correspond to the terminal prompt; the rest corresponds to outputs from command executions. e.g.

$ ls
folder1 folder2 file1

or equivalently

user@machine:~# ls
folder1 folder2 file1

Complete and run the following command

$ ssh root@<copy here the ipv4 address>

and you should see something similar as below printed in the terminal. Isn’t it magic?

Welcome to Ubuntu 18.10 (GNU/Linux 4.18.0-10-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue Jan 15 21:37:52 UTC 2019

  System load:  0.92              Processes:           90
  Usage of /:   4.5% of 24.06GB   Users logged in:     0
  Memory usage: 14%               IP address for ens3: <some IP address>
  Swap usage:   0%

  Get cloud support with Ubuntu Advantage Cloud Guest:

0 packages can be updated.
0 updates are security updates.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

root@<name of your droplet>:~#

Congratulations, you just connected as user root on your virtual machine.

3. Securing your Droplet

Leaving root as the only user is usually a bad idea: whoever owns root has administrator privilege on your virtual machine. Also, disabling the ways to connect to your server which you won’t be using is an accepted best practice - and it’s quite easy to set up thanks to ufw, the Uncomplicated FireWall utility.

A good place to start to secure your Droplet is the following guide from Digitial Ocean: Initial Server Setup with Ubuntu 18.04. But as a tl;dr, I will describe below the necessary steps.

3.1 Add a new user

Run the following command

$ adduser jonsnow

which should yield:

Adding user `jonsnow' ...
Adding new group `jonsnow' (1000) ...
Adding new user `jonsnow' (1000) with group `jonsnow' ...
Creating home directory `/home/jonsnow' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:

It’s a good idea to use a strong password, or maybe I should say passphrase. I will choose handball-waterski-nectar-holster-snail.

Retype new UNIX password:
passwd: password updated successfully
Changing the user information for jonsnow
Enter the new value, or press ENTER for the default
	Full Name []:
	Room Number []:
	Work Phone []:
	Home Phone []:
	Other []:
Is the information correct? [Y/n]

So far so good. That command even created your own user folder:

$ ls /home

3.2 Granting jonsnow admin privilege

To indicate you would like to execute a command with admin (called superuser) privilege, you would prefix it with sudo, as in “superuser do”. Since we might need to execute commands requiring admin role, we run

$ usermod -aG sudo jonsnow

which means “add user jonsnow to the superuser group”.

3.3 Enabling the firewall

We want to make sure we can still use ssh to login on our Droplet (otherwise, we can just kill it from the Digital Ocean admin panel).

$ ufw allow OpenSSH
Rules updated
Rules updated (v6)

Now we can enable the firewall to protect us from unwanted connections (answer y as “yes” to the question):

$ ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Congratulations, all connections, apart from SSH, are blocked!

3.4 Enabling ssh access for jonsnow

If you open a new terminal and try to connect to your server:

$ ssh jonsnow@<ipv4 address>

you will realise it’s not possible: Permission denied (publickey). This is because we have not configured jonsnow’s authorized ssh keys. The easiest is to copy the authorized key from the root user account. In the same terminal where you should have root@<machine name>:~# in front of the prompt, execute:

$ rsync --archive --chown=jonsnow:jonsnow ~/.ssh /home/jonsnow

and now in a different terminal, try again to ssh into your Droplet as jonsnow. Hurray, we’re now connected as root and jonsnow.

3.5 Disabling ssh access for root

Finally, we can disable connections as root; the following command replaces “PermitRootLogin yes” by “PermitRootLogin no” in the configuration file for sshd, the program (called ssh daemon) which deals with ssh connections:

$ sed --in-place 's/^PermitRootLogin yes$/PermitRootLogin no/g' /etc/ssh/sshd_config

We can now restart the SSH daemon to take into account this new configuration:

$ systemctl restart sshd

To verify this worked, open a new terminal and try to connect as root to your Droplet. The good answer should be Permission denied (publickey).

We should now have a proper and somewhat secure setup to install our Fathom instance.

4. Installing Fathom

We will follow the instructions from Fathom’s GitHub repository.

Note: The instructions assume you are connected to your Droplet as jonsnow.

4.1. Download the latest release

At the time of writing, the latest release is version 1.2.1. On the release page, make sure to copy the link from the release ending in linuxamd64.tar.gz_. To download it, execute in the terminal of the virtual machine:

$ wget https://github.com/usefathom/fathom/releases/download/v1.2.1/fathom_1.2.1_linux_amd64.tar.gz

If you want to see that the downloaded file is really there, you can run ls - short for list - to see the content of the current directory.

jonsnow@<name of your droplet>:~# ls
fathom_1.2.1_linux_amd64.tar.gz  snap

To make sure we downloaded the right file as the authors of this project intended, we should verify the integrity of the file. Using a hash function, like SHA-256, we can get some kind of fingerprint of any text/file. To do so, run:

$ sha256sum fathom_1.2.1_linux_amd64.tar.gz

which should print

d09a81f8bd7c844a4214a500a3de8c20b3fbff292b5a0fa648e9efdc05ecd769  fathom_1.2.1_linux_amd64.tar.gz

Going back to the release page, we can download checksums.txt and verify that the output we got matches the one written in that .txt file.

4.2. Extract the archive to /usr/local/bin

This is almost achieved by

$ tar -C /usr/local/bin -xzf fathom_1.2.1_linux_amd64.tar.gz

Indeed, we get some errors:

$ tar -C /usr/local/bin -xzf fathom_1.2.1_linux_amd64.tar.gz
tar: LICENSE: Cannot open: File exists
tar: README.md: Cannot open: File exists
tar: fathom: Cannot open: File exists
tar: Exiting with failure status due to previous errors

This is because we are trying to extract the content of the file we downloaded into a special folder on your virtual machine: /usr/local/bin is the usual folder to put executables that you downloaded, but you need admin privilege to write there. That’s why we need to prefix that command with sudo:

$ sudo tar -C /usr/local/bin -xzf fathom_1.2.1_linux_amd64.tar.gz

However, it is not yet executable. We can remedy this by executing

$ chmod +x /usr/local/bin/fathom

chmod is a utility to change permissions (read/write/execute) on a file or folder and the argument +x means add executability (or searchability in the case of folders).

We can now verify that Fathom is installed properly:

$ fathom --version
Fathom version 1.2.1, commit 8f7c6d2e45ebb28651208e2a7320e29948ecdb2c, built at 2018-11-30T09:21:37Z

4.3 Optional Steps

Configuring Fathom and Register your admin user are optional steps in the documentation.

The first one would be interesting to consider in case you would like to use a different database and make sure that the secret Fathom uses is one that you generated (in case you did not trust Fathom to provide you with a good secret).

The second one would be necessary in case you would like to make your dashboard private:

$ fathom user add --email="[email protected]" --password="strong-password"

That command would create a user with email and password of your choosing, for your Fathom instance. Not only that, but when trying to access the Fathom dashboard, you should be greeted with a login page instead of your analytics.

Login Page

Registering a user is also necessary if you would like to manage several websites on the same Fathom instance. Have a look at this GitHub comment to know more.

4.4 Fathom server

We can now execute the almighty command

$ fathom server
INFO[0000] Fathom version 1.2.1, commit 8f7c6d2e45ebb28651208e2a7320e29948ecdb2c, built at 2018-11-30T09:21:37Z
WARN[0000] Error reading configuration. File `.env` does not exist.
INFO[0000] Connected to sqlite3 database: /home/jonsnow/fathom.db
INFO[0000] Applied 26 database migrations!

Try and go over to http://< ipv4 address >:8080. Sadly, we do not see yet the desired output:

Welcome screen of a new Fathom instance

I want to see this, pretty please!

4.5 Your patience will be rewarded, pinky promise

Our security measures were a bit too strict: remember how we blocked all connections apart from SSH? The good news is that in this step, we are not only going to make the connection to our dashboard possible, but we will also make sure our Fathom instance restarts if the server is shut down or restarted for any reason. Just wait to see the icing on the cake.

4.5.1. Setting up NGINX

NGINX is going to provide us with a web server that can be seen as an app by ufw, so that we can allow it.


$ sudo ufw app list
Available applications:


$ sudo ufw app list
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS

To install it, we execute:

$ sudo apt install nginx

and remove the default configuration

$ sudo rm /etc/nginx/sites-enabled/default

Let us create a site configuration:

$ sudo nano /etc/nginx/sites-available/tracking.example.com

where tracking.example.com is the domain where you plan to access your dashboard.

Your terminal should transform into

nano tracking example com

Paste the following content:

server {
	server_name tracking.example.com;

	location / {
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_set_header Host $host;

Press successively CTRL+O to Write Out and CTRL+X to Exit.

If you read carefully in the previous command, we only created a configuration file in the available-sites folder. We now need to enable it by creating a symbolic link (it’s like a desktop shortcut, sort of) to the enabled-sites folder:

$ sudo ln -s /etc/nginx/sites-available/tracking.example.com /etc/nginx/sites-enabled/tracking.example.com

For this to come into effect, we must test our configuration and reload nginx:

$ sudo nginx -t # this is to test our configuration
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo service nginx reload # this is to reload nginx

We just need to tell the firewall to let us through

$ sudo ufw allow 'Nginx Full'
Rule added
Rule added (v6)

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

$ sudo ufw status # just to verify
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6)

Run fathom server and go to < ipv4 address > in your browser:

Welcome screen of a new Fathom instance

Hallelujah, hallelujah, hallelujah, ~Handel’s Messiah

4.5.2 Creating a system service

Before you go on and get your tracking code and show all your friends, family, pets the feat you just achieved, we really should tackle two remaining issues, and we will deal with the first in this part.

If your server goes down for any reason, is restarted, etc., your Fathom instance will not be restarted. And let’s be honest, leaving a terminal open with an open SSH connection to your Droplet with a fathom server active is not very practical. This is precisely what system services are for.

Following the isntructions from Automatically starting Fathom on boot will get the job done.

  • Creating the service
$ sudo nano /etc/systemd/system/tracking.example.com.service

and copy-paste

Description=Starts the fathom server
ExecStart=/usr/local/bin/fathom server
  • Reload the service controller daemon
$ sudo systemctl daemon-reload
  • Enable your service
$ sudo systemctl enable tracking.example.com
Created symlink /etc/systemd/system/multi-user.target.wants/tracking.example.com.service → /etc/systemd/system/tracking.example.com.service.
  • Start your server (forever and ever)
$ sudo systemctl start tracking.example.com

Going back to the browser and refreshing the page after the last command should work, just as if you had had fathom server running in the terminal. It’s now running in the background thanks to the service we just created.

4.5.3 The icing on the cake

Back to my promise: let’s do a grand finish and serve our analytics over a secure HTTPS connection. To endow our Fathom instance with an SSL certificate, we need to install certbot (Interactive Installation Guide). In our setup, we should do the following:

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx

Make sure that your DNS is properly configured to point an A record to the < ipv4 address > of your Droplet, before executing the following step.

Once that’s done, we can issue a certificate for our Fathom instance.

$ sudo certbot --nginx -d tracking.example.com

5. Using your Fathom instance

You can now go to your Fathom instance in the browser and fill in the name of your site.

tracking id

You now obtained your tracking snippet.

If, in the previous step, you added a Fathom user and had to log in, you would see a slightly different dashboard, with the ability to manage several sites:

managing several websites

Note: The cog is only visible if you are logged in.

The joys of tracking your website’s traffic is about to start: insert the snippet you obtained at the previous step or copy paste this one by adding the relevant information in < domain > and < SITETRACKINGID >.

You would usually insert this in the head tag of your HTML pages, or you could use react-helmet if your site is powered by React.

<!-- Fathom - simple website analytics - https://github.com/usefathom/fathom -->
  ;(function (f, a, t, h, o, m) {
    a[h] =
      a[h] ||
      function () {
        ;(a[h].q = a[h].q || []).push(arguments)
    ;(o = f.createElement('script')), (m = f.getElementsByTagName('script')[0])
    o.async = 1
    o.src = t
    o.id = 'fathom-script'
    m.parentNode.insertBefore(o, m)
  })(document, window, '//< domain >/tracker.js', 'fathom')
  fathom('set', 'siteId', '< SITE_TRACKING_ID >')
<!-- / Fathom -->

Happy tracking!!

Result and future improvements

I did not make my dashboard private (for people from the future: I might have changed my mind, apologies if that’s the case) and you can look at my impressive statistics at https://tracking.robincussol.com/

You can see that currently there are several root endpoints /, and they correspond to my local dev environment, my Netlify deployments and my real website. I might erase the stats and start afresh once I disable the tracking snippet in these different unwanted contexts.

Finally, in case my Droplet ever goes down and my data is lost (sure, I could set up some backup of my Droplet through Digital Ocean, but what’s the fun in that?), I would like to create a cron job that would send me the stats of the day to my email, and maybe backup the database to some other location.

That’s it for now, thank you for reading this very far. You will find below the resources mentioned in this article and that helped me to get up and running with Fathom. Stay tuned for more.


Join Robin's Gazette


every second Sunday

my favourite links and findings

on frontend technologies, writing and more!

52 issues and counting since December, 2020

    I hate spam, don't expect any from me. Unsubscribe at any time.

    Personal blog written by Robin Cussol
    I like math and I like code. Oh, and writing too.