How to host your personal google analytics alternative.
An open source, privacy-focused alternative to Google Analytics. It has nice ui and packs enough features that you can throw away other solutions until your app grows.
With fly, you can host your umami server and database on the same hosting, for free. Spinning a database there is trivial, and you can connect it to your app easily. The chance is you also use fly for other projects, you will then be able to leverage their networking too in that case (I encourage you to use fly by the way, it is awesome).
Let's take a quick peek before going through with deployment, it may not be a solution for you. Tldr; if you want to track personal projects, umami is the way to go in my opinion. Do not bloat your projects with Google Analytics or pay for other solutions.
Umami requires a backing database to store analytics data, if you have one, you can skip first step of the tutorial. This tutorial uses the fly cli. Make sure it is set up with your account. I'm also using the fly
command, a symlink to flyctl
that should be available by default, if not, use the original command instead.
We will create a new development instance of postgres on fly. The cli will ask you for an instance type, if you need a production ready setup, feel free to choose a higher tier. Also, in 2022, fly creates new postgres clusters using fly machines. This will not affect your deployment, but make sure your cli is updated to not create them in an old way.
To create a new database, run:
fly pg create
You will be asked for app name, then for its type. For umami, development instance is great. App name must be unique globally or it will fail, I like prefixing my apps with my account name.
You can create new app by calling flyctl launch
, but we do not need that bootstrap process. It will just complicate everything. So first, we will create your umami app:
fly apps create your-umami-app-name
This allocates your new app on the fly platform. The case is the same as with database, name must be unique. Now you can attach postgres database to the app. This will provision a new user and database inside the previously created postgres instance. Postgres will be also made visible in the app internal network.
Attaching is done through the following command:
fly pg attach --app your-umami-app-name your-pg-app-name
The command returns a database connection string that you can store as env variable inside your umami app. You do anything if you deployed the database to fly, attaching the app to the database creates a DATABASE_URL
fly secret int the app with the connection string automatically.
If for some reason you need to set that secret anyway, run:
# Do not forget to wrap connection string with quotes, or the command will fail
fly secrets set -a your-umami-app-name DATABASE_URL="connection_string"
Everything is almost set up. Navigate into a place where your app configuration file will be located. You can for example clone umami from github and store it there, if you will ever need a custom umami build, you can start from there.
First, save the existing app configuration from fly into a file:
fly config save -a your-umami-app-name
This will create a fly.toml
file in the current directory. Open it, and apply two modifications, change application port to 3000
and add a [build]
section with umami docker image. You can find the latest version on ghcr.io.
app = "your-umami-app-name"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
[experimental]
allowed_public_ports = []
auto_rollback = true
[build]
image = "ghcr.io/umami-software/umami:postgresql-v1.39.5"
[[services]]
http_checks = []
internal_port = 3000
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
force_https = true
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"
Save the file and run fly deploy
. The app should apply changes successfully, and after a minute or two, you will be able to use umami at your-umami-app-name.fly.dev
. The container runs init scripts when it starts. It will run database migrations, creating umami tables and admin account: admin
with password umami
.
If you encounter any problems, you can start debugging with fly logs
, maybe the container pull failed or some migration was not applied. If the error is non-trivial, you get more help at the troubleshooting page, umami github or fly forums.