Self-host · Fly.io
Self-hosted analytics on Fly.io, one Machine and one volume
Self-hosted analytics on Fly.io is one Machine running the Skald image, with a volume for its history. The repository's fly.toml is ready to edit and already reads each visitor's address.
Self-hosted analytics on Fly.io means running Skald's Docker image on one Fly Machine with a volume mounted at /var/lib/skald. Fly gives it HTTPS and keeps the Machine running; Skald keeps the history on the volume and takes your sites' logs by HTTPS. One of the ways to self-host Skald free.
30-day free trial · no card · we set it up within one working day · free to self-host
- app skald-exampleyour name
- image ghcr.io/spcaeo/skald:latestsource
- mount skald_data → /var/lib/skaldhistory
- auto_stop_machines offalways on
- SKALD_REAL_IP_HEADER Fly-Client-IPvisitor's address
- address https://skald-example.fly.devHTTPS
Sample values from the repository's fly.toml. Change the app name and the SKALD_* values to your own.
[01] deploy
Deploy Skald on Fly.io with three commands
Install flyctl and sign in. Edit deploy/fly.toml first: app (a name of your own), primary_region and the SKALD_* values under [env].
- Make the volume in the same region as the app: a Machine only mounts a volume in its own region.
- A new Fly volume belongs to root. The container hands it to its own user, 10001, at the first start, and the log says so once.
- Run the commands from the root of your copy of the repository, so
deploy/fly.tomlis found.
fly apps create skald-example
fly volumes create skald_data --size 3 --region fra -a skald-example
fly deploy -c deploy/fly.toml
The app name must match app in fly.toml, and the region must match primary_region.
[02] fly.toml
What the Fly.io config already sets
You change the names. The rest is set for how Skald runs: always on, one Machine, the visitor's address from Fly's own header.
Fly's proxy puts each visitor's address in Fly-Client-IP. private trusts Fly's private networks, where its proxy connects from. Other apps in your own Fly organisation can reach the Machine there too, and could claim an address.
| Setting | Value and why |
|---|---|
auto_stop_machines | "off": a stopped Machine misses Skald's schedule |
min_machines_running | 1 |
internal_port | 8080, with force_https |
| Health check | GET /traffic-auth/login every 30 s, after a 60 s grace period |
| Mount | skald_data at /var/lib/skald, 3 GB to start |
| Machine | 512 MB of memory, 1 CPU |
| Receiving logs | SKALD_INGEST=true, SKALD_LOG_DIR=/var/lib/skald/ingest/example.com |
| Visitor's address | SKALD_TRUSTED_PROXIES=private, SKALD_REAL_IP_HEADER=Fly-Client-IP |
[03] owner and domain
Make the first owner, then add your domain
The app answers at https://<app>.fly.dev as soon as it is deployed. Change the app name, the organisation and the email to your own before you copy.
$ fly ssh console -a skald-example -C "skald accounts init --org 'Example Co' --owner-email owner@example.com"
Prints a link that sets the owner's password.
$ fly certs add stats.example.com -a skald-example
- Add the A and AAAA records, or the CNAME, that it prints at your DNS provider.
- Put
https://stats.example.cominSKALD_BASE_URLin fly.toml. - Run
fly deploy -c deploy/fly.tomlagain.
[04] your site's log
Send your site's visits to Skald on Fly.io
Fly.io has no log of your website, so the site's requests arrive by HTTPS. SKALD_INGEST=true and SKALD_LOG_DIR turn the receiving end on. Then pick where your site runs.
In the dashboard, Settings > Connections > Send this site's visits to Skald fills in the send address and a sending token for you, and ends with Test connection.
One command on the web server
On the site's nginx or Apache server, with or without Docker, one command finds the access log and sends its new lines to this Skald. Skald makes the sending token for you.
curl -fsSL https://<your Skald>/traffic-kit/<code> | sudo bash
A template: your Skald shows the real line. Its link works once, for 24 hours.
The Skald Worker, on any Cloudflare plan
A small Worker passes every request on unchanged and, after the page has gone out, posts one record of it to this Skald. Cached pages are counted too.
A Vercel log drain
Vercel posts every request to this Skald. Log drains need Vercel Pro or Enterprise; on Hobby, only the script tag is left.
The script tag alone
One line in every page's head counts people, their clicks and their forms. It never sees AI crawlers or bots: they do not run scripts.
[05] keeping it
Backups, snapshots and upgrades on Fly.io
The volume holds everything Skald keeps. Keep two kinds of copy: Skald's own, and Fly's snapshots of the whole volume.
Skald's own backups
A nightly and a weekly copy of the history, each restored into a scratch file and checked before it counts.
fly ssh console -a skald-example -C "skald backup"makes one now.Volume snapshots
Skald's copies live on the same volume. Take Fly volume snapshots with
fly volumes snapshotstoo, so a lost volume is not the end of the history.Upgrades
Take a backup, then
fly deploy -c deploy/fly.tomlwith the image you want. The databases are brought up to date at start. Pin:2to get every 2.x release and never a breaking one.
What it does not do on Fly.io
- It does not scale out. A volume belongs to one Machine: never
fly scale count 2. - It does not sleep. With auto-stop on, a stopped Machine misses the schedule and the live figures.
- It has no log of your website on Fly, so the site's log is sent to it. A site with no server or CDN log (the script tag alone) shows no AI crawlers and no bots.
- Trusting
privatealso trusts other apps in your own Fly organisation.
keep reading
More on self-hosted analytics on Fly.io
questions
Self-hosted analytics on Fly.io FAQ
Straight answers, including what Skald does not do.
Why does fly.toml turn auto-stop off for Skald?
Skald runs its own schedule: the live figures every 2 minutes, the daily run and the nightly backup. A stopped Machine misses all of it. So fly.toml sets auto_stop_machines to off and min_machines_running to 1.
Can I run two Fly Machines for Skald?
No. A Fly volume belongs to one Machine, and Skald keeps its history in SQLite on that volume. Never run fly scale count 2.
Does Skald see visitors' real addresses on Fly.io?
Yes. Fly's proxy puts the visitor's address in the Fly-Client-IP header, and fly.toml already tells Skald to trust it from Fly's private networks. Other apps in your own Fly organisation can reach the Machine on those networks too, so keep untrusted apps out of that organisation.
How do I back up Skald on Fly.io?
Skald makes its own nightly and weekly copies on the volume, each one restore-tested. Take Fly volume snapshots as well with fly volumes snapshots, so a lost volume is not the end of the history.
How big a volume does Skald need on Fly.io?
The example creates 3 GB. It holds the history, accounts, settings, backups and the shipped log lines of the last days. skald doctor shows how full it is; Fly volumes can be extended later.
$ tail -f access.log | skald
See what AI does with your site. Free for 30 days.
No card. We set up hosted Skald for you within one working day, or you self-host it free. Every line of your log, sorted and added up.