How to Self-Host Umami Analytics with Docker
What Is Umami?
Umami is a simple, fast, privacy-focused web analytics tool. It collects page views, referrers, browser and OS data, and custom events — all without cookies. Umami is fully open source (MIT license), lightweight, and designed as a direct replacement for Google Analytics when you want clean data without the privacy concerns. The dashboard is minimal and loads fast.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 1 GB of RAM minimum
- A domain name (optional, for remote access)
Docker Compose Configuration
Create a docker-compose.yml file:
services:
umami:
image: ghcr.io/umami-software/umami:v3.0.3
container_name: umami
restart: unless-stopped
ports:
- "3000:3000"
environment:
DATABASE_URL: "postgresql://umami:umami@umami-db:5432/umami"
APP_SECRET: "change-me-use-a-random-string-at-least-32-chars" # Generate with: openssl rand -hex 32
depends_on:
umami-db:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/heartbeat || exit 1"]
interval: 5s
timeout: 5s
retries: 5
umami-db:
image: postgres:16-alpine
container_name: umami-db
restart: unless-stopped
environment:
POSTGRES_DB: "umami"
POSTGRES_USER: "umami"
POSTGRES_PASSWORD: "umami" # Change this in production
volumes:
- umami-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U umami"]
interval: 5s
timeout: 5s
retries: 5
volumes:
umami-db-data:
Important: Change APP_SECRET to a random string and POSTGRES_PASSWORD to a strong password. Update the password in DATABASE_URL to match.
Start the stack:
docker compose up -d
Initial Setup
- Open Umami at
http://your-server-ip:3000 - Log in with the default credentials:
admin/umami - Change the password immediately — go to Settings > Profile
- Add a website: go to Settings > Websites > Add website
- Enter your domain and copy the tracking code
- Add the tracking script to your website’s
<head>:
<script defer src="https://your-umami-domain.com/script.js"
data-website-id="your-website-id"></script>
The data-website-id is a UUID generated when you add the site in Umami.
Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
DATABASE_URL | PostgreSQL connection string | Required |
APP_SECRET | Session encryption key (min 32 chars) | Required |
CLIENT_IP_HEADER | Header for real IP behind proxy (e.g., X-Forwarded-For) | Auto-detected |
DISABLE_TELEMETRY | Set to 1 to disable anonymous telemetry | 0 |
DISABLE_UPDATES | Set to 1 to disable update checks | 0 |
TRACKER_SCRIPT_NAME | Rename the tracking script (ad blocker evasion) | script |
COLLECT_API_ENDPOINT | Rename the data collection endpoint | /api/send |
Avoid Ad Blockers
Many ad blockers block umami and script.js by default. Rename the script and endpoint:
environment:
TRACKER_SCRIPT_NAME: "stats"
COLLECT_API_ENDPOINT: "/api/collect"
Your tracking script becomes:
<script defer src="https://your-domain.com/stats.js"
data-website-id="your-id"></script>
Teams and Permissions
Umami supports multiple users with role-based access. Create team members under Settings > Users. Users can be assigned to specific websites — they only see analytics for sites they have access to.
Custom Events
Track button clicks, form submissions, or any user action:
umami.track('signup', { plan: 'premium', source: 'homepage' });
Events appear in the dashboard under the Events tab and can be filtered by custom properties.
Reverse Proxy
Behind Nginx Proxy Manager or Caddy, forward traffic to port 3000. Set CLIENT_IP_HEADER to get accurate visitor IPs:
environment:
CLIENT_IP_HEADER: "X-Forwarded-For"
See Reverse Proxy Setup for the full configuration.
Backup
The PostgreSQL database contains all analytics data. Back it up with pg_dump:
docker exec umami-db pg_dump -U umami umami > umami-backup.sql
Restore:
cat umami-backup.sql | docker exec -i umami-db psql -U umami umami
For automated backups, see Backup Strategy.
Troubleshooting
Dashboard shows zero visitors
Symptom: Tracking script is installed but no data appears.
Fix:
- Open browser developer tools, check the Network tab for requests to
/api/send. If blocked, rename the script (see ad blocker section above) - Verify
data-website-idmatches the UUID in Umami settings - Check that the script URL is correct and accessible
”Invalid database” or connection errors on startup
Symptom: Umami container exits with database connection errors.
Fix: Ensure the PostgreSQL container is healthy before Umami starts. The depends_on with condition: service_healthy handles this. If the database needs extra initialization time on first run, restart:
docker compose restart umami
Cannot log in after upgrade
Symptom: Login fails with correct credentials after updating Umami.
Fix: Database migrations may need to run. Check logs:
docker logs umami
If migration errors appear, the database schema may need manual intervention. Back up first, then recreate:
docker compose down
docker compose up -d
High memory usage
Symptom: Umami container uses excessive RAM on high-traffic sites.
Fix: Umami is a Node.js application. Set memory limits in Docker Compose:
services:
umami:
deploy:
resources:
limits:
memory: 512M
Resource Requirements
- RAM: 200 MB idle, 300-500 MB under moderate traffic
- CPU: Very low. Umami is lightweight even at 100K+ monthly page views.
- Disk: 100 MB for the application. Database grows ~500 MB per million page views.
Frequently Asked Questions
Is Umami free?
The self-hosted version is fully free and open source under the MIT license. Umami also offers a paid cloud-hosted version at cloud.umami.is.
Umami vs Plausible — which should I use?
Both are excellent privacy-friendly analytics tools. Umami is lighter on resources and completely free (MIT license). Plausible has a more polished UI and built-in features like Google Search Console integration and email reports. See Umami vs Plausible for the full comparison.
Does Umami support MySQL?
Umami v2+ only supports PostgreSQL. MySQL support was dropped. Use the PostgreSQL configuration shown above.
Can I track multiple websites with one Umami instance?
Yes. Umami supports multiple websites from a single installation. Add each site in the dashboard and use the unique tracking script for each one. There’s no practical limit on the number of sites.
Does Umami comply with GDPR without a cookie banner?
Yes. Umami doesn’t use cookies, doesn’t collect personal data, and doesn’t track visitors across sites. It’s GDPR-compliant by design, so no cookie consent banner is needed. This is one of its key advantages over Google Analytics.
How does Umami compare to Matomo?
Umami is lightweight and privacy-focused with a minimal footprint. Matomo is a full Google Analytics replacement with heatmaps, session recordings, e-commerce tracking, and tag management. Choose Umami for simple, privacy-first analytics. Choose Matomo when you need enterprise-grade analytics features.
Verdict
Umami is the lightest self-hosted analytics tool you can run. It’s dead simple to set up, uses minimal resources, and gives you clean privacy-friendly data. The MIT license means no restrictions on use. The downsides: fewer built-in features than Plausible (no email reports, no Search Console integration out of the box) and a more basic dashboard. For a single-developer project or personal site, Umami is perfect. For a team or business needing more features, consider Plausible or Matomo.
Related
- Privacy-Friendly Analytics Setup Guide
- GoAccess vs Umami: Self-Hosted Analytics Compared
- GoatCounter vs Umami: Which Analytics to Self-Host?
- Umami vs GoatCounter: Lightweight Analytics Face-Off
- How to Self-Host Plausible
- How to Self-Host Matomo
- Plausible vs Umami
- Umami vs Matomo
- Best Self-Hosted Analytics
- Replace Google Analytics
- Docker Compose Basics
- Reverse Proxy Setup
- Backup Strategy
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments