Google Analytics is powerful, but it comes with a cost: your visitors’ privacy. Umami is a self-hosted analytics platform that gives you the insights you need without cookies, fingerprinting, or sending data to third parties. It’s lightweight, GDPR-compliant out of the box, and looks great doing it.

What is Umami?

Umami is an open-source, privacy-focused web analytics tool built with Next.js and PostgreSQL (or MySQL). It tracks page views, referrers, devices, and more — all without cookies or personal data collection. The dashboard is clean, fast, and does exactly what you need without the bloat of Google Analytics.

Why Replace Google Analytics?

  • No cookies: Umami doesn’t use cookies, so no annoying consent banners
  • GDPR/CCPA compliant: No personal data collection by default
  • Lightweight script: The tracking script is under 2KB — won’t slow down your site
  • Own your data: Everything stays on your server
  • No data sampling: Google Analytics free tier samples heavy-traffic sites; Umami doesn’t
  • Simple UI: See what matters without drowning in 200 reports you’ll never read
  • Unlimited websites: Track as many sites as you want, no per-site pricing

Prerequisites

Before starting, you’ll need:

  • A Linux server (Ubuntu 22.04+ or Debian 12+ recommended)
  • Docker and Docker Compose installed
  • A domain name (optional but recommended)
  • A reverse proxy like Nginx Proxy Manager or Traefik (for HTTPS)
  • Basic terminal knowledge

Step 1: Create the Project Directory

mkdir -p ~/umami && cd ~/umami

Step 2: Create the Docker Compose File

Create docker-compose.yml:

version: '3'
services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://umami:your-secure-password@db:5432/umami
      DATABASE_TYPE: postgresql
      APP_SECRET: replace-me-with-a-random-string
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: your-secure-password
    volumes:
      - umami-db:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U umami"]
      interval: 5s
      timeout: 5s
      retries: 5

volumes:
  umami-db:

Important: Replace your-secure-password with a strong password (both places) and set APP_SECRET to a random string. Generate one with:

openssl rand -base64 32

Step 3: Start Umami

docker compose up -d

Umami takes about 30 seconds on first start to initialize the database. Check progress with:

docker compose logs -f umami

Look for Listening on http://0.0.0.0:3000 to confirm it’s ready.

Step 4: Log In and Change the Default Password

Open http://your-server-ip:3000 in your browser.

Default credentials:

  • Username: admin
  • Password: umami

Change this immediately. Go to Settings → Profile and update your password.

Step 5: Add Your First Website

  1. Go to Settings → Websites
  2. Click Add website
  3. Enter your site name and domain (e.g., selfhostsetup.com)
  4. Click Save
  5. Click the Edit icon next to your new site
  6. Copy the Tracking code — it looks like this:
<script async src="https://your-umami-domain.com/script.js" data-website-id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"></script>

Step 6: Add the Tracking Script to Your Site

Paste the tracking code into the <head> section of your website. Where exactly depends on your setup:

Hugo (PaperMod or similar):

Add to layouts/partials/extend_head.html:

<script async src="https://analytics.yourdomain.com/script.js" data-website-id="your-website-id"></script>

WordPress:

Use a plugin like “Insert Headers and Footers” or add it to your theme’s header.php.

Plain HTML:

Just paste it before </head> in every page.

You’ll want HTTPS for the tracking script to work on HTTPS sites. If you’re using Nginx Proxy Manager:

  1. Add a new proxy host
  2. Set the domain (e.g., analytics.yourdomain.com)
  3. Forward to your-server-ip:3000
  4. Enable SSL with Let’s Encrypt
  5. Turn on Websockets Support

If you’re using Traefik or raw Nginx, point your subdomain to port 3000 with SSL termination.

Step 8: Verify It’s Working

Visit your website in a browser, then check the Umami dashboard. You should see your visit appear in real-time within a few seconds. If not:

  • Check browser console for script loading errors
  • Verify the domain in Umami settings matches your actual domain
  • Make sure your ad blocker isn’t blocking the script (see tips below)

Avoiding Ad Blockers

Some ad blockers flag script.js from analytics subdomains. Umami has a built-in solution:

Rename the tracking script by setting the TRACKER_SCRIPT_NAME environment variable:

environment:
  TRACKER_SCRIPT_NAME: custom-name

Then update your tracking code to reference /custom-name.js instead of /script.js.

Proxy through your own domain by adding a rewrite rule in your web server that forwards /stats.js to your Umami instance. This makes the script appear to come from your own domain.

Understanding the Dashboard

Umami’s dashboard gives you:

  • Page views and visitors: Real-time and historical
  • Referrers: Where your traffic comes from
  • Browsers and OS: What your visitors use
  • Devices: Desktop, mobile, tablet breakdown
  • Countries: Geographic distribution
  • Events: Custom event tracking (button clicks, form submissions)
  • UTM parameters: Campaign tracking support

All of this without a single cookie.

Custom Event Tracking

Track button clicks, form submissions, or any interaction:

// Track a button click
document.getElementById('signup-btn').addEventListener('click', () => {
  umami.track('signup-click');
});

// Track with custom data
umami.track('purchase', { product: 'pro-plan', price: 29 });

Events show up in the dashboard under the Events tab for each website.

Multiple Users and Teams

Umami supports multiple user accounts with different permission levels:

  1. Go to Settings → Users
  2. Click Add user
  3. Set their role (Admin or Viewer)

Viewers can see dashboards but can’t modify settings. Useful for sharing analytics with clients or team members without giving them admin access.

Backup Strategy

Your analytics data lives in the PostgreSQL volume. Back it up regularly:

# Dump the database
docker exec umami-db-1 pg_dump -U umami umami > umami-backup-$(date +%Y%m%d).sql

# Restore if needed
cat umami-backup.sql | docker exec -i umami-db-1 psql -U umami umami

Add this to a cron job for automated backups:

0 3 * * * docker exec umami-db-1 pg_dump -U umami umami > /backups/umami-$(date +\%Y\%m\%d).sql

Updating Umami

cd ~/umami
docker compose pull
docker compose up -d

Umami handles database migrations automatically on startup.

Troubleshooting

Dashboard shows no data:

  • Verify the tracking script is loading (check browser Network tab)
  • Confirm the data-website-id matches what’s in Umami settings
  • Check that the domain in Umami matches your site’s actual domain

Script blocked by ad blocker:

  • Rename the tracker script via environment variable
  • Proxy the script through your own domain

High memory usage:

  • PostgreSQL defaults can be tuned for smaller servers
  • Add shm_size: 256mb to the db service if you see shared memory errors

Container won’t start:

  • Check logs: docker compose logs umami
  • Most common issue: database password mismatch between services

Umami vs Alternatives

FeatureUmamiPlausibleMatomo
Cookie-freeOptional
Script size~2KB~1KB~22KB
Self-host difficultyEasyEasyModerate
Resource usageLowLowHigh
Custom events
Ecommerce trackingBasicBasicAdvanced
UI complexitySimpleSimpleComplex

Umami hits the sweet spot for most self-hosters: simple enough to set up in 10 minutes, powerful enough for real analytics, and light enough to run on a Raspberry Pi.

Conclusion

Umami gives you everything most websites actually need from analytics — page views, referrers, device stats, and custom events — without the privacy baggage of Google Analytics. It’s a 10-minute Docker deploy that respects your visitors and keeps your data where it belongs: on your server.

If you’re running a blog, SaaS landing page, or documentation site, Umami is probably all the analytics you need. And if you ever outgrow it, your data is in PostgreSQL — easy to export, easy to migrate.