For my personal website (yes, this one), I wanted to get analytics of visits, pages visited etc., in a simple and privacy-conscious way. Oh yeah, and I also wanted it to be free, atleast for the number of views I get.

Google analytics, the most commonly used, was ruled out under the privacy-conscious rule 1. After searching for quite a bit, I narrowed down to Panelbear, which provides analytics without cookies and respects the privacy of visitors. I used Panelbear for a few months - it is quite nice. So if you want something simple, free, and privacy-friendly, go with Panelbear.

Panelbear does have one inherent limitation. Although it is free for small websites, it only retains your visit data for 30 days. So after that, your data is lost, unless you pay for one of their plans. I wanted more control, so I started looking for some open-source solutions that I could preferentially self-host. That is when I hit upon umami.

Umami is quite similar to panelbear - it checks all the criteria. You can even self-host it using Heroku’s free tier plan. The steps are well-documented in the docs of umami so I mostly just followed them. The documentation can be found here. Some of the steps were tricky/inconvenient, so I made some slight modifications to the steps. Here they are, in case you (or the future me) decides to set up umami (again):

1. Create an account in Heroku and create an app.

2. Create a database. Umami requires a database in which it can log visits. You can create that in Heroku (for free!). Go to the resources page and instal thel Heroku Postgres addon.

3. Fork the Umami Github repository.

4. Next, instead of connecting to Github (Heroku required permissions to all my repositories), I used Heroku-cli. I created a repository in Heroku, cloned in onto my computer,and added the Github fork as my upstream master. That way, I could now pull from the Github repository and push it onto Heroku.

git remote add upstream #your git url
git remote -v  			#check if it is added
git fetch upstream git merge upstream/master 	#merge with the github repository version
git push heroku master		#send the merged repository to the heroku remote

5. Now, if you had pushed the forked umami repo into heroku, added the hash salt (in the docs) and deployed, you should have been able to access the login page of umami. But when you try to login using the default username and password (mentioned here), it will give an error. That is because the database has not yet been initialised and the default username and password has not yet been added into it.

6. Now come the tricky few steps - first, setting up the database. Start by opening up the Heroku postgres database and going to settings. Click view database credentials and copy the host, database, username, and password into a temporary text file.

7. Now install the necessary packages that are needed to build the umami cloned repository in your computer. It requires nodejs and I used postgresql along with it (in arch linux, you can use pacman).

8. Go to the cloned repository and run:

npm install

9. It is finally time to initiate the database. Use the copied database credentials and run the following command. This will create the login and the password for your umami instance.

psql -h hostname -U username -d databasename -f sql/schema.postgresql.sql

10. To test if it works properly, add a .env file in the folder with a database url and a hash salt (details here). I used a 32-character random string for the hash salt (used a password generator for this).

DATABASE_URL=postgresql://username:mypassword@localhost:5432/mydb
HASH_SALT=random string

11. Now you can build, start and check if the local umami instance is using the database properly (i.e. if you are able to log in), using the following commands

npm run build
npm start

12. If you are able to log into the local umami instance, then you are done. Commit the changes (.env file) and push it into Heroku (it should be automatically deployed). Now you should be able to log in, change password and get cracking2.

Footnotes

1. Not really sure why? There are several articles on this - maybe start with this one?

2. Ideally the DATABASE_URL should automatically be added to your app->settings->reveal config vars. If not, add the same DATABASE_URL as in your .env file (from above).