Deployment guide

ITFlow

Overview

ITFlow is an open-source IT documentation and business management platform for managed service providers and internal IT teams. It gives you one place to record every client with their contacts, locations, assets, networks, racks and credentials. It then runs the work around them: tickets with email parsing and a client portal, projects, invoices, quotes, recurring billing, expenses, and domain and SSL certificate expiry tracking.

The SecureAnyCloud image ships ITFlow 26.07 served by Apache and PHP 8.3 on a hardened Ubuntu 24.04 LTS base, patched at build time, with a bundled local MariaDB server. It is served over HTTPS from the moment it boots. No administrator password exists anywhere in the image: ITFlow installs itself on your instance at first boot and generates a unique password and a unique TLS certificate for that instance. Backed by 24/7 SecureAnyCloud support.

What you get:

  • ITFlow 26.07, the current monthly stable release, installed from the official upstream source and verified by checksum at build time.
  • Apache 2.4 with PHP 8.3 and OPcache, plus every PHP extension and shell command ITFlow requires.
  • An encrypted credential vault with TOTP support, which keeps client passwords and second factors alongside the documentation that explains them.
  • HTTPS on port 443 with a self-signed certificate generated for your instance at first boot. Port 80 permanently redirects to it, because ITFlow refuses to present a sign-in form over plain HTTP.
  • MariaDB bound to 127.0.0.1:3306, with its data directory on a dedicated 20 GiB data disk.
  • Your uploaded client documents, ticket attachments and invoice PDFs on that same dedicated data disk.
  • A unique administrator password, database password and TLS certificate generated on the first boot of every VM.
  • Scheduled jobs (mail queue, ticket email parser, domain and certificate refresh) on a systemd timer rather than a public web endpoint.
  • Hardening past a stock install: the web installation wizard is deleted, and PHP cannot execute from the writable uploads tree.

Prerequisites

  • An Azure subscription and permission to create virtual machines.
  • The Azure CLI installed and signed in (az login), if you deploy from the command line.
  • An SSH key pair for the VM administrator account (azureuser).
  • Inbound TCP 443 (and 80 for the redirect) open to the clients and staff who will use ITFlow, plus TCP 22 for administration.

Step 1 - Deploy from the Azure Marketplace

Find ITFlow 26.07 IT Documentation and MSP Management on Ubuntu 24.04 LTS by SecureAnyCloud in the Azure Marketplace and select Get It Now. Choose your subscription, resource group and region.

Keep the recommended Standard_B2s size or larger. Set the administrator username to azureuser with your SSH public key, and allow inbound 443, 80 and 22. The image attaches its own 20 GiB data disk automatically.

Step 2 - Deploy from the Azure CLI

az vm image terms accept --urn sac1647283583153:itflow-ubuntu-24-04:default:latest
az vm create \
  --resource-group my-itflow-rg \
  --name my-itflow-vm \
  --image sac1647283583153:itflow-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
az vm open-port --resource-group my-itflow-rg --name my-itflow-vm --port 443 --priority 1001
az vm open-port --resource-group my-itflow-rg --name my-itflow-vm --port 80 --priority 1002

First boot installs ITFlow for this VM. It generates the TLS certificate, creates the database, creates your administrator account and writes the credentials to a root-only file. This takes roughly 15 to 30 seconds after the VM reports as running.

Step 3 - Confirm the services are running

SSH in as azureuser and confirm that Apache and MariaDB are up, the scheduler is armed, and the ports are as expected. ITFlow answers on 443. MariaDB is bound to loopback only and is not reachable from outside the VM.

systemctl is-active apache2 mariadb
active active
systemctl is-enabled itflow-scheduler.timer
enabled
sudo ss -tlnp | grep -E ':443 |:80 |:3306 ' | sed 's/ */ /g' | cut -c1-90
LISTEN 0 80 127.0.0.1:3306 0.0.0.0:* users:(("mariadbd",pid=991,fd=23)) LISTEN 0 511 *:443 *:* users:(("apache2",pid=5675,fd=6),("apache2",pid=5535,fd=6),("apache LISTEN 0 511 *:80 *:* users:(("apache2",pid=5675,fd=4),("apache2",pid=5535,fd=4),("apache2

Check that the health endpoint answers over HTTPS and that plain HTTP redirects to it:

curl -ks -o /dev/null -w 'https /healthz -> HTTP %{http_code}\n' https://127.0.0.1/healthz
curl -s -o /dev/null -w 'http / -> HTTP %{http_code} -> %{redirect_url}\n' http://127.0.0.1/
https /healthz -> HTTP 200 http / -> HTTP 301 -> https://127.0.0.1/

/healthz is deliberately left reachable over plain HTTP, so an Azure load balancer probe works without following a redirect. Everything else on port 80 redirects to 443.

Step 4 - Retrieve the per-VM administrator password

No password ships in the image. Your instance generated its own on first boot and wrote it to a file that only root can read.

sudo cat /root/itflow-credentials.txt

The file gives you ITFLOW_ADMIN_EMAIL, ITFLOW_ADMIN_PASSWORD and the internal database credentials. The sign-in account is admin@example.com. You can change that address once you are signed in.

Step 5 - Sign in

Browse to https:// followed by your VM's public IP address or DNS name.

Your browser warns you that the certificate is not trusted. This is expected: the appliance generated a self-signed certificate for your instance at first boot, because no image can know the DNS name you will put in front of it. Accept the warning to continue, or go to "Installing your own TLS certificate" below to replace it first.

Sign in with the email and password from Step 4.

If you see the message "Login is restricted as ITFlow defaults to HTTPS only for enhanced security", you browsed to http:// rather than https://. Use HTTPS.

Step 6 - Set the base URL that emailed links are built from

Do this before you invite any client. ITFlow builds the links it emails (ticket portal links, invoice and quote links, guest share links, and new-user password setup links) from a single setting called $config_base_url. First boot sets it to the address your VM could prove it had. On Azure this is the private IP, because Azure's instance metadata service does not report a VM's public IP address.

Check the current value:

grep -E '^\$config_base_url' /var/www/itflow/config.php
$config_base_url = '10.0.0.5';

When the VM has the public DNS name or IP that your clients will use, set it here. Substitute your own hostname for <your-domain>:

sudo sed -i "s|^\$config_base_url = .*|\$config_base_url = '<your-domain>';|" /var/www/itflow/config.php grep -E '^\$config_base_url' /var/www/itflow/config.php

Every ITFlow installation has to make this choice. It is not specific to this image. Signing in and using the product works regardless, but emailed links point at whatever this value says.

Step 7 - The dashboard

After you sign in, you land in the agent interface. The dashboard summarises income, expenses and profit, recurring revenue, unbilled tickets and new clients, with a cash flow chart. Use the Financial and Technical toggles at the top to show each panel.

Change your administrator password now. Open the user menu at the top right and choose My Preferences. The password from Step 4 is a bootstrap credential that is unique to your instance, and replacing it with your own is good practice.

Step 8 - Add your first client

Clients are the object that everything else in ITFlow hangs from. Select Clients in the sidebar, then New Client. Give the client a name and a primary contact, then select Create Client.

Open the client to reach its overview. It shows the client's contacts, locations, assets, licences, credentials, networks, racks, certificates and domains, alongside its tickets, quotes, invoices and billing position, plus a running activity log.

Credentials stored against a client are encrypted. Your own password unwraps the encryption key when you sign in. This is why ITFlow asks you to sign in again after a password change, and why nobody with only database access can read the credentials.

Step 9 - Tickets

Select Tickets to reach the support queue. Tickets can be raised by hand, through the client portal, or created automatically from inbound email once you connect a mailbox under Admin, Mail Settings. The mail queue and the ticket email parser run automatically on this image (see Step 11).

Step 10 - No known or default credentials

This image contains no administrator account at all. Rather than shipping a preinstalled copy whose password would have to be rotated, ITFlow installs itself on your instance at first boot and creates the administrator with a password generated at that moment.

The ordering is deliberate. ITFlow derives the credential vault's encryption key from the administrator password, so the per-instance password has to be the original password rather than a replacement.

You can verify the result on your own VM. The round trip below signs in against the real login form with the password from the credentials file:

sudo bash /usr/local/sbin/itflow-cred-roundtrip.sh
PASS: the credential in /root/itflow-credentials.txt authenticates (index.php -> https://127.0.0.1/agent/clients.php)

The paths that upstream protects with .htaccess files are denied by the web server configuration on this image. This includes the guard that stops PHP executing from the writable uploads tree. Probe them:

for p in /config.php /scripts/setup_cli.php /cron/cron.php /uploads/probe.php /plugins/vendor/autoload.php /setup/; do printf '%-32s HTTP %s\n' "$p" "$(curl -ks -o /dev/null -w '%{http_code}' https://127.0.0.1$p)" done
/config.php HTTP 403 /scripts/setup_cli.php HTTP 403 /cron/cron.php HTTP 403 /uploads/probe.php HTTP 403 /plugins/vendor/autoload.php HTTP 403 /setup/ HTTP 404

/setup/ returns 404 because the web installation wizard is deleted from this image rather than merely disabled. Upstream leaves it in the web root, gated by a configuration flag. It is an unauthenticated database configuration endpoint, and this image does not need it.

Step 11 - The scheduled jobs

ITFlow needs scheduled jobs for its mail queue, inbound ticket email parsing, and domain and certificate expiry refresh. Upstream asks you to add these to a crontab. This image runs them from a systemd timer every five minutes, so no public web endpoint exists for an anonymous visitor to trigger.

Confirm that the timer is enabled:

systemctl is-enabled itflow-scheduler.timer
enabled

Run a pass by hand at any time:

sudo systemctl start itflow-scheduler.service
sudo systemctl is-active itflow-scheduler.timer

Step 12 - Verify the stack and where your data lives

The certificate is issued for your instance and is valid for a year. Check its subject and dates:

sudo openssl x509 -in /etc/ssl/sac/itflow.crt -noout -subject -dates
subject=C = GB, O = sac, CN = 10.0.0.5 notBefore=Jul 16 18:40:00 2026 GMT notAfter=Jul 16 18:40:00 2027 GMT

Both the database and your uploaded client documents live on the dedicated data disk, not the OS disk, so you can snapshot and grow them independently. Check the mounts:

findmnt -no SOURCE,TARGET,FSTYPE,SIZE /data
findmnt -no SOURCE,TARGET /var/lib/mysql
findmnt -no SOURCE,TARGET /var/www/itflow/uploads
/dev/sda /data ext4 19.5G /dev/sda[/mysql] /var/lib/mysql /dev/sda[/itflow-uploads] /var/www/itflow/uploads

Read the installed schema version:

sudo mariadb --protocol=socket -uroot -N -e "SELECT CONCAT('ITFlow database schema ', config_current_database_version) FROM itflow.settings"
ITFlow database schema 2.4.4

Installing your own TLS certificate

The self-signed certificate keeps traffic encrypted from the first second, but browsers warn about it. When your VM has a public DNS name, replace the certificate.

To use a certificate you already hold, copy the certificate and key onto the VM. The Apache configuration already reads these two paths, so replacing their contents is all you need to do:

sudo cp <your-domain>.crt /etc/ssl/sac/itflow.crt
sudo cp <your-domain>.key /etc/ssl/sac/itflow.key
sudo chown root:root /etc/ssl/sac/itflow.key
sudo chmod 0600 /etc/ssl/sac/itflow.key
sudo apache2ctl configtest
sudo systemctl restart apache2

To use Let's Encrypt, point a DNS A record at the VM and open port 80. Then run:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d <your-domain>

Certbot writes its own certificate paths into the Apache configuration and renews automatically. After either route, set $config_base_url to the same hostname as in Step 6, so that emailed links match the certificate.

Backing up

Your data is the MariaDB database plus the uploads tree, and both are on /data. The simplest protection is an Azure snapshot of the data disk. For a logical dump of the database, run:

sudo mariadb-dump --protocol=socket -uroot --single-transaction itflow > ~/itflow-backup.sql

ITFlow also has a backup feature in the admin area that packages the database and uploads together.

Security notes

  • No credential ships in the image. ITFlow is installed on your instance at first boot, so there is no default account, no shipped password hash and no database in the image to inherit one from.
  • HTTPS only. ITFlow refuses to present a sign-in form over plain HTTP, and this image honours that. Port 443 serves the product, port 80 only redirects, and the session cookie is marked Secure and HttpOnly.
  • The credential vault is bound to your password. The site encryption key is sealed with a key derived from the administrator password, so database access alone does not reveal stored client credentials.
  • MariaDB is loopback only. It listens on 127.0.0.1:3306 and is not reachable from outside the VM.
  • The installer is gone. The web installation wizard is deleted from the web root, not merely disabled.
  • No PHP execution in the uploads tree. Client documents and ticket attachments land in a writable directory, so the web server is configured to refuse to execute anything from it.
  • Scheduled jobs are not web-reachable. They run from a systemd timer through the PHP command line interface.
  • No telemetry. The appliance is installed with telemetry off and does not phone home. Opting in stays your choice, in the admin settings.
  • Restrict access. Limit inbound 443 and 22 to the networks that need them, and replace the self-signed certificate before exposing ITFlow to clients.

Trademark

ITFlow is a trademark of its respective owners. SecureAnyCloud is not affiliated with, endorsed by, or sponsored by the ITFlow project. This image packages the unmodified open source ITFlow release, which is distributed under the GNU General Public License version 3, together with SecureAnyCloud's configuration and hardening. The ITFlow name is used here solely to identify the software included in this image.

Support

SecureAnyCloud provides 24/7 technical support for this image by email (sales@secureanycloud.com) and live chat, with a one-hour average response time for critical issues. We help with deployment, TLS certificate installation, mail and ticket parsing setup, the client portal, invoicing and recurring billing, upgrades, backup and restore, and MariaDB administration.

Deploy on Azure

Launch ITFlow 26.07 IT Documentation and MSP Management 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

Deploy on Azure