Ackee on Ubuntu 24.04 on Azure User Guide
Overview
This image runs Ackee 3.6.0, the open source, privacy-friendly web analytics tool - a cookie-free, self-hosted alternative to trackers like Google Analytics - on Ubuntu 24.04 LTS. Ackee shows pageviews, referrers, devices and a clean real-time dashboard without ever tracking or fingerprinting individual visitors, and without setting a single cookie. It is built from source and run from /opt/ackee on the Node.js 24 LTS runtime by an unprivileged ackee system account under a systemd service that starts it on boot and restarts it on failure. A local MongoDB 8.0 Community database stores every domain's analytics data.
Ackee listens on the loopback address 127.0.0.1:3000 by design and is never exposed directly. nginx is installed as a reverse proxy on port 80 that forwards every request to Ackee. Visitors reach the dashboard on the standard HTTP port.
What is included:
- Ackee 3.6.0 built from source, run by systemd as the unprivileged
ackeeuser - The Ackee dashboard and tracking API on
:80(nginx reverse proxy to127.0.0.1:3000) - A per-VM
adminaccount (username + password) set on first boot and recorded in a root-only file - MongoDB 8.0 Community, bound to loopback, with its data directory on a dedicated Azure data disk at
/var/lib/ackee mongod.service,ackee.serviceandnginx.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point; size up for sites with heavy traffic. NSG inbound: allow 22/tcp from your management network and 80/tcp for the dashboard and tracking script. Ackee serves plain HTTP on port 80; for production, terminate TLS in front of it with your own domain, since browsers increasingly require HTTPS for pages that embed third-party scripts.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Ackee by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Review the dedicated data disk on the Disks tab, then Review + create then Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name ackee \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name ackee --port 80 --priority 1010
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the services are running
Ackee is served by nginx on port 80, which reverse-proxies to the Node.js app on 127.0.0.1:3000, which in turn talks to MongoDB on 127.0.0.1:27017. Confirm all three services are active and nginx is listening on port 80:
systemctl is-active mongod ackee nginx ackee-firstboot
sudo ss -tlnp | grep -E ':80 |:3000 |:27017 '
Expected output:
active
active
active
active
LISTEN 0 4096 127.0.0.1:27017 0.0.0.0:* users:(("mongod",pid=...))
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=...))
LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=...))
LISTEN 0 511 *:3000 *:* users:(("MainThread",pid=...))

Step 5 - Retrieve your admin password
On the first boot of every VM, ackee-firstboot.service generates a unique administrator password and writes it - together with the admin username and the dashboard URL - into a root-only file. Read it with:
sudo cat /root/ackee-credentials.txt
Unlike many self-hosted apps, Ackee has no persisted account record: the username and password you see here are checked live, on every sign-in attempt, against the Ackee process's own environment - so the credentials in this file are always the current, authoritative ones for this VM.

Step 6 - Confirm the stack and health endpoint
nginx serves an unauthenticated /healthz endpoint for load balancer probes. Confirm the Node.js and MongoDB versions and that the dashboard responds:
node -v
mongod --version | head -1
curl -sI http://127.0.0.1/healthz | head -1
curl -s http://127.0.0.1/ | grep -o '<title>[^<]*</title>'
Expected output:
v24.18.0
db version v8.0.26
HTTP/1.1 200 OK
<title>Ackee</title>

Step 7 - Sign in to the dashboard
Browse to http://<vm-public-ip>/. Enter admin and the password from Step 5.

Step 8 - Add your first domain
Once signed in, open Settings from the top navigation, find the Domains section, and click New domain. Give it a title (for example example.com) and click Add.
Step 9 - Read the dashboard overview
The Overview page (the default view after signing in) aggregates pageviews, durations, pages, referrers, systems, devices, browsers, sizes and languages across every domain you track - all anonymous and aggregated, with no per-visitor identifiers stored. It updates as traffic arrives once you add the tracking script to your site.

Step 10 - View a domain's detail
Once a domain exists, open the Domains dropdown in the top navigation and select it to see that domain's own statistics in isolation - the same set of cards as the Overview page, scoped to just that site.

Step 11 - Get the tracking code and manage domain settings
Back in Settings, click the domain (listed by its id) to reopen it. This shows the domain's Embed code - the <script> tag to paste into your site right before the closing </body> tag - along with its title and id, and lets you rename or delete the domain. Because Ackee sets no cookies and stores no personal data, no cookie banner is required in most jurisdictions - check your own compliance requirements before relying on this.
<script async src="http://<vm-public-ip>/tracker.js" data-ackee-server="http://<vm-public-ip>" data-ackee-domain-id="<your-domain-id>"></script>

Step 12 - Confirm analytics data lives on the dedicated disk
All MongoDB data - every domain, pageview, referrer and device record - lives under /var/lib/ackee, which is a dedicated Azure data disk captured into the image and re-provisioned on every VM:
df -h /var/lib/ackee | tail -1
sudo ls /var/lib/ackee/mongodb | head -5
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/ackee

Maintenance
- Back up your analytics data: everything Ackee stores lives in MongoDB's data files under
/var/lib/ackee. Snapshot the data disk, or usemongodump/mongorestorefor logical backups. - Add more domains: sign in as admin and click Create domain for each site you want to track.
- Rotate credentials: the admin username and password live in the Ackee process's environment at
/opt/ackee/.env; edit it and restart withsudo systemctl restart ackeeto change them. - Security updates: unattended security upgrades are enabled, so the OS keeps itself patched. Reboot when a new kernel is installed.
- TLS: for production, front Ackee with your own domain and a TLS-terminating reverse proxy or Azure Application Gateway - most browsers restrict third-party script behaviour on plain HTTP pages.
Support
cloudimg provides 24/7/365 expert technical support for this image. Contact support@cloudimg.co.uk. Ackee is licensed under the MIT License. This image is provided by cloudimg; additional charges apply for build, maintenance and 24/7 support.