How to Self-Host Ackee Analytics with Docker

What Is Ackee?

Ackee is a self-hosted, privacy-focused analytics tool that tracks page views, referrers, browsers, and operating systems without cookies. It stores data in MongoDB, exposes a GraphQL API, and provides a clean single-page dashboard. Ackee is designed for developers who want basic traffic metrics without the complexity of Matomo or the cloud dependency of Google Analytics.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 512 MB of free RAM
  • 2 GB of free disk space
  • A domain name (recommended for CORS and HTTPS)

Docker Compose Configuration

Create a docker-compose.yml file:

services:
  ackee:
    image: electerious/ackee:3.5.1
    container_name: ackee
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      ACKEE_MONGODB: "mongodb://mongo:27017/ackee"
      ACKEE_USERNAME: "admin"                        # CHANGE: dashboard login username
      ACKEE_PASSWORD: "change-this-password"         # CHANGE: use a strong password
      ACKEE_ALLOW_ORIGIN: "https://example.com"      # CHANGE: your website's domain (CORS)
    depends_on:
      - mongo
    networks:
      - analytics

  mongo:
    image: mongo:7.0.16
    container_name: ackee-mongo
    restart: unless-stopped
    volumes:
      - ackee-data:/data/db
    networks:
      - analytics

networks:
  analytics:
    driver: bridge

volumes:
  ackee-data:

Environment Variables

VariablePurpose
ACKEE_MONGODBMongoDB connection string
ACKEE_USERNAMEDashboard login username
ACKEE_PASSWORDDashboard login password
ACKEE_ALLOW_ORIGINCORS origin — set to your website’s domain. Comma-separate for multiple domains
ACKEE_AUTO_ORIGINSet to true to allow all origins (less secure)

Start the stack:

docker compose up -d

Initial Setup

  1. Open the dashboard at http://your-server-ip:3000
  2. Log in with the username and password from your environment variables
  3. Click SettingsDomainsAdd Domain
  4. Enter your website’s name and domain
  5. Copy the generated tracking script

Adding the Tracking Script

Add the tracking snippet to your website’s <head>:

<script async src="https://your-ackee-instance.com/tracker.js"
  data-ackee-server="https://your-ackee-instance.com"
  data-ackee-domain-id="YOUR_DOMAIN_ID">
</script>

The script is ~2 KB, loads asynchronously, and sets no cookies.

Configuration

Multiple Domains

Ackee can track multiple websites from a single instance. Add each domain in the dashboard settings. Each gets a unique domain ID and tracking snippet.

Detailed Mode

By default, Ackee runs in “anonymous” mode — no individual visitor tracking, just aggregate metrics. Enable detailed mode for per-visitor data:

<script async src="https://your-ackee-instance.com/tracker.js"
  data-ackee-server="https://your-ackee-instance.com"
  data-ackee-domain-id="YOUR_DOMAIN_ID"
  data-ackee-opts='{ "detailed": true }'>
</script>

Detailed mode collects screen size, language, and referrer per visit. It’s still cookieless but provides more granularity.

GraphQL API

Ackee exposes a GraphQL API for programmatic access to your analytics data:

{
  domains {
    id
    title
    statistics {
      views {
        id
        count
      }
    }
  }
}

Endpoint: https://your-ackee-instance.com/api

Authentication: Bearer token (create permanent tokens in Settings → Tokens).

Reverse Proxy

For production deployment behind HTTPS:

server {
    listen 443 ssl;
    server_name analytics.example.com;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

HTTPS is strongly recommended — the ACKEE_ALLOW_ORIGIN setting works best with HTTPS origins, and browsers may block the tracker on mixed-content pages.

See Reverse Proxy Setup for full configuration.

Backup

Back up the MongoDB data volume:

docker exec ackee-mongo mongodump --out /tmp/backup --db ackee
docker cp ackee-mongo:/tmp/backup ./ackee-backup-$(date +%Y%m%d)

Or back up the entire ackee-data Docker volume with Restic or BorgBackup. See Backup Strategy.

Troubleshooting

Tracking Script Not Sending Data

Symptom: Dashboard shows zero views after adding the tracking script

Fix: Check browser console for CORS errors. The ACKEE_ALLOW_ORIGIN must exactly match your website’s origin (including protocol and port). Common mistakes:

  • http:// vs https:// mismatch
  • Missing www. prefix
  • Trailing slash in the origin URL

Dashboard Shows “Unauthorized”

Symptom: Login returns 401 or the dashboard is blank

Fix: Verify ACKEE_USERNAME and ACKEE_PASSWORD environment variables are set correctly. Restart the container after changing them:

docker compose restart ackee

MongoDB Connection Failed

Symptom: Ackee logs show MongoNetworkError: connect ECONNREFUSED

Fix: Ensure the MongoDB container is running and on the same Docker network as Ackee:

docker compose ps
docker network ls

Resource Requirements

  • RAM: 150-300 MB (Ackee ~50 MB + MongoDB ~100-200 MB)
  • CPU: Minimal
  • Disk: 1-5 GB depending on traffic volume and data retention

Verdict

Ackee is the most minimal self-hosted analytics tool worth running. It gives you the basics — page views, referrers, browsers, screen sizes — without the overhead of Matomo or Plausible. The GraphQL API is a nice touch for developers who want to pull analytics into other tools.

The limitation: Ackee lacks funnels, goals, custom events, and campaign tracking. For anything beyond “how many people visited and where did they come from,” you’ll outgrow Ackee quickly. Use Plausible or Umami if you need goals and custom events. Use Ackee if you genuinely want the bare minimum.

Comments