Skip to content
Souloss
Go back

Setup Umami Analytics: Free Vercel Deployment

A step-by-step guide to deploy Umami analytics for free using Vercel + Neon PostgreSQL and integrate with your astro-minimax blog.

Umami is an open-source, privacy-friendly web analytics tool. Compared to Google Analytics, Umami doesn’t use cookies, doesn’t track users across sites, and is fully GDPR compliant. This guide will show you how to deploy Umami for free using Vercel + Neon PostgreSQL and integrate it with your astro-minimax blog.

Why Choose Umami

FeatureUmamiGoogle Analytics
Privacy-friendlyFully GDPR compliantRequires cookie consent
Self-hostedSupportedNot supported
Data ownershipFull controlGoogle holds data
Cookie usageNoneRequired
Page size impactMinimal (< 2KB)Larger
Open sourceMIT licenseClosed source

Deployment Options Comparison

OptionCostAdvantagesDisadvantages
Vercel + Neon (Recommended)FreeZero ops, one-click deploy, auto updatesVercel free tier limits
Self-hosted DockerFreeFull control, unlimitedRequires server, self-maintenance
Umami CloudPaidNo ops, auto updatesFrom $9/month

Recommended: Vercel + Neon - Completely free, no server needed, simple deployment, suitable for personal blogs and small websites.


Host Umami on Vercel with Neon PostgreSQL database from Vercel Storage for zero-cost deployment.

Prerequisites

Step 1: Fork Umami Repository

  1. Visit Umami GitHub Repository
  2. Click Fork button in the top right to fork the repository to your account

Step 2: Deploy Umami on Vercel

  1. Login to Vercel Dashboard
  2. Click Add NewProject
  3. Select your forked umami repository
  4. Configure the project:
    • Framework Preset: Select Next.js
    • Environment Variables: Skip for now, configure later
  5. Click Deploy to start deployment

First deployment may fail (missing database connection). This is normal - redeploy after configuring the database in the next step.

Step 3: Create Neon PostgreSQL Database

  1. In Vercel Dashboard, go to your Umami project
  2. Click Storage tab at the top
  3. Click Create Database
  4. Select Neon PostgreSQL as database type
  5. Login to Neon account to authorize (if not linked)
  6. Configure the database:
    • Project Name: e.g., umami-analytics
    • Database Name: Recommended umami
    • Region: Choose closest to your users
  7. Click Create to create the database

Once created, Vercel will automatically inject the DATABASE_URL environment variable into the project.

Step 4: Redeploy

  1. Go to Deployments tab
  2. Select the latest deployment
  3. Click Redeploy to redeploy
  4. Wait for deployment to complete (~1-2 minutes)

DATABASE_URL is the only required environment variable. APP_SECRET (for session encryption) is now optional - Umami will auto-generate it.

Step 5: Initialize Umami

  1. After successful deployment, click Visit to access your Umami instance
  2. First login with default credentials:
    • Username: admin
    • Password: umami
  3. Change default password immediately: Click avatar in top right → ProfileChange Password

Step 6: Bind Custom Domain (Optional)

  1. Project → SettingsDomains
  2. Enter your domain, e.g., umami.yourdomain.com
  3. Add CNAME record in your DNS pointing to cname.vercel-dns.com
  4. Wait for DNS propagation

Option B: Self-Hosted Docker Deployment

If you have server resources and want full control over data, use Docker for self-hosted deployment.

Quick Deploy

Create docker-compose.yml file:

DATABASE_URL is the only required environment variable. APP_SECRET (for session encryption) is optional - Umami will auto-generate it.

Start the service:

docker compose up -d
bash

Service will start at http://localhost:3001. Default admin credentials:

Change default password immediately after first login.

Production Configuration

Reverse Proxy Configuration

Recommended to use Nginx or Caddy as reverse proxy with HTTPS:

Nginx Example:

server {
    listen 443 ssl http2;
    server_name umami.your-domain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
nginx

Caddy Example (Simpler):

umami.your-domain.com {
    reverse_proxy localhost:3001
}
plaintext

Caddy automatically requests and renews HTTPS certificates.

Environment Variables

VariableRequiredDescription
DATABASE_URLYesPostgreSQL connection string
APP_SECRETNoSession encryption, auto-generated
TRACKER_SCRIPT_NAMENoTracker script filename, default script.js
DISABLE_TELEMETRYNoDisable telemetry, set to 1
REMOVE_TRAILING_SLASHNoRemove trailing slash from URLs, set to 1

PostgreSQL Optimization

For production, adjust PostgreSQL configuration:

db:
  image: postgres:15-alpine
  environment:
    POSTGRES_DB: umami
    POSTGRES_USER: umami
    POSTGRES_PASSWORD: your-secure-password-here
  volumes:
    - umami-db-data:/var/lib/postgresql/data
  command: postgres -c shared_buffers=256MB -c max_connections=200
yaml

Data Backup

Backup PostgreSQL data regularly:

# Backup
docker exec umami-db pg_dump -U umami umami > umami_backup_$(date +%Y%m%d).sql

# Restore
cat umami_backup_20260318.sql | docker exec -i umami-db psql -U umami umami
bash

Option C: Umami Cloud

If you don’t want to manage operations, use Umami Cloud hosted service.

Pricing

PlanMonthlyWebsitesPageviews
Pro$910100,000/month
Business$1925500,000/month
EnterpriseCustomUnlimitedCustom

Usage Steps

  1. Register for Umami Cloud account
  2. Login and go to Dashboard
  3. Click Add website to add your website
  4. Get websiteId and script URL

Get Website ID

Regardless of which option you use, you need to get the websiteId for blog integration.

Steps

  1. Login to Umami dashboard
  2. Click SettingsWebsites in top right
  3. Click Add website to add your site:
    • Name: Your blog name
    • Domain: Your blog domain (e.g., blog.example.com)
  4. After adding, click the website name to view details
  5. In Tracking code section you’ll see:
    • data-website-id: This is your websiteId
    • Script URL: e.g., https://your-umami-instance/script.js

Example tracking code:

<script async src="https://umami.example.com/script.js" data-website-id="1419a8ae-a14b-4bb7-8c39-ee5fe00a8a88"></script>
html

Extract from the code above:


Integrate with Blog

Configure Umami in src/config.ts:

umami: {
  enabled: true,
  websiteId: "1419a8ae-a14b-4bb7-8c39-ee5fe00a8a88",
  src: "https://umami.example.com/script.js",
},
js
OptionDescription
enabledEnable analytics. Script auto-injected when true
websiteIdWebsite ID from Umami dashboard
srcUmami tracker script URL. Use your domain for self-hosted, https://cloud.umami.is/script.js for cloud

After configuration, rebuild and deploy your blog:

pnpm run build
bash

Verify Integration

After deployment, open browser developer tools:

  1. Check Network tab for requests to your Umami service
  2. Check Realtime page in Umami dashboard to confirm visit records

Environment Variables Reference

If you don’t want to commit websiteId to the repository, use environment variables:

Method 1: Build-time Environment Variables

Add in your deployment platform’s build configuration:

UMAMI_WEBSITE_ID=your-website-id
UMAMI_SRC=https://umami.example.com/script.js
bash

Modify src/config.ts:

umami: {
  enabled: true,
  websiteId: import.meta.env.UMAMI_WEBSITE_ID || "your-website-id",
  src: import.meta.env.UMAMI_SRC || "https://umami.example.com/script.js",
},
js

Method 2: Use .env File

Create .env file (add to .gitignore):

UMAMI_WEBSITE_ID=your-website-id
UMAMI_SRC=https://umami.example.com/script.js
bash

Privacy Compliance

Umami was designed with privacy compliance in mind:

GDPR Compliance

Privacy Policy Suggestion

Declare Umami usage in your privacy policy:

This website uses Umami for analytics. Umami does not use cookies, does not track personal information, and all data is used solely to improve website experience.

User Opt-out

Umami supports user opt-out from tracking. Add an opt-out link:

<a href="#" data-umami-track="false">Opt out of tracking</a>
html

Or via JavaScript:

window.umami.trackView = false;
js

Troubleshooting

Statistics Not Displaying

  1. Check script loading: In browser developer tools Network tab, confirm script.js loads successfully
  2. Check domain configuration: Ensure domain in Umami matches actual blog domain
  3. Check CSP policy: If using Content Security Policy, allow Umami script domain

Vercel Deployment Failed

  1. Check environment variables: Confirm DATABASE_URL and APP_SECRET are correctly configured
  2. Check database status: In Vercel Storage, confirm Neon database is created
  3. View build logs: Check Deployments page for detailed error messages

Neon Database Connection Issues

  1. Database suspended: Neon free tier suspends after idle, first access needs wake-up (~5-10 seconds)
  2. SSL connection: Neon requires SSL, ensure connection string includes ?sslmode=require
  3. Connection timeout: Check region settings, choose closest region for lower latency

Docker Self-hosted Won’t Start

  1. Check database connection: Ensure PostgreSQL container is running
  2. Check logs: Run docker logs umami to view error messages
  3. Check port: Ensure port 3001 is not occupied

CORS Issues

If Umami and blog are on different domains, configure CORS:

Vercel deployment: Add environment variable:

CORS_ALLOWED_ORIGINS=https://your-blog-domain.com
plaintext

Docker deployment: Add to docker-compose.yml:

environment:
  # ... other config
  CORS_ALLOWED_ORIGINS: https://your-blog-domain.com
yaml

Inaccurate Statistics

Umami uses fingerprinting to identify users. These situations may cause statistical bias:


Next Steps

After configuring Umami:

For more Umami features, refer to Umami Documentation.



Previous Post
How to Use Git Hooks to Auto-Set Post Dates
Next Post
Deploy Waline Comment System on Vercel

评论区

文明评论,共建和谐社区