Fa
Applications Azure

FacturaScripts on Ubuntu 24.04 on Azure User Guide

| Product: FacturaScripts on Ubuntu 24.04 LTS on Azure

Overview

FacturaScripts is an open source ERP and invoicing platform for small and medium businesses. It handles the commercial cycle end to end: customers and suppliers, quotes, orders, delivery notes and invoices, along with inventory, taxes, receipts and double entry accounting. It is a PHP web application backed by MariaDB, with a plugin architecture that lets you extend it without forking the core. It originated in Spain and is widely used across Spain and Latin America.

This cloudimg image is a complete, hardened FacturaScripts appliance on a fully patched Ubuntu 24.04 LTS base. Apache 2 serves port 80 and dispatches PHP to a PHP 8.3 FPM pool; MariaDB 10.11 listens only on the loopback interface. The interface is configured in English, and there is no default login anywhere in the image: the MariaDB root password, the application database password and the FacturaScripts administrator password are all generated uniquely on the first boot of each VM. The complete database schema is materialised during that first boot, so the application is ready to invoice immediately rather than building tables as you click. Your database and your uploaded documents each live on their own dedicated Azure data disk. Backed by 24/7 cloudimg support.

What is included:

  • FacturaScripts 2026.6, the current upstream release, licensed LGPL-3.0
  • Apache 2.4 on port 80, dispatching PHP to PHP FPM over a unix socket
  • PHP 8.3 FPM with every extension FacturaScripts requires, including mysqli, bcmath, gd, mbstring, intl, zip, curl, simplexml and opcache
  • MariaDB 10.11, bound to 127.0.0.1 only and never exposed to the network
  • The full FacturaScripts schema, materialised on first boot so your first invoice does not fail on a missing table
  • Interface language set to English
  • A per VM FacturaScripts administrator password, a per VM application database password and a per VM MariaDB root password, recorded in a root only file
  • A /cloudimg-status.php page that proves Apache, PHP FPM and MariaDB are all working together
  • Two dedicated Azure data disks: one for the database at /var/lib/mysql, one for the application and its uploaded documents at /var/www
  • apache2.service, php8.3-fpm.service and mariadb.service as enabled systemd units
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 cloudimg support

Prerequisites

  • An Azure subscription with permission to create virtual machines
  • An SSH key pair for administrative access to the VM
  • A network security group allowing inbound TCP 22 (SSH) and TCP 80 (HTTP) from the addresses you will use

Step 1 - Deploy from the Azure Marketplace

Search the Azure Marketplace for FacturaScripts on Ubuntu 24.04 LTS by cloudimg, choose Create, and select the Standard_B2s size or larger. Provide your SSH public key for the azureuser account and allow inbound ports 22 and 80.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group my-resource-group \
  --name facturascripts-01 \
  --image cloudimg:facturascripts:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

# Then open HTTP to the addresses you will browse from:
az vm open-port --resource-group my-resource-group --name facturascripts-01 --port 80

Step 3 - Confirm FacturaScripts is running

SSH to the VM and confirm every tier is up. Apache deliberately does not start until the first boot service has written this VM's configuration, so all four units being active is also the proof that first boot completed.

systemctl is-active apache2 php8.3-fpm mariadb facturascripts-firstboot

Expected output:

active
active
active
active

Confirm what is listening. Port 80 is served to the network; MariaDB is bound to the loopback address only and is never reachable from outside the VM.

ss -tln | grep -E ':80 |:3306 '

The apache2, php8.3-fpm, mariadb and facturascripts-firstboot services all active, with Apache listening on port 80 and MariaDB bound to loopback 127.0.0.1:3306

Step 4 - Retrieve this VM's credentials

Every password is generated on this VM's first boot and written to a root only file. Nothing is shared with any other deployment of this image.

sudo cat /root/facturascripts-credentials.txt

The file records the FacturaScripts sign in details, the application database credentials and the MariaDB root password, together with the URL to browse to.

The per VM credentials file listing the FacturaScripts administrator user and password, the application database name, user and password, and the MariaDB root password, with the passwords masked

Read just the administrator password when you need it:

sudo grep '^FACTURASCRIPTS_ADMIN_PASSWORD=' /root/facturascripts-credentials.txt | cut -d= -f2-

Step 5 - Sign in to FacturaScripts

Browse to the VM's public address. FacturaScripts presents its sign in page in English.

http://<public-ip>/

Sign in with the user admin and the password from Step 4.

The FacturaScripts sign in page, rendered in English, asking for a user name and password

You can confirm the sign in works from the command line as well. This reads the generated password, requests the login form, submits it, and checks that FacturaScripts issued a session:

ADMIN_PASS=$(sudo grep '^FACTURASCRIPTS_ADMIN_PASSWORD=' /root/facturascripts-credentials.txt | cut -d= -f2-)
CJ=$(mktemp)
TOKEN=$(curl -s -c "$CJ" http://127.0.0.1/login | grep -oE 'name="multireqtoken" value="[^"]+"' | head -1 | cut -d'"' -f4)
curl -s -o /dev/null -b "$CJ" -c "$CJ" -d action=login -d fsNick=admin \
  --data-urlencode "fsPassword=$ADMIN_PASS" -d "multireqtoken=$TOKEN" http://127.0.0.1/login
grep -q fsLogkey "$CJ" || { echo "error: sign in was rejected"; rm -f "$CJ"; exit 1; }
echo "SIGN_IN_OK"
rm -f "$CJ"

Expected output:

SIGN_IN_OK

Step 6 - Complete the company setup wizard

The first time you sign in, FacturaScripts opens its setup wizard. This is the product's own first run step and it is intentionally left for you, because the details it asks for are yours: it collects your country, your company name and address, and your tax identification and default tax rate. Nothing in the wizard is a credential, and it is only reachable once you have signed in with this VM's administrator password.

Choose your country, then enter your company name and address and save. FacturaScripts then unlocks the full menu.

Step 7 - Create your first customer

From the menu choose Customers, then New. Enter the customer's name, business name, tax number and email, and save. FacturaScripts confirms with Record updated correctly! and assigns the customer a code.

A FacturaScripts customer record created and saved, showing the confirmation message, the assigned customer name and the contact and commercial detail fields

The saved customer appears in the customer list, read straight back out of MariaDB:

The FacturaScripts customer list showing the newly saved customer with its code, tax number and email address

Step 8 - Raise your first sales invoice

Choose Invoices under Sales, then New. FacturaScripts opens its customer picker; choose the customer you created. Add lines with the Line button, or type a product reference, then save.

FacturaScripts assigns the document a number from the active series and records it against the customer:

A FacturaScripts sales invoice saved and numbered F2026A1, showing the customer, series, date, payment method and the line entry area

The invoice is then listed in the sales invoice ledger, with its code, customer, total, paid state and date:

The FacturaScripts sales invoice ledger listing invoice F2026A1 against the customer, with its total, paid status and date

Step 9 - Verify the stack end to end

Three separate systemctl is-active checks can all pass while the application is broken, so this image ships a status page that exercises the whole path in a single request: Apache accepts it, PHP FPM executes it, and it runs real queries against the FacturaScripts schema in MariaDB.

curl -s http://127.0.0.1/cloudimg-status.php | grep -o 'FACTURASCRIPTS_STATUS_OK' || { echo "error: the end to end check did not pass"; exit 1; }

Expected output:

FACTURASCRIPTS_STATUS_OK

Browse to http://<public-ip>/cloudimg-status.php to see the same check rendered, including the MariaDB version, the PHP runtime and SAPI, the application database, the administrator account read back from the database and the number of tables in the schema.

There is also a static health endpoint with no authentication, suitable for an Azure Load Balancer probe:

curl -sI http://127.0.0.1/healthz | head -1

Step 10 - Component versions

apache2 -v | head -1
php -v | head -1
mariadb --version

The Apache, PHP and MariaDB versions with the FacturaScripts release, the healthz endpoint returning 200, and the end to end status page round trip

Step 11 - Where your data lives

Two dedicated Azure data disks are captured into the image and re-provisioned on every VM, so the database and the application tier are independently resizable and survive an OS disk swap.

findmnt -no SOURCE,TARGET,FSTYPE /var/lib/mysql
findmnt -no SOURCE,TARGET,FSTYPE /var/www

/var/lib/mysql holds the MariaDB datadir, which is where every invoice, customer, supplier and accounting entry is stored. /var/www holds the application itself at /var/www/facturascripts, including MyFiles, where FacturaScripts keeps uploaded attachments and generated documents.

df -h /var/lib/mysql /var/www

Both dedicated ext4 data disks, one holding the MariaDB datadir at /var/lib/mysql and one holding the application at /var/www, with MariaDB bound to loopback and the materialised schema size

Step 12 - Review the database accounts

MariaDB is reachable only from the VM itself:

grep -h bind-address /etc/mysql/mariadb.conf.d/*.cnf | tail -1

On box maintenance needs no password, because root@localhost authenticates through the unix socket rather than a password:

sudo mariadb -e "SELECT user, host, plugin FROM mysql.user ORDER BY user, host;"

The application connects as the least privilege fsuser account, which has rights on the facturascripts database only. There are no anonymous accounts, and the packaged debian-sys-maint account is removed at build time.

Confirm the schema was fully materialised on first boot:

sudo mariadb -N -B -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='facturascripts';"

Language and regional settings

The image sets the FacturaScripts interface language to English, and the administrator account is created with English as its language. FacturaScripts is a Spanish origin project, so a small number of upstream strings and some seeded reference data, such as the default payment method names, still read in Spanish; you can rename that reference data to suit your business from the settings menu. The dashboard also shows a community news feed that FacturaScripts fetches live from facturascripts.com, which is published in Spanish.

To change the interface language for a user, open the user's profile from the top right menu and set the language there. Additional translations ship with the application.

Enabling HTTPS with Let's Encrypt

FacturaScripts handles financial data, so put it behind TLS before you use it in production. Point a DNS name at the VM's public address, open port 443, and then:

sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d your-domain.example --agree-tos -m you@your-domain.example --redirect

certbot obtains the certificate, configures the Apache virtual host and installs a renewal timer.

Security notes

  • No default login. The MariaDB root password, the application database password and the FacturaScripts administrator password are all generated on this VM's first boot. The published admin/admin default that a manual FacturaScripts installation would create is never valid on this image.
  • The installer wizard is never exposed. Apache is held back by a systemd condition until the first boot service has written this VM's configuration, so there is no window in which FacturaScripts' database setup wizard is reachable from the internet.
  • The database is not on the network. MariaDB binds to 127.0.0.1 only. Do not add port 3306 to your network security group.
  • Configuration is not web readable. config.php carries the database password; it is 0640 root:www-data on disk and denied by Apache.
  • Change the administrator password from the user profile once you have signed in, and create a named user per person rather than sharing the admin account.
  • Keep the VM patched with sudo apt-get update && sudo apt-get upgrade; unattended security upgrades are enabled by default.
  • Restrict inbound port 80 and 443 to the networks that need them, and keep SSH restricted to your management range.

Support

cloudimg provides 24/7 support for this image. Contact support@cloudimg.co.uk with the VM name and region, and include the output of sudo cat /root/facturascripts-credentials.txt with the passwords removed if the issue relates to first boot.