Adding Umami Analytics to Ghost
Self-hosted, privacy-first stats without Google analytics
I've been experimenting with self-hosted analytics and wanted something lightweight, privacy-friendly, and super easy to run alongside a Ghost instance. I settled on Umami. It's open source and doesn't creep on visitors the way Google Analytics does.
Deploying Umami
On my VPS I spun up Umami with Docker Compose:
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- "6570:3000"
environment:
DATABASE_URL: postgresql://umami:umami@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: "changeme"
depends_on:
- db
db:
image: postgres:14
environment:
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami
POSTGRES_DB: umami
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
After running docker-compose up -d
, Umami is running on port 6570.
Created a new tunnel endpoint on Cloudflare, logged in with the default credentials (admin/umami
) and added a new website.
Adding the Tracking Script to Ghost
In Ghost, the cleanest way is to drop Umami's JS tracking script into the theme:
- Go to Ghost Admin > Settings > Code Injection.
- Under Site Header, paste the snippet:
<script async defer data-website-id="YOUR-UMAMI-SITE-ID" src="https://analytics.mysite.uk/umami.js"></script>
Watching It Work
The script you inject into Ghost runs inside the visitor's browser, and each time someone loads a page it quietly sends a request back to your Umami server. That request includes details such as the page they visited, the type of browser they’re using, their approximate location based on IP, and how long they remained on the site. Umami then takes this stream of requests and groups them into sessions and visitors so you see meaningful trends rather than just raw hit counts. Unlike Google Analytics, it doesn't drop cookies or try to build individual profiles. It just captures the basics and presents them in a clean, privacy-friendly dashboard.