Analytics AWS

Open Web Analytics on AWS User Guide

| Product: Open Web Analytics

Overview

Open Web Analytics (OWA) is an open source web analytics framework and a privacy respecting, self hosted alternative to Matomo and Google Analytics. It tracks visits, page views, sessions, referrers, search terms and marketing campaigns, and reports on entry and exit pages, visitor loyalty, geolocation, browsers and operating systems, with click and DOM heatmaps and e-commerce and goal tracking. A JavaScript or PHP tracker can be dropped into any site or app, and because you host it yourself, the data never leaves your own instance.

The cloudimg image delivers Open Web Analytics on an Apache, PHP and MariaDB stack, installed from the distribution's own package repositories with no third party APT repositories. The application is installed and locked down at build time and its credentials are rotated per instance on first boot, so you land on a working analytics dashboard rather than an installer. Backed by 24/7 cloudimg support.

What is included:

  • Open Web Analytics 1.8.2 (GPL-2.0) at /var/www/owa, installed from the official packaged release asset with the version and licence verified at build time
  • Apache 2.4 with mod_rewrite, MariaDB bound to 127.0.0.1, and PHP 8.3 with the mysqli, pdo_mysql, gd, mbstring, xml, curl, intl, bcmath and zip extensions, plus OPcache
  • The install wizard pre completed and denied from the web, so install.php, cli.php and owa-config.php all return HTTP 403
  • A default site already created, so you can copy a tracking snippet and start measuring immediately
  • Two dedicated EBS data volumes: the MariaDB datadir at /var/lib/mysql and the application tier at /var/www, each independently resizable
  • Per-instance administrator, application database and application secrets, all generated on first boot and written to a root-only file - no shared or default credential ships in the image
  • A public URL derived from the request host, so OWA answers correctly on the instance's public IP, its private IP, or any domain you point at it later
  • 24/7 cloudimg support

Connecting to your instance

Connect over SSH on port 22 using the private key for the key pair you selected at launch. The login user depends on the operating system variant you launched:

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<instance-public-ip>

Prerequisites

An AWS account, an EC2 key pair, and a VPC subnet. m5.large (2 vCPU, 8 GB RAM) is the recommended instance type and is sufficient for low to medium traffic; move to an m5.xlarge or larger for high traffic sites or many tracked properties.

In the instance's security group, allow inbound TCP 80 from the addresses that should reach the dashboard and receive tracking requests, and TCP 22 for administration. To serve HTTPS later, also allow TCP 443.

Step 1 - Launch from AWS Marketplace

In the AWS Marketplace console find Open Web Analytics by cloudimg and choose Continue to Subscribe, then Continue to Configuration and Continue to Launch. Pick your region, the m5.large instance type, your VPC subnet, your key pair, and a security group that allows inbound 22 and 80.

Step 2 - Launch from the EC2 CLI

aws ec2 run-instances \
  --image-id <ami-id-from-the-listing> \
  --instance-type m5.large \
  --key-name your-key \
  --security-group-ids sg-xxxxxxxx \
  --subnet-id subnet-xxxxxxxx \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=open-web-analytics}]'

Step 3 - Confirm the services are running

Both services that back Open Web Analytics should report active, and the application answers HTTP 200. MariaDB listens on 127.0.0.1:3306 only, so the database is never exposed to the network:

for s in apache2 mariadb; do echo "$s -> $(systemctl is-active "$s")"; done
ss -tlnH | awk '{print $4}' | grep -E ':80$|:3306$'
curl -s -o /dev/null -w 'healthz -> HTTP %{http_code}\n' http://127.0.0.1/healthz
curl -s -o /dev/null -w 'login   -> HTTP %{http_code}\n' -L http://127.0.0.1/index.php

Expected: apache2 -> active, mariadb -> active, the two listening sockets (127.0.0.1:3306 and *:80), healthz -> HTTP 200, and login -> HTTP 200.

Step 4 - Retrieve your administrator credentials

On the first boot of every instance, a one-shot service (open-web-analytics-firstboot.service) generates credentials that are unique to that instance: a fresh MariaDB application password, fresh application nonce and authentication secrets, and a fresh Open Web Analytics administrator password. No shared or default credential ships in the image.

sudo stat -c '%a %U:%G %n' /root/open-web-analytics-credentials.txt
sudo awk -F= '/^OPEN_WEB_ANALYTICS_ADMIN_USER=/{print} /^OPEN_WEB_ANALYTICS_URL=/{print}' /root/open-web-analytics-credentials.txt

The file is mode 0600 and owned by root, so only root can read it. It contains the dashboard URL, the administrator username (admin) and password, and the database credentials. Read the administrator password itself with sudo cat /root/open-web-analytics-credentials.txt.

You can prove the database credentials really authenticate - and that a wrong password is genuinely rejected - from the instance's own shell, without printing any secret:

DB_USER=$(sudo awk -F= '$1=="MARIADB_USER"{print $2}' /root/open-web-analytics-credentials.txt)
DB_PASS=$(sudo awk -F= '$1=="MARIADB_PASSWORD"{print $2}' /root/open-web-analytics-credentials.txt)
DB_NAME=$(sudo awk -F= '$1=="MARIADB_DATABASE"{print $2}' /root/open-web-analytics-credentials.txt)
OK=$(sudo mariadb -h 127.0.0.1 -u "$DB_USER" -p"$DB_PASS" -D "$DB_NAME" -N -B -e 'SELECT 1' 2>/dev/null || sudo mariadb -u "$DB_USER" -p"$DB_PASS" -D "$DB_NAME" -N -B -e 'SELECT 1' 2>/dev/null || true)
BAD=$(sudo mariadb -h 127.0.0.1 -u "$DB_USER" -p'wrong-password' -D "$DB_NAME" -N -B -e 'SELECT 1' 2>/dev/null || true)
echo "correct password -> ${OK:-rejected}"
echo "wrong password   -> ${BAD:-rejected}"

Expected: correct password -> 1 and wrong password -> rejected.

Step 5 - Sign in

Browse to http://<instance-public-ip>/ and sign in with the username admin and the password from the credentials file.

The Open Web Analytics login page

After signing in you land on the Sites Roster, which lists the web sites being tracked with their visits, page views and bounce rate, and links to view reports, edit the profile, or get the tracking code.

The Open Web Analytics sites roster

The image does not bake an address into the configuration. OWA derives its public URL from the incoming request, so the dashboard, the tracking snippet and every absolute link answer correctly on the instance's public address, its private address, or a custom domain you point at it later - with no reconfiguration. You can see that for yourself:

curl -s -o /dev/null -w 'custom host  -> HTTP %{http_code}\n' -H 'Host: analytics.mydomain.test' http://127.0.0.1/index.php
PAGE=$(curl -s -H 'Host: analytics.mydomain.test' 'http://127.0.0.1/index.php?owa_do=base.loginForm')
echo "$PAGE" | grep -qi 'analytics.mydomain.test' && echo 'host-derived: OWA emitted absolute URLs for the request host' || echo 'host-derived: not found'

Expected: an HTTP status for the custom host and host-derived: OWA emitted absolute URLs for the request host.

Step 6 - Explore the reports

Choose View Reports for your site to open the dashboard. The Site Metrics chart plots visits over time, and the metric cards summarise visits, unique visitors, page views and average visit duration, with a Top Content table beneath.

The Open Web Analytics dashboard

The left navigation groups the reports into Content, Action Tracking, Visitors, Traffic and Goals. The Web Pages report, for example, breaks down page views, visits and unique page views per page.

The Open Web Analytics web pages report

Step 7 - Settings

The Settings area holds the general configuration options for the platform, and confirms the installed version.

The Open Web Analytics settings page

Step 8 - Confirm the version and the locked-down entrypoints

The install wizard and the command line entrypoint are pre completed and denied from the web, so they return HTTP 403. The configuration file, which holds the application to database password, is denied too:

awk -F"'" '/define\(.OWA_VERSION./{print "OWA " $4}' /var/www/owa/owa_env.php
php -v | head -1
for p in /install.php /cli.php /owa-config.php; do echo "$p -> HTTP $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1$p)"; done

Expected: OWA 1.8.2, a PHP 8.3 line, and HTTP 403 for /install.php, /cli.php and /owa-config.php.

Step 9 - Confirm the security model

A round-trip proof confirms that the per-instance administrator authenticates through the real web login form and that blank and common weak passwords are all rejected. The first-boot sentinel confirms first boot completed, and MariaDB is bound to loopback only:

sudo bash /usr/local/sbin/open-web-analytics-cred-roundtrip.sh
sudo test -f /var/lib/cloudimg/open-web-analytics-firstboot.done && echo 'sentinel present - first boot completed'
ss -tlnH 'sport = :3306' | awk '{print "mariadb listening on " $4}'

Expected: OK per-VM administrator authenticates via the web login form; blank + weak guesses rejected, sentinel present - first boot completed, and mariadb listening on 127.0.0.1:3306.

Step 10 - Add your site and install the tracking snippet

Open Web Analytics ships with one default site already created. To track your own site, choose Reporting -> Add New (or edit the default site), give it a domain and a name, then choose Get Tracking Code. Copy the generated JavaScript snippet into your site's HTML before the closing </body> tag - or use the WordPress, Mediawiki or PHP tracker documented in the OWA wiki. As soon as the snippet is in place, visits appear in the reports.

First-boot service and security model

open-web-analytics-firstboot.service is a one-shot unit ordered After=network-online.target mariadb.service. On the first boot of each instance it rotates the application database password (in lock step with the MariaDB grant, then re-authenticates to prove it), regenerates the four OWA nonce and authentication secrets, sets the administrator password to a fresh per-instance random, writes the credentials file at mode 0600, and drops a sentinel at /var/lib/cloudimg/open-web-analytics-firstboot.done so it runs exactly once. It resolves the instance's public address via EC2 IMDSv2 for the credentials-file URL, falling back to the private address.

Because every secret is generated on your own instance, no two cloudimg deployments of this image share a credential, and nothing sensitive exists in the published image. The build image ships a clean, empty analytics dataset - the demo data used to prepare the screenshots above is removed before capture.

Using your own domain and HTTPS

The image serves plain HTTP on port 80 so that it works immediately on any address. For production, point your domain at the instance and terminate TLS. The quickest route is Certbot with the Apache plugin:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d analytics.your-domain.com

Because no address is baked into the configuration, OWA starts answering on your domain, and emitting the tracking snippet and absolute links for it, as soon as DNS resolves - there is nothing to reconfigure. It also switches to https:// automatically once a certificate is in front of it. Alternatively, place an Application Load Balancer with an AWS Certificate Manager certificate in front of the instance.

Administration from the command line

MariaDB root uses socket authentication, so on-box database maintenance needs no password:

sudo mariadb

To reset the administrator password from the shell, temporarily lift the command line lockdown, run OWA's own command, then restore the lockdown:

sudo a2disconf cloudimg-owa-lockdown && sudo systemctl reload apache2
sudo -u www-data php /var/www/owa/cli.php cmd=change-password user=admin password='your-new-password'
sudo a2enconf cloudimg-owa-lockdown && sudo systemctl reload apache2

Keeping Open Web Analytics up to date

Open Web Analytics is pinned to the version verified at build time, so the image you launched is the image that runs. To upgrade, download the newer packaged release into /var/www/owa, keeping your owa-config.php, then run the schema update from the OWA dashboard or CLI. Always take a backup first and test outside production.

Backup and maintenance

Back up the database and the application configuration:

sudo mariadb-dump --single-transaction owa > /var/backups/owa-$(date +%F).sql
sudo cp /var/www/owa/owa-config.php /var/backups/owa-config-$(date +%F).php

The operating system receives unattended security upgrades. The two data tiers each ride their own EBS volume (/var/lib/mysql and /var/www), so each can be snapshotted and resized independently.

Licensing

Open Web Analytics is distributed under the GNU General Public License, version 2 (GPL-2.0). The licence text ships in the image at /var/www/owa/LICENCE. cloudimg charges only for the packaging, maintenance and support of the image; the software itself remains under its open source licence.

Support

Every cloudimg image includes 24/7 support. Contact support@cloudimg.co.uk with your AWS account ID and the instance ID.