Applications Azure

Hi.Events on Ubuntu 24.04 on Azure User Guide

| Product: Hi.Events on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of Hi.Events on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Hi.Events is an open source, self hosted platform for organising events and selling tickets end to end. You create events and ticket types, take orders, manage attendees, design a branded public event page and checkout, capture custom questions at purchase, apply promo codes and capacity limits, message attendees, and run day of check in with QR code scanning, with organiser reporting and a full REST API for integrations.

The cloudimg image ships the free and open source, AGPL-3.0 licensed Hi.Events application, run the officially supported way as the upstream all in one container pinned by image digest, alongside the official PostgreSQL and Redis containers. All three images are captured into the VM, so your instance starts in seconds and migrates its database automatically on first boot. Because the upstream project ships with open registration and example secrets, nothing here ships with a known secret: a unique Laravel application key, a unique token signing secret, a unique database password and a per instance admin account with a random password are generated for each VM on first boot, before the app is reachable, and open self registration is then locked so no anonymous visitor can create an organiser account on your server. Backed by 24/7 cloudimg support.

Hi.Events is a trademark of its owner. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by Hi.Events. It ships the free and open source AGPL-3.0 licensed self hosted software, unmodified, including the "Powered by Hi.Events" attribution.

The docker, hi-events, nginx, firstboot and postboot services all active, and the three compose containers (Hi.Events all in one, PostgreSQL and Redis) running and healthy

What is included:

  • Hi.Events v1.11.0-beta (the AGPL-3.0 licensed all in one container: SSR frontend, Laravel REST API, internal nginx, queue worker and scheduler), pinned by image digest
  • PostgreSQL 17 and Redis 7 (official images), private to the instance, pinned by image digest
  • Docker Engine with the application published to the loopback interface only, fronted by nginx on port 80; PostgreSQL and Redis have no host port at all
  • hi-events.service, hi-events-firstboot.service, hi-events-postboot.service and nginx.service as systemd units, enabled and active on boot
  • A unique application key, a unique JWT signing secret, a unique database password and a per instance admin account with a random password generated per VM on first boot, never baked into the image
  • Open self registration locked on first boot; no default login, no shipped secret and an empty database migrated fresh on first boot
  • Ubuntu 24.04 LTS base with latest security patches applied at build time
  • Azure Linux Agent for seamless cloud integration and SSH key injection
  • 24/7 cloudimg support with guaranteed 24 hour response SLA

Prerequisites

  • Active Azure subscription, SSH public key, VNet + subnet in target region
  • Subscription to the Hi.Events listing on Azure Marketplace

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is a sensible starting point. For busier events or many concurrent buyers use Standard_D2s_v5 or larger. NSG inbound: allow 22/tcp from your management network and 80/tcp for the web application from the networks that use it.

Step 1: Deploy from the Azure Portal

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Hi.Events 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). Then Review + create and Create.

Step 2: Deploy from the Azure CLI

RG="hi-events-prod"; LOCATION="eastus"; VM_NAME="hi-events-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/hi-events-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name he-vnet --address-prefix 10.100.0.0/16 --subnet-name he-subnet --subnet-prefix 10.100.1.0/24
az network nsg create -g "$RG" --name he-nsg
az network nsg rule create -g "$RG" --nsg-name he-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name he-nsg --name allow-http --priority 110 \
  --destination-port-ranges 80 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name he-vnet --subnet he-subnet --nsg he-nsg --public-ip-sku Standard

Step 3: Connect to your VM

ssh azureuser@<vm-ip>

Step 4: Confirm the services are running

The stack runs as three containers (the Hi.Events all in one application, PostgreSQL and Redis) under one hi-events.service, fronted by nginx. Confirm the services are active and see the containers. nginx listens on :80; the application is published to 127.0.0.1 only and the database and worker have no host port:

sudo systemctl is-active docker hi-events nginx
sudo docker compose -f /etc/hi-events/compose.yaml ps

You will see the services report active and the three containers running. The application (127.0.0.1:8123) is bound only to the loopback interface; PostgreSQL and Redis are reachable only on the private container network. nginx on :80 is the single public front door and proxies everything to the application, which internally routes / to the frontend and /api to the REST API.

Step 5: Read the per instance credentials

A unique application key, a unique JWT signing secret, a unique database password and a per instance admin account with a random password were generated for this VM on the first boot, before the app was reachable, and written to a root only file. Read them:

sudo cat /root/hi-events-credentials.txt

The file (mode 0600 root:root) holds ADMIN_EMAIL and ADMIN_PASSWORD (the account you sign in with), plus WEB_URL, API_URL and the APP_KEY. None of these ship in the image; every value is unique to this VM, so no two instances share a credential and there is no default login to change.

The hi-events-credentials.txt file at mode 0600 root root with the per VM admin email and password and URLs, the password and application key redacted, and a note that they are generated uniquely on first boot

Step 6: Verify the security model

The frontend is reachable without authentication, but every protected API endpoint requires a bearer token, and open self registration is locked. Confirm that the frontend loads, that an unauthenticated request to a protected endpoint is rejected with 401, that the per instance admin credential authenticates a real call, and that a fresh registration attempt is rejected:

ADMIN_EMAIL=$(sudo grep '^ADMIN_EMAIL=' /root/hi-events-credentials.txt | cut -d= -f2-)
ADMIN_PASSWORD=$(sudo grep '^ADMIN_PASSWORD=' /root/hi-events-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'frontend      (no auth):  %{http_code}\n' http://localhost/
curl -s -o /dev/null -w 'users/me      (no token): %{http_code}\n' -H 'Accept: application/json' http://localhost/api/users/me
TOKEN=$(curl -s -X POST http://localhost/api/auth/login \
  -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -d "{\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\"}" \
  | python3 -c 'import sys,json;d=json.load(sys.stdin);print(d.get("token") or d.get("access_token") or d.get("data",{}).get("token",""))')
curl -s -o /dev/null -w 'users/me      (with token): %{http_code}\n' \
  -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json' http://localhost/api/users/me

The frontend returns 200, the protected endpoint is rejected with 401 for no token, and the same call with the per instance admin token returns 200. This is the security model: the API is gated by a bearer token you obtain by signing in, and open registration is locked so nobody can create an organiser account on your server without your say so.

curl showing the frontend returning HTTP 200, the protected users endpoint returning 401 without a token and 200 with the per instance admin token, and a registration attempt being rejected because open registration is locked

The same round trip is bundled as a single script on the image, which the build and smoke tests run to prove the credential works end to end and that registration is locked:

sudo /usr/local/sbin/hi-events-roundtrip.sh

The bundled round trip script reporting OK: the frontend and API are live, no and wrong tokens are rejected with 401, open registration is locked, and the per instance admin credential authenticates a real API call

Step 7: Open the web application and sign in

Browse to http://<vm-ip>/ to reach Hi.Events. Sign in with the ADMIN_EMAIL and ADMIN_PASSWORD from Step 5. Open self registration is locked on this image, so the sign in form is the way in; see Step 11 to re enable registration if you want others to create their own organiser accounts.

The Hi.Events sign in page, with the email and password fields and a panel highlighting the platform features: custom branding, instant payouts, mobile optimized checkout and data ownership

Step 8: Your organizer dashboard

On first sign in Hi.Events prompts you to set up your organization (the identity shown on your event pages). Once set up, the organizer dashboard is your home: it shows gross sales, products sold, attendees, orders, tax and fees at a glance, your recent orders and your upcoming events, with navigation to events, reports, settings and the homepage designer.

The Hi.Events organizer dashboard showing sales, products sold, attendees, orders, tax and fees statistics, a recent orders panel and an upcoming events panel listing a real event

Step 9: Create an event

Choose Create Event and give your event a name, a start and end date and a description. Once created, the event has its own dashboard with sales, attendee and page view statistics and a product sales chart, plus everything you need to configure it: event settings, homepage designer, ticket designer, registration questions, tickets and products, orders, promo codes, affiliates, attendees and check in.

The Hi.Events event dashboard for a created event, showing attendees, products sold, refunded, gross sales, page views and completed orders statistics and a product sales chart, with the full event management navigation

Step 10: Add tickets and products

Open Tickets & Products to create the tickets you will sell. Each ticket has a type (paid, free, tiered or donation), a price, an optional capacity and a sale period. Paid tickets require online payments, which you enable by connecting Stripe. Below, a paid General Admission ticket at $25.00 and a free Student ticket are both on sale.

The Hi.Events Tickets and Products page for the event, showing a paid General Admission ticket at 25.00 dollars and a free Student ticket, both marked on sale, with create, edit and reorder controls

Step 11: Publish, check in and manage registration

When your event is ready, set it to Live to publish its public event and checkout page, and share the link. As attendees arrive, use the Check-in area to scan QR codes from tickets and track arrivals in real time. Reports cover sales, attendees and check in summaries, and you can export orders and attendees to CSV.

Open self registration is locked on this image so no anonymous visitor can create an organiser account on your server. To re enable it (for example to let colleagues self register), edit /etc/hi-events/hi-events.env, set APP_DISABLE_REGISTRATION=false, and recreate the application container:

sudo docker compose --env-file /etc/hi-events/hi-events.env -f /etc/hi-events/compose.yaml up -d

Step 12: Call the API from your own machine

Every feature of the web application is backed by the REST API, which you can call directly. Obtain a token by signing in, then call a protected endpoint with the VM address:

TOKEN=$(curl -s -X POST http://<vm-ip>/api/auth/login \
  -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -d '{"email":"<ADMIN_EMAIL>","password":"<ADMIN_PASSWORD>"}' \
  | python3 -c 'import sys,json;d=json.load(sys.stdin);print(d.get("token") or d.get("access_token") or d.get("data",{}).get("token",""))')
curl -s -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json' "http://<vm-ip>/api/users/me"

The login returns a JWT bearer token; pass it as an Authorization: Bearer header to reach protected endpoints such as your organizers, events, tickets, orders and attendees.

Step 13: Server components

Component Version / Detail
Application Hi.Events v1.11.0-beta all in one (SSR frontend + Laravel API + queue worker + scheduler, pinned by image digest)
Database PostgreSQL 17 (private container, migrated automatically on first boot)
Queue / cache Redis 7 (private container)
Front door nginx on :80 proxying to the application on 127.0.0.1:8123
Application key per instance, generated first boot into /etc/hi-events/hi-events.env
Token signing secret per instance JWT secret, generated first boot
Database password per instance, generated first boot
Admin account per instance random password, seeded first boot into /root/hi-events-credentials.txt
Registration locked on first boot (APP_DISABLE_REGISTRATION=true)
Operating system Ubuntu 24.04 LTS (patched at build)
License AGPL-3.0 (Hi.Events)

Step 14: Managing the service

sudo systemctl status hi-events --no-pager | head -12
sudo docker compose -f /etc/hi-events/compose.yaml logs --tail 40 all-in-one

Restart the whole stack with sudo systemctl restart hi-events, follow the application logs live with sudo docker compose -f /etc/hi-events/compose.yaml logs -f all-in-one, and view configuration in /etc/hi-events/hi-events.env and /etc/hi-events/compose.yaml. After changing the environment file, recreate the application container to apply it (Step 11).

Step 15: Configure email (for tickets, receipts and password resets)

Out of the box the image uses a log mail driver, so no email is actually sent. To deliver order confirmations, tickets and password reset emails, set your SMTP details in /etc/hi-events/hi-events.env (MAIL_MAILER=smtp, MAIL_HOST, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD, MAIL_FROM_ADDRESS) and recreate the application container as in Step 11.

Step 16: Use your own domain and HTTPS (production)

The image serves the application over plain HTTP on port 80, which is convenient behind a load balancer or private network. For production you should terminate TLS in front of the VM so credentials and payment flows travel encrypted:

  • Front the VM with Azure Application Gateway, a load balancer with a managed certificate, or a CDN, and forward to nginx on port 80.
  • Or install your own certificate: add a TLS server block to /etc/nginx/sites-available/hi-events referencing your certificate and key, open 443/tcp on the NSG, then sudo systemctl reload nginx.
  • Point a DNS name you control at the VM public IP. Because the application reads its public URLs at first boot from the resolved address, use a stable public IP, or set APP_FRONTEND_URL, VITE_FRONTEND_URL and VITE_API_URL_CLIENT in /etc/hi-events/hi-events.env to your https:// domain and recreate the container (Step 11) when using a custom domain and TLS.

Step 17: Security recommendations

  • Restrict the NSG. Allow TCP 80 (and 22 for admin) only from the networks that use the app.
  • Terminate TLS in front of the app (Step 16) so the admin password, tokens and payment flows are encrypted in transit.
  • Rotate the seeded admin password. Sign in and change it in your profile.
  • Keep registration locked unless you deliberately need open sign ups (Step 11).
  • Keep the database and worker private. PostgreSQL and Redis have no host port and are reachable only on the private container network; keep them that way.
  • Keep the OS patched. Unattended security upgrades remain enabled on the running VM.

Step 18: Support and Licensing

Hi.Events is distributed under the GNU Affero General Public License v3 (AGPL-3.0). This cloudimg image bundles the unmodified official open source release, including the "Powered by Hi.Events" attribution the project requires; cloudimg provides the packaging, the single nginx front door, the per instance secret and admin generation, the registration lock down, the paired deploy guide, and 24/7 support with a guaranteed 24 hour response SLA. Hi.Events is an independent open source project and this image is not affiliated with or endorsed by it.

Deploy on Azure

Launch Hi.Events on Ubuntu 24.04 LTS by cloudimg from the Azure Marketplace and follow this guide to a working event management and ticketing platform in minutes.