Applications Azure

SuiteCRM 8 on Ubuntu 24.04 on Azure User Guide

| Product: SuiteCRM 8 on Ubuntu 24.04 LTS on Azure

Overview

SuiteCRM is a full open source customer relationship management platform: accounts, contacts, leads and opportunities with a configurable sales pipeline, quotes and invoices, cases with a self-service portal, campaigns and target lists, projects, a workflow engine, reporting, and a documented REST version 8 API. The cloudimg image delivers the official SuiteCRM 8.10.2 release fully installed on Ubuntu 24.04, served over HTTPS, with every per-VM secret generated on first boot — so a working CRM is serving within minutes of launch. Backed by 24/7 cloudimg support.

SuiteCRM is free software published under the GNU Affero General Public License version 3. In accordance with section 7(b) of that licence, the Appropriate Legal Notices are retained: the "Supercharged by SuiteCRM" and "Powered By SugarCRM" notices remain displayed in the application footer, and this image is not white-labelled or re-skinned. SuiteCRM is a trademark of SuiteCRM Ltd and SugarCRM is a trademark of SugarCRM Inc; cloudimg is not affiliated with, endorsed by, or sponsored by either. This image packages the upstream open source release with cloudimg's provisioning, hardening and support.

What is included:

  • SuiteCRM 8.10.2, served from /var/www/suitecrm, with the web root at /var/www/suitecrm/public
  • PHP 8.3 (php8.3-fpm, over a local UNIX socket) behind Apache 2.4, reachable at https://<vm-ip>/; port 80 only ever redirects to HTTPS and serves no content of its own
  • A local MariaDB 10.11 LTS database, bound to 127.0.0.1 only
  • SuiteCRM's scheduler on a systemd timer (suitecrm-cron.timer, every five minutes) rather than a web-triggered endpoint
  • A per-VM administrator password, database password, session salt, application secret, REST API signing key pair and HTTPS certificate, all generated on first boot and written to a root-only file — no default, shared or published credential ships in the image
  • The web installer is gone. SuiteCRM 8 ships an unauthenticated installation wizard at /install.php and a legacy one at /legacy/install.php. The installation is completed at build time with SuiteCRM's own command line installer, both entry points are then deleted from the image, and the web server denies those routes outright
  • A password policy hardened beyond upstream's (minimum 12 characters, mixed case, digits and symbols) with SuiteCRM's login throttling left enabled
  • 24/7 cloudimg support

The SuiteCRM sign-in page served over HTTPS, with the AGPL Appropriate Legal Notices in the footer

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2ms (2 vCPU / 8 GiB RAM) is the recommended starting size: SuiteCRM is a PHP application with a local database, and the extra memory keeps the MariaDB InnoDB buffer pool and PHP's opcache warm. Scale up for large record volumes, many concurrent users, or heavy campaign and reporting use. NSG inbound: allow 22/tcp from your management network and 443/tcp (HTTPS) from wherever your team will browse. 80/tcp is optional and only redirects to HTTPS.

Step 1: Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for SuiteCRM by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size (Standard_B2ms or larger); under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTPS (443). Then Review + create and Create.

Step 2: Deploy from the Azure CLI

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

Open HTTPS so your team can reach the platform:

az vm open-port --resource-group <your-rg> --name suitecrm --port 443 --priority 900

Step 3: Connect to your VM

ssh azureuser@<vm-public-ip>

First boot takes two to four minutes. During that window the appliance generates this VM's own secrets and only then starts the web server, so a browser will refuse the connection until it finishes — that is deliberate. The image is built to fail closed: if first boot were to fail, the VM stays unreachable rather than serving a half-configured CRM.

Step 4: Confirm the SuiteCRM stack is running

systemctl is-active mariadb php8.3-fpm apache2 suitecrm-cron.timer

All four report active:

active
active
active
active

Check the front door and the redirect, and confirm nothing unexpected is listening off-box:

curl -sk -o /dev/null -w 'HTTPS front door: %{http_code}\n' -H "Host: $(hostname -I | awk '{print $1}')" https://127.0.0.1/
curl -s -o /dev/null -w 'HTTP port 80: %{http_code} -> %{redirect_url}\n' -H "Host: $(hostname -I | awk '{print $1}')" http://127.0.0.1/
ss -lntH | awk '{print $4}' | grep -vE '^(127\.|\[::1\])' | sed -E 's/.*:([0-9]+)$/\1/' | sort -un | paste -sd, -
HTTPS front door: 200
HTTP port 80: 301 -> https://10.0.0.10/
22,80,443

Exactly three ports are reachable from outside the VM: SSH, the HTTPS application, and port 80 which does nothing but redirect. MariaDB is bound to 127.0.0.1 and PHP-FPM talks to Apache over a UNIX socket, so neither is a network service.

Services active and the exact off-box listening set

Step 5: Retrieve the first-boot credentials

The administrator password is generated on this VM's first boot and written to a file only root can read:

sudo cat /root/suitecrm-credentials.txt
# cloudimg :: SuiteCRM 8 appliance credentials
# Generated on this VM's first boot. This file is readable only by root.
# Change the administrator password after your first sign-in.
suitecrm.admin.user=admin
suitecrm.admin.pass=********
suitecrm.db.name=suitecrm
suitecrm.db.user=suitecrm
suitecrm.db.pass=********

Confirm the file is locked down and that first boot really completed:

sudo stat -c '%a %U:%G %n' /root/suitecrm-credentials.txt
sudo stat -c '%n' /var/lib/cloudimg/suitecrm-firstboot.done
600 root:root /root/suitecrm-credentials.txt
/var/lib/cloudimg/suitecrm-firstboot.done

The per-VM credentials file, its mode, and the first-boot sentinel

Step 6: Understand the platform URL

SuiteCRM records the address it serves on in site_url, and the appliance refreshes that on every boot — so if your VM's public IP changes across a stop and start, the platform follows it with no edit from you:

php -r '$sugar_config=[];require "/var/www/suitecrm/public/legacy/config.php"; echo $sugar_config["site_url"], "\n";'
https://20.42.103.140

That is this VM's own public address. If you later put SuiteCRM behind a DNS name, Step 11 covers switching it over.

Step 7: Sign in

Browse to https://<vm-public-ip>/. Your browser will warn about the self-signed certificate until you install your own (Step 11) — accept the warning to continue. Sign in with the username admin and the password from Step 5.

Your first sign-in opens SuiteCRM's setup wizard — a "Welcome to SuiteCRM!" page asking for your name and contact details, your locale (time zone, date and time format) and your default currency. This is SuiteCRM's own first-run experience and it is deliberately left in place: those are your details to set, not ours. Fill them in and click Finish. Subsequent sign-ins go straight to the dashboard.

Change the administrator password immediately after that, from the user menu at the top right. SuiteCRM locks an account after five failed sign-in attempts for thirty minutes, so keep the credentials file to hand until you have set a password you will remember.

Step 8: Create your first account and contact

From the top navigation choose Accounts → Create Account, give it a name, and Save. The record view shows the account with its relationship panels and the opportunity insights alongside:

A saved Account record in SuiteCRM

Then Contacts → Create Contact, fill in a first and last name, and Save. Set Account Name on the contact to link the two together:

A saved Contact record in SuiteCRM

Accounts → View Accounts lists what you have created, with the Quick Charts panel summarising new accounts by month:

The Accounts list view showing the saved record

Step 9: Confirm the installer is not exposed

This is worth checking yourself, because it is the single most important difference between this image and a hand-rolled SuiteCRM install. Both installer entry points are deleted from the image, and the web server refuses those routes:

A=$(hostname -I | awk '{print $1}')
for p in /install.php /legacy/install.php /legacy/install/installConfig.php /legacy/config.php; do
  printf '%-40s %s\n' "$p" "$(curl -sk -o /dev/null -w '%{http_code}' -H "Host: $A" https://127.0.0.1$p)"
done
printf '%-40s %s\n' "/  (the application itself)" "$(curl -sk -o /dev/null -w '%{http_code}' -H "Host: $A" https://127.0.0.1/)"
/install.php                             403
/legacy/install.php                      403
/legacy/install/installConfig.php        403
/legacy/config.php                       403
/  (the application itself)              200

The last line is the point: the denies are targeted, not a blanket block. Note that 403 rather than 404 is deliberate — the web server refuses the route before SuiteCRM's front controller ever sees it, which matters because the application rewrites unknown paths to itself and would otherwise answer 200 with the app.

The installer lockout, with the positive control alongside

Step 10: Scheduled jobs

SuiteCRM's scheduler drives workflow, email reminders, inbound mailboxes and report generation. On this image it runs from a systemd timer every five minutes as the web user, rather than from a publicly reachable URL:

systemctl list-timers suitecrm-cron.timer --no-pager | head -3
NEXT                            LEFT LAST                              PASSED UNIT                ACTIVATES
Sun 2026-09-20 09:57:34 UTC 3min 26s Sun 2026-09-20 09:52:34 UTC 1min 33s ago suitecrm-cron.timer suitecrm-cron.service

To confirm jobs are genuinely executing rather than merely scheduled, look at what the schedulers themselves recorded:

sudo mariadb -u root suitecrm -BN -e "SELECT name, last_run FROM schedulers WHERE deleted=0 ORDER BY last_run DESC LIMIT 4;"
Run Report Generation Scheduled Tasks   2026-09-20 09:52:35
Check Inbound Mailboxes 2026-09-20 09:52:35
Run Email Reminder Notifications    2026-09-20 09:52:35
Process Workflow Tasks  2026-09-20 09:52:35

Those timestamps advance every five minutes. You can manage which jobs are active from Admin → Schedulers inside SuiteCRM.

Step 11: Use a domain name and your own certificate

Point a DNS A record at the VM's public IP, then issue a real certificate. Install certbot and request one:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d crm.example.com

Certbot rewrites the Apache virtual host for you. Then tell SuiteCRM its new address:

sudo php -r '$c=[];require "/var/www/suitecrm/public/legacy/config.php"; $c=$sugar_config; $c["site_url"]="https://crm.example.com"; $c["host_name"]="crm.example.com"; $o="<?php\n"; foreach($c as $k=>$v){$o.="\$sugar_config[".var_export($k,true)."] = ".var_export($v,true).";\n";} file_put_contents("/var/www/suitecrm/public/legacy/config.php",$o);'
sudo systemctl restart apache2

Note that the appliance's boot-time refresh would otherwise reset site_url to the VM's IP address. Once you are using a DNS name, disable that refresh so your setting sticks:

sudo systemctl disable --now suitecrm-baseurl.service

Step 12: Configure outbound email

SuiteCRM sends notifications, password resets and campaigns through an SMTP relay you supply. Configure it inside the application at Admin → Email Settings, entering your provider's host, port, and credentials. Nothing on this image listens for or relays mail itself, and no mail server is installed.

Step 13: Security model

cat /var/www/suitecrm/VERSION
php -v | head -1
mariadb --version | sed -E 's/.*(10\.[0-9.]+-MariaDB).*/MariaDB \1/'
apache2 -v | head -1
sshd -T | grep -E '^(permitrootlogin|passwordauthentication|clientaliveinterval) '
8.10.2
PHP 8.3.6 (cli) (built: Sep  2 2026 12:56:02) (NTS)
MariaDB 10.11.14-MariaDB
Server version: Apache/2.4.58 (Ubuntu)
clientaliveinterval 120
permitrootlogin no
passwordauthentication no

What the image does for you, and what remains your responsibility:

  • No shared secret. The administrator password, database password, session salt, Symfony application secret and REST API signing key pair are all minted on your VM's first boot. Two VMs launched from this image share none of them.
  • No installer. Both installation entry points are removed and denied, so there is no unauthenticated setup page to find.
  • Loopback-only data plane. MariaDB listens on 127.0.0.1 and PHP-FPM on a UNIX socket; neither is reachable from the network.
  • Root login refused. PermitRootLogin no and PasswordAuthentication no — administer the VM as azureuser with your SSH key.
  • Yours to do: restrict 22/tcp to your management network in the NSG, install a real certificate (Step 11), change the administrator password, and create individual named users rather than sharing admin.

SuiteCRM, PHP, MariaDB and Apache versions with the HTTPS and redirect check

Step 14: Back up your CRM

A SuiteCRM backup is the database plus the uploaded files and the configuration:

sudo mariadb-dump -u root --single-transaction --routines suitecrm > /var/backups/suitecrm-$(date +%F).sql
sudo tar czf /var/backups/suitecrm-files-$(date +%F).tar.gz \
  /var/www/suitecrm/public/legacy/upload \
  /var/www/suitecrm/public/legacy/custom \
  /var/www/suitecrm/public/legacy/config.php \
  /var/www/suitecrm/.env.local

Copy both off the VM — to Azure Blob Storage or your own backup target — and test a restore before you rely on it.

Step 15: Maintenance and upgrades

The image ships with unattended security updates enabled, so the operating system keeps itself patched. Apply pending updates on your own schedule with:

sudo apt-get update && sudo apt-get -y upgrade

SuiteCRM point releases are applied with the product's own upgrade tooling from Admin → Upgrade Wizard, or from the command line with bin/console suitecrm:app:upgrade. Always take the Step 14 backup first, and read the upstream release notes for the version you are moving to. cloudimg publishes refreshed images for new SuiteCRM releases; moving to a new image is the cleanest path for a major version change.

Support

cloudimg provides 24/7 support for this image by email at support@cloudimg.co.uk and by live chat. We help with deployment, retrieving the first-boot credentials, signing in, user and role administration, module customisation, the scheduler, outbound email, custom domains and certificates, backups, and upgrades. Questions about SuiteCRM feature behaviour are answered on a best-effort basis and, where appropriate, pointed at the SuiteCRM community documentation at docs.suitecrm.com.