GoAccess
Overview
GoAccess is a fast, open-source, real-time web-log analyzer. It parses your nginx, Apache or CDN access logs and renders an interactive HTML dashboard that updates live in the browser over a WebSocket as new requests arrive. The dashboard covers unique visitors, requested files, HTTP status codes, referrers, operating systems, browsers, geo location and bandwidth.
This SecureAnyCloud image compiles the pinned GoAccess 1.10.2 from its official source release and runs it as a dedicated goaccess system user under systemd. An nginx reverse proxy fronts the generated report on port 80, adds a per-VM HTTP Basic Auth gate and proxies the live-update WebSocket. A unique dashboard password is generated on the first boot of every VM.
Out of the box, GoAccess analyzes the VM's own nginx access log, so the dashboard is populated the moment you sign in. Repointing it at your real logs is a one-line change.
What you get:
- GoAccess 1.10.2 compiled from source (UTF-8, GeoIP2 and OpenSSL support) running as the
goaccesssystemd service - A live-updating HTML dashboard on
:80, fronted by nginx with the GoAccess WebSocket proxied for real-time updates - Per-VM HTTP Basic Auth (user
admin) protecting the dashboard, with a unique password generated on first boot - A dashboard that ships analyzing the VM's own nginx access log, so it is populated on first view
- A dedicated Azure data disk at
/var/lib/goaccessholding the persisted parse database, the report and the password file goaccess.serviceandnginx.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet and subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting point, because GoAccess is light on resources.
In the network security group (NSG), allow inbound 22/tcp from your management network and 80/tcp for the dashboard. Also allow 443/tcp if you add TLS.
GoAccess serves plain HTTP on port 80. In production, terminate TLS in front of it with your own domain and switch the live-update WebSocket to secure wss (see Maintenance).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, and search the Marketplace for GoAccess by SecureAnyCloud. 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 choose Review + create and Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:goaccess-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name goaccess \
--image sac1647283583153:goaccess-ubuntu-24-04:default:latest \
--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 goaccess --port 80 --priority 1010Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
systemctl is-active goaccess.service nginx.serviceBoth services report active. GoAccess parses the log and serves its live-update WebSocket on the loopback connector 127.0.0.1:7890. nginx fronts the HTML report on port 80, adds the per-VM HTTP Basic Auth gate, and proxies the WebSocket at /ws.
GoAccess's persisted parse database and the generated report live on the dedicated Azure data disk mounted at /var/lib/goaccess.
Step 5 - Retrieve your dashboard password
nginx protects the GoAccess dashboard with HTTP Basic Auth. The username is admin. A unique password is generated on the first boot of your VM and written to a root-only file:
sudo cat /root/goaccess-credentials.txtThis file contains GOACCESS_USERNAME, GOACCESS_PASSWORD and the GOACCESS_URL to open in a browser. The password is stored on disk only as a bcrypt hash in /var/lib/goaccess/.htpasswd, so no plaintext password ships in the image.
Store the password somewhere safe.
Step 6 - Confirm the health endpoint
nginx serves an unauthenticated health endpoint for load balancers and probes:
curl -s http://localhost/healthzThe endpoint returns ok. It never requires authentication, so it is safe to use for an Azure Load Balancer health probe.
Step 7 - Confirm authentication and the live-update WebSocket
Because a password is set on first boot, an unauthenticated request to the dashboard returns HTTP 401. Nobody can reach your analytics without the password.
The following commands read the per-VM password from the credentials file and prove the round trip. An unauthenticated request is rejected, the correct password authenticates, and the live-update WebSocket upgrades:
PW=$(sudo grep '^GOACCESS_PASSWORD=' /root/goaccess-credentials.txt | cut -d= -f2-)
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/)"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/)"
echo "ws : $(curl -s -m 5 -o /dev/null -w '%{http_code}' -H 'Connection: Upgrade' -H 'Upgrade: websocket' -H 'Sec-WebSocket-Version: 13' -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" http://127.0.0.1/ws)"The output is unauth : 401, then authed : 200, then ws : 101, which means the WebSocket handshake succeeds. The /ws endpoint carries only the incremental parse data that drives the live update. The report page itself stays behind the password.
Step 8 - Sign in to the dashboard
Browse to http://<vm-public-ip>/. When your browser prompts for a username and password, enter admin and the password from Step 5.
GoAccess opens on the overview. The General Statistics summary at the top shows total requests, valid requests, unique visitors, requested files, referrers, not-found URLs, bandwidth and processing time. Each analysis panel follows.
Because the image ships analyzing the VM's own nginx log, the dashboard is already populated. It updates live as new requests arrive.
Step 9 - Read the requests and static-files panels
Scroll down to the Requested Files and Static Requests panels. Each shows the top URLs by hits and visitors, the HTTP method and protocol, the bytes served and the percentage of traffic.
These panels are the fastest way to see what is actually being requested from your site.
Step 10 - Read the visitor hostnames and operating-system panels
Further down, the Visitor Hostnames and IPs and Operating Systems panels break your traffic down by client IP and by platform (Windows, Linux, macOS, Android, iOS, crawlers). Use them to see who is reaching your site and from what.
The Browsers panel just below does the same by user agent (Safari, Chrome, Edge, Firefox and more).
Step 11 - Read the referrers and HTTP status-code panels
The Referring Sites panel shows where your traffic comes from. The HTTP Status Codes panel groups requests by response code (2xx success, 3xx redirection, 4xx client errors, 5xx server errors), so you can spot error spikes at a glance.
Add a GeoLite2 database (see Maintenance) to populate the Geo Location panel and map visitors by country.
Step 12 - Repoint GoAccess at your own logs
Out of the box, GoAccess analyzes this VM's own nginx access log at /var/log/nginx/access.log. To analyze your real site's logs, edit the log path on the ExecStart line of the service unit and restart the service:
sudo systemctl edit --full goaccess.service
# change the log path on the ExecStart line
sudo systemctl restart goaccess.serviceGoAccess reads the standard COMBINED log format by default, which nginx and Apache both emit. For a different format, add a matching --log-format to the ExecStart line.
You can also point GoAccess at several log files at once by listing them on the command line.
Step 13 - Confirm data lives on the dedicated disk
GoAccess's persisted parse database, the generated report and the per-VM password file are kept under /var/lib/goaccess on the dedicated Azure data disk. Your analytics therefore survive OS changes, and you can resize the disk independently:
findmnt /var/lib/goaccessThe mount is backed by a separate Azure data disk that is captured into the image and re-provisioned on every VM.
Maintenance
- Password: The dashboard password is set on first boot and stored as a bcrypt entry in
/var/lib/goaccess/.htpasswd. To change it, runsudo htpasswd -B /var/lib/goaccess/.htpasswd admin, thensudo systemctl reload nginx. - Your own logs: Repoint GoAccess at your real nginx, Apache or CDN access logs by editing the log path on the
ExecStartline ofgoaccess.service(Step 12). The persisted parse database under/var/lib/goaccesskeeps historical data across restarts via--persist/--restore. - GeoIP: The binary is built with GeoIP2 support, but no GeoLite2 database ships because MaxMind's licence does not allow redistribution. Download a GeoLite2-Country or GeoLite2-City
.mmdbfrom MaxMind. Then add--geoip-database /path/to/GeoLite2-City.mmdbto theExecStartline to populate the geo panel. - TLS and secure WebSocket: GoAccess serves plain HTTP on port 80 with a
ws://live-update WebSocket. In production, front it with TLS (for example, certbot with your own domain). Then set the report's--ws-urltowss://<your-domain>/wsand proxy/wsover:443so live updates flow over a secure WebSocket. - Real-time WebSocket URL: GoAccess bakes the WebSocket URL into the report on first boot from the VM's public IP. If the VM's public IP changes, re-run first boot (
sudo rm /var/lib/sac/data/goaccess-firstboot.done && sudo systemctl start goaccess-firstboot.service), or edit/etc/goaccess/goaccess.envand restartgoaccess.service. - Storage: All GoAccess state lives under
/var/lib/goaccesson the data disk. Back up that volume to protect your persisted analytics. - Security patches: unattended-upgrades remains enabled, so the OS continues to receive security updates automatically.
Support
SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com for help.
Deploy on Azure
Launch GoAccess Real-Time Web Log Analyzer on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
This image runs GoAccess, the fast real-time web-log analyzer. GoAccess parses web server access logs and renders them as an interactive HTML dashboard that you open in a browser. The dashboard covers unique visitors, requested files, static resources, not-found URLs, visitor hosts, operating systems, browsers, HTTP status codes, referrers and bandwidth, all updating live over a WebSocket as new requests arrive.
GoAccess is built from the official 1.10.2 release and runs as the dedicated goaccess system user under systemd. It writes a real-time HTML report and drives a WebSocket server on the loopback interface at 127.0.0.1:7890. nginx fronts both as a reverse proxy on port 80 (and 443 once you add TLS), serves the dashboard behind HTTP Basic Auth and proxies the WebSocket.
What you get:
- A dashboard that analyzes the instance's own nginx access log out of the box, so it is populated the moment you open it
- An unauthenticated health endpoint at
/healthzfor load balancers and uptime checks - A dedicated EBS data volume mounted at
/var/lib/goaccess, holding the generated report, the persisted parse database and the Basic Auth password file, and independently resizable and separate from the operating system disk - A unique dashboard password for every deployed instance, with no shared or default credentials in the image
On the first boot of every deployed instance, a one-shot service generates the instance's dashboard password and applies it as an nginx HTTP Basic Auth credential for the user admin. It records the password in /root/goaccess-credentials.txt with mode 0600 and templates the live-update WebSocket URL to the instance's own public address.
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your operators will use to reach the GoAccess dashboard
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
Launch the instance from AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and choose Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for GoAccess. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login).
Under Network settings, select your VPC and subnet. Create or select a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your users will use to reach the dashboard.
Leave the root volume at the default size or larger. The image adds a separate data volume for the report and parse database automatically.
Choose Launch instance. First-boot initialization takes under a minute after the instance state becomes Running and the status checks pass.
Launch the instance from the AWS CLI
The following command launches an instance from the SecureAnyCloud GoAccess Marketplace AMI into an existing subnet and security group.
Replace <ami-id> with the AMI ID shown on the Marketplace listing and <key-name> with your EC2 key pair name. Replace <subnet-id> with your subnet ID and <security-group-id> with a security group that opens ports 22, 80 and 443 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=goaccess-01}]'On success, the command prints a JSON document. Note the instance ID. Once the instance is running, retrieve its public address with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Connect and retrieve the dashboard password
Connect over SSH with the key pair you selected and the public IP address from Step 2. The SSH login user depends on the operating system of the AMI variant you launched. For GoAccess 1.10 on Ubuntu 24.04, the login user is ubuntu.
The first-boot service runs before the SSH daemon becomes ready, so the credentials file is always in place when you log in for the first time.
ssh <login-user>@<public-ip>
sudo cat /root/goaccess-credentials.txtThe plain-text file contains the dashboard URL, the username admin and the per-instance dashboard password.
From the same SSH session, you can confirm the deployment is healthy. nginx serves the health endpoint, and it is open:
curl -fsS http://127.0.0.1/healthzokAn ok response confirms nginx is fronting the application. You can also confirm that the services that make up the stack are running and enabled, and check the GoAccess version:
systemctl is-active goaccess nginx goaccess-firstboot goaccess --versionactive active active GoAccess - 1.10.2. For more details visit: https://goaccess.io/ Copyright (C) 2009-2024 by Gerardo OrellanaGoAccess listens on the loopback interface, and nginx publishes the dashboard on port 80. Confirm the listening sockets:
sudo ss -tlnp | grep -E ':80 |:7890 'LISTEN 0 4096 127.0.0.1:7890 0.0.0.0:* users:(("goaccess",...)) LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",...))Sign in to the dashboard
Open http://<public-ip>/ in your browser. When nginx challenges you with HTTP Basic Auth, enter the username admin and the per-instance password from the credentials file. GoAccess then serves the real-time dashboard.
The Overall Analyzed Requests panel at the top summarizes total and valid requests, unique visitors, requested files, referrers, not-found URLs, log size and transferred bandwidth. The Last Updated badge shows the live WebSocket connection pushing updates as new requests arrive.
Because the image ships analyzing the instance's own nginx access log, the dashboard is already populated on first view. As traffic reaches the instance, the panels update in real time without a page refresh.
Read the analytics panels
Scroll down through the stacked panels. The Unique Visitors Per Day chart plots hits and visitors over time. The Requested Files (URLs) panel ranks the most-requested paths by hits, visitors and bandwidth, with the request method and protocol for each.
The Visitor Hostnames and IPs panel shows which clients are generating traffic. The Operating Systems and Browsers panels break visitors down by platform and user agent.
Every panel has a sortable table and a chart. Use the Panel Options menu to change the metric plotted or expand the rows shown.
The HTTP Status Codes panel groups responses into 2xx success, 3xx redirection, 4xx client errors and other classes, so you can spot a rise in errors at a glance. Further panels cover static requests, not-found URLs, referrers, referring sites and time distribution.
Point GoAccess at your own logs
Out of the box, GoAccess analyzes this instance's own nginx access log at /var/log/nginx/access.log. To analyze your own web server, CDN or reverse-proxy logs, edit the service environment file and set GOACCESS_LOG to your log path. Then restart the service.
The default configuration expects the combined log format, which nginx and Apache both use by default.
cat /etc/goaccess/goaccess.envGOACCESS_LOG=/var/log/nginx/access.log WS_URL=ws://<public-ip>:80/wsEdit the file with sudo, change the GOACCESS_LOG line to your log file, and restart GoAccess. GoAccess re-parses the log, rebuilds the report and resumes streaming live updates:
sudo systemctl restart goaccessGoAccess supports many log formats beyond combined, including the common log format, W3C, Amazon CloudFront, Amazon S3, Application and Classic Load Balancer, Caddy and Traefik. To use one of those, add the matching --log-format value to the ExecStart line.
Alternatively, copy the logs from your other hosts onto this instance and point GOACCESS_LOG at them.
Add or change dashboard users
The dashboard is protected by an nginx HTTP Basic Auth file at /var/lib/goaccess/.htpasswd. To change the admin password or add more users, use htpasswd and reload nginx. You do not need to restart GoAccess, because nginx owns the credential check.
sudo htpasswd -bB /var/lib/goaccess/.htpasswd analyst <new-password>
sudo systemctl reload nginxThe -B flag stores a bcrypt hash, matching the format the first-boot service uses. The -b flag takes the password on the command line. Omit it to be prompted interactively.
Replace <new-password> with the password you want to set.
Configure HTTPS and the encrypted WebSocket
In production, serve the dashboard and its live-update WebSocket over HTTPS. Point a DNS name at the instance and open port 443 in the security group. Then install a certificate with a tool such as Certbot, which can update the nginx site automatically.
Once nginx serves TLS on 443, update the WebSocket URL so the dashboard connects over the encrypted wss:// scheme. Set WS_URL in /etc/goaccess/goaccess.env to wss://your-goaccess-host:443/ws and restart GoAccess.
GoAccess bakes the WebSocket URL into the report, so live updates only work when the URL matches the address and scheme your browser uses to reach nginx.
sudo systemctl restart goaccessHealth checks and monitoring
nginx serves an unauthenticated health endpoint at /healthz that returns 200 ok. Use it for an Elastic Load Balancer target group or an external uptime monitor.
The dashboard and every other path require the Basic Auth credential, while the health endpoint stays open.
curl -fsS http://127.0.0.1/healthzokInspect the service logs at any time with journalctl:
sudo journalctl -u goaccess -n 50 --no-pagerBackup and maintenance
GoAccess keeps its persisted parse database, the generated report and the Basic Auth password file on the dedicated data volume at /var/lib/goaccess. Stopping the service flushes the in-memory parse data to the on-disk database. The database is reloaded when the service starts again, so history survives restarts.
Snapshot the EBS data volume on your normal schedule to back up the parse database and the dashboard credentials.
sudo ls /var/lib/goaccessKeep the instance patched with your normal operating-system update process.
The GoAccess binary is installed at /usr/local/bin/goaccess. To move to a newer release, replace that binary and restart the service.
Troubleshooting
If the browser returns 401 Unauthorized, confirm that you are using the username admin and the exact password from /root/goaccess-credentials.txt.
If the dashboard loads but the Last Updated badge never advances, the live-update WebSocket is not connecting. Check that WS_URL in /etc/goaccess/goaccess.env matches the address and scheme your browser uses to reach the instance. Also check that port 80 (or 443 for wss://) is open in the security group.
If the dashboard is empty, confirm that the log named in GOACCESS_LOG exists and is in the expected format. Then restart GoAccess.
systemctl status goaccess --no-pagerSupport
This image is published and supported by SecureAnyCloud. Contact SecureAnyCloud support by email and chat, available 24/7, for help with deploying, repointing GoAccess at your own logs, configuring HTTPS and the encrypted WebSocket, enabling GeoIP location, or scaling analytics across multiple hosts.
Deploy on AWS
Launch GoAccess on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com