Hi.Events
Overview
This guide covers the deployment and configuration of Hi.Events on Ubuntu 24.04 on Azure, using SecureAnyCloud Azure Marketplace images. Hi.Events is an open-source, self-hosted platform for organizing events and selling tickets end to end.
You create events and ticket types, take orders and manage attendees. You design a branded public event page and checkout, capture custom questions at purchase, and apply promo codes and capacity limits. You can message attendees and run day-of check-in with QR code scanning. Organizer reporting and a full REST API for integrations are included.
The SecureAnyCloud image ships the free and open-source, AGPL-3.0 licensed Hi.Events application. It runs 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.
The upstream project ships with open registration and example secrets, but this image ships with no known secret. First boot generates a unique Laravel application key, a unique token signing secret, a unique database password and a per-instance admin account with a random password for each VM. It does this before the app is reachable. Open self-registration is then locked, so no anonymous visitor can create an organizer account on your server. SecureAnyCloud support is available 24/7.
Hi.Events is a trademark of its owner. SecureAnyCloud produces this image, which 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.
What you get:
- 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 and 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.serviceandnginx.serviceas 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 and never baked into the image
- Open self-registration locked on first boot, with no default login, no shipped secret and an empty database migrated fresh on first boot
- Ubuntu 24.04 LTS base with the latest security patches applied at build time
- Azure Linux Agent for seamless cloud integration and SSH key injection
- 24/7 SecureAnyCloud support with a guaranteed 24-hour response SLA
Prerequisites
- An active Azure subscription, an SSH public key, and a VNet and subnet in your target region
- A 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 rules: Allow 22/tcp from your management network. Allow 80/tcp for the web application from the networks that use it.
Deploy from the Azure Portal
Sign in to the Azure Portal, choose Create a resource, and search the Marketplace for Hi.Events 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). Then choose Review + create and Create.
Deploy from the Azure CLI
RG="hi-events-prod"; LOCATION="eastus"; VM_NAME="hi-events-01" IMAGE_URN="sac1647283583153:hi-events-ubuntu-24-04:default:latest" 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
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:hi-events-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
--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 StandardConnect to your VM
ssh azureuser@<vm-ip>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 that the services are active and list 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 psThe services report active and the three containers report 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. It proxies everything to the application, which internally routes / to the frontend and /api to the REST API.
Read the per-instance credentials
On first boot, before the app was reachable, this VM generated a unique application key, a unique JWT signing secret, a unique database password and a per-instance admin account with a random password. It wrote them to a file that only root can read. Read them with:
sudo cat /root/hi-events-credentials.txtThe file (mode 0600 root:root) holds ADMIN_EMAIL and ADMIN_PASSWORD, which are the account you sign in with. It also holds WEB_URL, API_URL and the APP_KEY.
None of these values 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.
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 and that an unauthenticated request to a protected endpoint is rejected with 401. Confirm 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/meThe frontend returns 200. The protected endpoint is rejected with 401 when you send no token, and the same call with the per-instance admin token returns 200.
This is the security model. A bearer token that you obtain by signing in gates the API, and open registration is locked, so nobody can create an organizer account on your server without your approval.
The image bundles the same round trip as a single script. The build and smoke tests run it to prove that the credential works end to end and that registration is locked:
sudo /usr/local/sbin/hi-events-roundtrip.shOpen 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 only way in. To let others create their own organizer accounts, re-enable registration as described in Step 11.
Your organizer dashboard
On your first sign-in, Hi.Events prompts you to set up your organization, which is the identity shown on your event pages.
Once you have set it up, the organizer dashboard is your home. It shows gross sales, products sold, attendees, orders, tax and fees at a glance, along with your recent orders and upcoming events. It also links to events, reports, settings and the homepage designer.
Create an event
Choose Create Event and give your event a name, a start and end date, and a description.
Once you create the event, it has its own dashboard with sales, attendee and page view statistics and a product sales chart. The event also has 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.
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. For example, a paid General Admission ticket at $25.00 and a free Student ticket can both be on sale.
Publish, check in and manage registration
When your event is ready, set it to Live to publish its public event and checkout page, then 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. You can export orders and attendees to CSV.
Open self-registration is locked on this image, so no anonymous visitor can create an organizer account on your server. To re-enable it, for example to let colleagues register themselves, edit /etc/hi-events/hi-events.env and set APP_DISABLE_REGISTRATION=false. Then recreate the application container:
sudo docker compose --env-file /etc/hi-events/hi-events.env -f /etc/hi-events/compose.yaml up -dCall the API from your own machine
The REST API backs every feature of the web application, and you can call it 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.
Server components
- Application: Hi.Events v1.11.0-beta all-in-one (SSR frontend, Laravel API, queue worker and scheduler), pinned by image digest
- Database: PostgreSQL 17 in a private container, migrated automatically on first boot
- Queue and cache: Redis 7 in a private container
- Front door: nginx on :80, proxying to the application on 127.0.0.1:8123
- Application key: per instance, generated on first boot into /etc/hi-events/hi-events.env
- Token signing secret: a per-instance JWT secret, generated on first boot
- Database password: per instance, generated on first boot
- Admin account: per instance, with a random password seeded on 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 time
- License: AGPL-3.0 (Hi.Events)
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-oneRestart 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. View the configuration in /etc/hi-events/hi-events.env and /etc/hi-events/compose.yaml.
After you change the environment file, recreate the application container to apply the change (Step 11).
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). Then recreate the application container as in Step 11.
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, terminate TLS in front of the VM so that 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
serverblock to/etc/nginx/sites-available/hi-eventsthat references your certificate and key, open443/tcpon the NSG, then runsudo systemctl reload nginx. - Point a DNS name that you control at the VM public IP. The application reads its public URLs at first boot from the resolved address. Use a stable public IP, or, when you use a custom domain and TLS, set
APP_FRONTEND_URL,VITE_FRONTEND_URLandVITE_API_URL_CLIENTin/etc/hi-events/hi-events.envto yourhttps://domain and recreate the container (Step 11).
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.
Support and Licensing
Hi.Events is distributed under the GNU Affero General Public License v3 (AGPL-3.0). This SecureAnyCloud image bundles the unmodified official open-source release, including the "Powered by Hi.Events" attribution that the project requires.
SecureAnyCloud provides the packaging, the single nginx front door, the per-instance secret and admin generation, the registration lockdown, 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 SecureAnyCloud from the Azure Marketplace and follow this guide to a working event management and ticketing platform in minutes.
Deploy on Azure
Launch Hi.Events 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