FacturaScripts on Ubuntu 24.04 on Azure User Guide
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.1only 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.phppage 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.serviceandmariadb.serviceas enabled systemd units- An unauthenticated
/healthzendpoint 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 '

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.

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.

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.

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

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:

The invoice is then listed in the sales invoice ledger, with its code, customer, total, paid state 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

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

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/admindefault 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.1only. Do not add port 3306 to your network security group. - Configuration is not web readable.
config.phpcarries the database password; it is0640 root:www-dataon 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
adminaccount. - 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.