GoatCounter self-hosted setup on a VPS


GoatCounter is a lightweight, privacy-friendly, open-source analytics server. I wanted to self-host it, couldn’t find a good guide on how to do it from scratch on a fresh VPS, and decided to write this up after some trial and error.

Other guides which may be useful if something here doesn’t work:

VPS setup

Create a new VPS…

…or use an existing one, GoatCounter just needs free ports 80 and 443 (if you want to run it behind a reverse proxy on another port, you can, but you’ll have to adjust the setup script a bit). For this guide, I’m using Arch Linux on Linode, but any systemd-based Linux distro should work.

Basic distro setup

Add your SSH key (on Linode, you can do this even before creating the VPS) and disable password authentication. If you want to deal with a firewall, this would be a good time to also set it up.

The setup script below will create a goatcounter user automatically and run GoatCounter under it. It could be hardened a bit further with chroot (RootDirectory=... option in systemd) and path whitelisting, but there are some issues with it and this is “secure enough” for most uses (just make sure you don’t give read access for all users to anything interesting on the VPS).

Domain setup

GoatCounter seems to expect that you have a domain you can use for it. I didn’t try using the VPS IP directly, nor would I recommend it. So, setup a DNS entry for your VPS, and enter the domain in the next step.

GoatCounter installation & setup

I wrote an automated script that downloads the latest GoatCounter version and sets everything up:


It supports installing, upgrading and uninstalling GoatCounter. The script should be ran as root (it creates a new service user and sets up a systemd service). The script was tested on the latest Arch Linux and Ubuntu 22.04, but it should work on any reasonably recent distro, as long as it uses systemd and has curl installed. Either upload it to the VPS, chmod +x and run, or enter the following commands in your shell:

# download the script
curl --location --output ~/goatcounter_setup.sh https://actually.fyi/posts/goatcounter-vps/goatcounter_setup.sh
chmod +x ~/goatcounter_setup.sh
# install goatcounter
sudo ~/goatcounter_setup.sh

In case something fails, it should be safe to rerun the script again (but it will reset any existing GoatCounter configuration). There are some configuration options at the top of the script, you may want to modify these before running it (but the defaults should be OK).

After the script finishes (it will prompt you for domain, e-mail and password), GoatCounter should be up and running. If all goes well, it will retrieve a Let’s Encrypt TLS certificate on its own, otherwise it will hopefully print an error and tell you what to fix.

Try to connect to it over HTTPS (use the domain you entered earlier) and log in using the entered credentials (e-mail and password). If you are able to successfully authenticate, add the client JS script tag to your website, test that it correctly records the visit and you should be done.

To upgrade an existing GoatCounter installation, run ./goatcounter_setup.sh upgrade. To uninstall, run ./goatcounter_setup.sh uninstall.

If something in the script doesn’t work for you, send me an e-mail at nulya@actually.fyi, hopefully I’ll find some time to figure it out.