Applications Azure

Easy!Appointments on Ubuntu 24.04 on Azure User Guide

| Product: Easy!Appointments on Ubuntu 24.04 LTS on Azure

Overview

Easy!Appointments is a powerful open source, self hosted online appointment scheduler. Publish a public booking page where your customers pick a service, a provider and an available time slot around the clock, and manage everything from the admin calendar: appointments, customers, services, providers and secretaries with their own working plans, blocked periods and exceptions. It sends email and ICS notifications, syncs provider calendars with Google Calendar and CalDAV, and exposes a REST API. The cloudimg image delivers Easy!Appointments fully installed and configured on Ubuntu 24.04 as a LAMP application, so a complete scheduling system is running within minutes of launch, with all of your booking data staying on your own server. Backed by 24/7 cloudimg support.

Easy!Appointments is licensed under the GNU General Public License v3.0 (GPL-3.0). All product and company names are trademarks or registered trademarks of their respective holders. This image repackages the upstream open source release with cloudimg's provisioning and support.

What is included:

  • Easy!Appointments 1.6.0 (GPL-3.0), served from /var/www/easyappointments
  • PHP 8.3 (php8.3-fpm) + MariaDB + nginx, all from Ubuntu 24.04 main, with the public booking page and admin backend on port 80
  • The MariaDB database on a dedicated, independently resizable data disk mounted at /var/lib/mysql
  • A per-VM administrator password and MariaDB password, both generated on first boot and written to a root-only file, so no default or shared login ships in the image
  • mariadb.service, php8.3-fpm.service and nginx.service as systemd units, enabled and active, with MariaDB bound to loopback only
  • 24/7 cloudimg support

Easy!Appointments public booking page

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 good starting point; scale up for busier booking pages. NSG inbound: allow 22/tcp from your management network and 80/tcp (HTTP) from your users.

Step 1 — Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Easy!Appointments 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

az vm create \
  --resource-group <your-rg> \
  --name easy-appointments \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Open HTTP to reach the booking page and admin backend:

az vm open-port --resource-group <your-rg> --name easy-appointments --port 80 --priority 900

Step 3 — Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 — Confirm the services are running

The three services that back Easy!Appointments should all report active. The public booking page (GET /) and the admin login page both answer HTTP 200 on port 80:

systemctl is-active mariadb php8.3-fpm nginx
curl -s -o /dev/null -w 'GET /                -> %{http_code}\n' http://127.0.0.1/
curl -s -o /dev/null -w 'GET /index.php/login -> %{http_code}\n' http://127.0.0.1/index.php/login

Expected: three lines of active, then GET / -> 200 (the public booking page) and GET /index.php/login -> 200 (the admin sign-in page). Only nginx on port 80 is exposed; php-fpm runs behind it and MariaDB listens on loopback only.

Service status and HTTP liveness on port 80

Step 5 — Retrieve your administrator password

On the first boot of every VM, a one-shot service (easy-appointments-firstboot.service) generates credentials that are unique to that VM: a fresh MariaDB password and a fresh administrator password. It installs the application schema, creates the administrator account and pins the application to your VM's own address. No shared or default credentials ship in the image.

sudo cat /root/easy-appointments-credentials.txt

The file (mode 0600, root only) contains the administrator login (ea.admin.login, which is administrator), the administrator password (ea.admin.pass), and the booking page and admin backend URLs.

Per-VM credentials, root-only and masked

You can prove the login round-trip from the VM's own shell. Easy!Appointments signs in through a JSON endpoint that carries a CSRF token, so this reads the per-VM password, fetches the token and posts a real sign-in (a correct password answers "success":true), then confirms a wrong password is rejected ("success":false):

PASS=$(sudo grep '^ea.admin.pass=' /root/easy-appointments-credentials.txt | cut -d= -f2-)
J=$(mktemp)
T=$(curl -s -c "$J" -b "$J" http://127.0.0.1/index.php/login | grep -oE '"csrf_token":"[^"]+"' | head -1 | sed -E 's/.*"csrf_token":"([^"]+)".*/\1/')
echo -n 'good password -> '; curl -s -c "$J" -b "$J" -H 'X-Requested-With: XMLHttpRequest' \
  --data-urlencode "username=administrator" --data-urlencode "password=$PASS" --data-urlencode "csrf_token=$T" \
  http://127.0.0.1/index.php/login/validate; echo
rm -f "$J"

Expected: good password -> {"success":true,...}, confirming the credentials in the file sign in.

Step 6 — Open the booking page and sign in to the backend

Browse to http://<vm-public-ip>/ for the public booking page, where customers pick a service, a provider and an available time slot in a short wizard and confirm their appointment.

The admin backend is at http://<vm-public-ip>/index.php/login. Sign in with the login administrator and the password from the credentials file.

Easy!Appointments admin sign-in

After signing in you land on the admin calendar, where you manage appointments across providers in day, week and month views.

Easy!Appointments admin calendar

Step 7 — Add your services and providers

From the backend navigation open Services to define the services customers can book (name, duration, price and category), then open Users to add providers and secretaries and set their working plans. The public booking page updates automatically as you add services and providers.

Services administration

Step 8 — Confirm the version and the data disk

grep -oE "\\\$config\['version'\] = '[^']+'" /var/www/easyappointments/application/config/app.php
php -v | head -1
findmnt /var/lib/mysql

Expected: $config['version'] = '1.6.0', PHP 8.3, and /var/lib/mysql mounted from the dedicated data disk (/dev/sdc). The booking database lives on that disk, which is independently resizable and survives instance replacement — resize it from the Azure portal if you need more room.

Version and database data disk

First-boot service and security model

A one-shot easy-appointments-firstboot.service runs after MariaDB and php-fpm are up. It generates a per-VM MariaDB password and a per-VM administrator password, installs the schema with the Easy!Appointments console installer, rotates the administrator password to the generated value (hard-gated so the stored hash always matches the credentials file), pins the application URL to the VM's own address, writes the credentials file at mode 0600 (root only) and drops a sentinel so it runs exactly once.

systemctl is-active easy-appointments-firstboot.service
sudo stat -c '%a %U:%G %n' /root/easy-appointments-credentials.txt

Expected: active, then 600 root:root /root/easy-appointments-credentials.txt.

First-boot rotation and credential file permissions

Enabling HTTPS with your own domain

The image serves the booking page over plain HTTP on port 80. For a browser-trusted certificate, point a DNS record at the VM and install a certificate from your CA (for example Let's Encrypt):

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com

Certbot updates the nginx site to serve your domain certificate. Then set the application base URL to your domain in /var/www/easyappointments/config.php (const BASE_URL) so generated links and the booking page use your domain.

Backup and maintenance

Easy!Appointments' data lives in the MariaDB easyappointments database on the dedicated data disk. Back the database up with mariadb-dump, and snapshot the data disk and OS disk from the Azure portal for a full point-in-time copy:

sudo mariadb-dump --single-transaction easyappointments | gzip > /var/backups/easyappointments-$(date +%F).sql.gz

Keep the OS current with sudo apt-get update && sudo apt-get upgrade; the image ships with unattended security updates enabled. Review the Easy!Appointments documentation before moving between major versions.

Support

This image is backed by 24/7 cloudimg support for deployment, services and providers setup, working plans and availability, email and calendar notifications, Google Calendar and CalDAV sync, the REST API, user management, database tuning, TLS and scaling. Email support@cloudimg.co.uk or use the live chat in the support portal; critical issues receive a one-hour average response.