Self-host · ghcr.io/spcaeo/skald
Self-host Skald free: self-hosted web analytics on your own server
Self-hosted web analytics with Skald is one Docker image, one disk and your server's log. Every figure stays on a machine you run.
Self-hosted web analytics is analytics you run on your own server, so the visits, the history and the accounts never leave it. Skald is source-available under the Elastic License 2.0 and free to self-host, for your own sites or your clients' sites. It reads your server's access log and sorts every line into five groups: server log analytics.
Free to self-host · Elastic License 2.0 · or let us host it: 30-day free trial, no card
- Daily run · ran at 07:15, no failureOK
- Days stored · none of the last 14 missingOK
- Access log · /logs/access.log, written 1 min agoOK
- Page assets · a browser fetched /_next/static/OK
- Mail · no SMTP server setOFF
- Disk · 31.4 GB free where the history livesOK
Sample output. The doctor says what works and, for anything that does not, the fix in plain words.
[01] where it runs
Where to self-host your web analytics
Skald is a long-running program with a disk. It needs one machine or one container that stays up. Any of these works, and they all run the same image.
pick a place
Docker on a small Linux server
Any small server with Ubuntu 24.04 or Debian 12 works. One vCPU and 1 GB of memory is enough for most sites. Docker Compose can bring its own Caddy, which gets the HTTPS certificate by itself.
When your site runs on the same server, Skald reads its access log in place, mounted read-only. Nothing else to set up.
A plain Ubuntu or Debian server
No Docker: the install script puts Skald beside the nginx you already have, as its own system user with systemd and cron. It pins a release you can check against its published SHA256SUMS file.
Skald then lives under /traffic/ on your site's own name, or on a stats. name you add.
Railway: the image as a service
Deploy the Docker image, add a volume at /var/lib/skald, set a few variables and generate a domain. Railway does not publish its proxies' addresses, so you find them once with one command.
Render: one Blueprint
The Blueprint makes the web service, a 5 GB disk and the settings, and asks for the ones it cannot guess. A disk needs a paid instance type: a free instance loses the history at every restart.
Fly.io: one Machine, one volume
The repository's fly.toml is ready to edit. It keeps the Machine running, because a stopped Machine misses Skald's schedule, and it already reads the visitor's address from Fly's own header.
Your own PaaS on your own server
Coolify, CapRover and Dokku run the image with persistent storage and give it HTTPS. When the site runs on the same server, its log can be mounted read-only, as with plain Docker.
Kubernetes: one replica, always
A minimal example: a 5 GiB volume claim, a Deployment with one replica and the Recreate strategy, and a Service. Add an Ingress with your own controller and certificate manager.
[02] what it needs
What every self-hosted install needs
The same short list on every platform. Get these right and the rest is the platform's own buttons.
Skald needs to see your site's requests. On the same server it reads the log in place. When the site runs somewhere else, one command on that server sends its log, or a Cloudflare Worker or a Vercel log drain does it for you.
| Part | What Skald needs |
|---|---|
| Image | ghcr.io/spcaeo/skald, or build docker/Dockerfile |
| Port | 8080; the dashboard is at /traffic/ |
| Disk | a persistent volume at /var/lib/skald. Lose it and you lose everything |
| Copies | exactly one. Never scale out, never two on one volume |
| HTTPS | required for sign-in: the session cookie is Secure |
| Health check | GET /traffic-auth/login answers 200 |
| First owner | skald accounts init inside the container prints a link to set the password |
[03] running it
Self-hosted analytics that looks after itself
Skald runs its own schedule: the live figures every 2 minutes, the daily run and a nightly backup. You check it with one command and upgrade it with another.
Backups tested by restoring
Every night a copy of the history, and a weekly one. Each copy is restored into a scratch file and checked, table by table, before it counts as a backup.
The doctor
skald doctorprints one line per part: runs, missing days, the log, hooks, the tag, mail, version and disk. Each line is OK, NEEDS ATTENTION or OFF, with the fix.Fill the past days
skald backfill --days 14stores each day your log's rotations still hold, so the dashboard does not start empty.Upgrades with a way back
Docker: pull the new image, pin
:2to get every 2.x release and never a breaking one. The install script:skald upgradebacks up, checks health and rolls back if a check fails.Told when a release is out
Owners and admins see a line in the dashboard and the daily mail when a newer Skald is out, drawn in red for a security release. Automatic upgrades are off by default.
Many sites, one install
Each site keeps its own settings, page assets, visitor IDs and logo. Add or remove sites from the dashboard.
Python standard library only · SQLite files · no build step · 2,500+ tests against hand-built logs
What it does not do
- It does not run on Vercel, Netlify or Cloudflare Workers functions: they stop between requests and keep no disk. It can measure a site there from a server of its own.
- It does not scale out. One copy, one disk: the history is SQLite.
- A free tier with no persistent disk, or one that stops the app when idle, loses the history and misses the schedule.
- Without a server or CDN log (Shopify, Webflow, Squarespace, or the script tag alone) it sees no AI crawlers and no bots: they never run a script.
[04] licence
Source-available, and free to self-host
Skald is source-available under the Elastic License 2.0. Read it, change it and run it for your own sites or your clients' sites, including at work.
One limit: offering Skald itself to others as a hosted or managed service needs a commercial licence. Because of that limit it is not an OSI-approved licence, so we call it source-available.
- Run it for your own sitesfree
- Run it for your clients' sitesfree
- Read and change the codefree
- Offer Skald to others as a hosted servicecommercial licence
A summary, not the licence. The licence text on GitHub is what counts.
in this section
Pick where Skald runs
keep reading
More on self-hosted web analytics
questions
Self-hosted web analytics FAQ
Straight answers, including what Skald does not do.
Is Skald free to self-host?
Yes. Skald is source-available under the Elastic License 2.0. You may run it on your own server for your own sites or your clients' sites, including at work, at no cost. Offering Skald itself to others as a hosted or managed service needs a commercial licence: contact us.
What licence is Skald under?
The Elastic License 2.0. It is source-available: you can read, change and run the code for your own sites and your clients' sites. Its one limit is on offering Skald itself to others as a hosted service. Because of that limit it is not an OSI-approved licence, so we call Skald source-available.
What does a self-hosted Skald need?
One machine or one container that stays up, with a persistent disk for the history. The image is ghcr.io/spcaeo/skald, it listens on port 8080, and sign-in needs HTTPS in front. One small Linux server with one vCPU and 1 GB of memory is enough for most sites. Run exactly one copy: the history is SQLite on one disk.
Can Skald run on Vercel, Netlify or Cloudflare Workers?
No. Skald keeps its history on a disk and runs its own schedule, and those platforms stop between requests and keep no disk. Skald can still measure a site hosted there: run Skald on a small server or a platform such as Render or Fly.io, and let the site's host send its log. Vercel log analytics.
How do I upgrade a self-hosted Skald?
With Docker, pull the new image and start the container again: the volume keeps every figure, and the databases are brought up to date when it starts. Pin the :2 tag to get every 2.x release and never a breaking one. On a server installed with install.sh, skald upgrade takes a tested backup, checks health and rolls back by itself if a check fails.
Does a self-hosted Skald send my data anywhere?
Counting needs no outside service: the log is read on your server and the history stays on your disk. Once a day Skald fetches the address lists crawler owners publish, and asks GitHub whether a newer release is out, with only its version number in the request (you can turn that off). Integrations you switch on, such as Search Console or AI answers, talk to those services.
$ tail -f access.log | skald
Run it yourself, or let us run it for you.
Self-hosting is free. Hosted Skald is 30 days free, no card, set up for you within one working day.