Bacula on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and use of Bacula on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Bacula is a mature, enterprise grade open source suite for backing up, restoring and verifying data across a network of machines. It is built from cooperating daemons: a Director (bacula-dir) that schedules and coordinates every job; a Storage Daemon (bacula-sd) that writes backup data to disk, tape or a virtual autochanger; and File Daemons (bacula-fd) that run on each protected machine. A catalog database records every job, file, volume and client so restores can be browsed and performed precisely, and everything is driven from the bconsole management console.
The image installs Bacula 13.0.4 from the Ubuntu 24.04 archive and runs the Director, a Storage Daemon writing to a file based volume, a local File Daemon and a PostgreSQL 16 catalog together on one node. It is a self contained backup appliance: it backs itself up out of the box (a ready to run BackupClient1 job), and you point the File Daemons of your other servers at it to protect them too.
Functional out of the box. On first boot the appliance builds a fresh catalog, brings up all three daemons and is immediately ready to run backup, restore and verify jobs from bconsole. A demo backup job (BackupClient1) and a file based Storage volume are configured so you can run a real backup and restore in seconds.
Secure by default — no shipped credentials. The Ubuntu Bacula packages bake per install passwords into the daemon config files and the catalog. cloudimg replaces every one of them on the first boot of every VM with unique per instance secrets written to a root only file, so no two instances ever share a login and no upstream default survives into the image. All daemons and the catalog are bound to loopback only.
What is included:
- Bacula 13.0.4 (Director, Storage Daemon, File Daemon, bconsole) from the Ubuntu 24.04 archive, run under systemd
- A PostgreSQL 16 catalog, built fresh with a unique password on each VM's first boot
- A ready to run
BackupClient1backup job writing to a file based Storage volume in/var/lib/bacula/backups - Per instance Director, Storage, File daemon and catalog passwords generated on first boot, written
0600to/root/bacula-credentials.txt - All daemons and the catalog bound to loopback for a secure default
Prerequisites
- Active Azure subscription, SSH public key, VNet + subnet in target region
- Subscription to the Bacula listing on Azure Marketplace
- Network Security Group rules allowing TCP 22 (admin). No product ports need to be open to the internet for the single node appliance; backing up remote clients uses the daemon ports you open deliberately (see Step 8)
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is ample for the Director, daemons and catalog on a single node. Size up for large catalogs, many concurrent jobs, or a heavy backup workload.
Step 1: Deploy from the Azure Portal
- Open the Bacula offer on the Azure Marketplace and choose Get It Now, then Create.
- Select your subscription, resource group and region, and choose the
Standard_B2ssize. - Provide your SSH public key for the
azureuseraccount. - Allow inbound TCP 22 from your admin network in the Network Security Group, then create the VM.
Step 2: Deploy from the Azure CLI
az vm create \
--resource-group my-rg \
--name bacula-01 \
--image <bacula-marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
Step 3: First boot
On the first boot of every VM, bacula-firstboot.service generates unique per instance daemon and catalog passwords, renders the /etc/bacula configuration from placeholder templates, builds a fresh PostgreSQL catalog, and starts the Director, Storage Daemon and File Daemon. First boot completes in a few seconds. The unique credentials for this VM are written to /root/bacula-credentials.txt.
Step 4: Confirm the daemons are running
SSH in as azureuser and confirm the three Bacula daemons and the catalog are active, then open the console and check the Director's status:
systemctl is-active bacula-director bacula-sd bacula-fd postgresql
echo 'status director' | sudo bconsole
You should see all four services report active, and the Director report its version, resources and scheduled jobs.

Step 5: Run a backup
The appliance ships a ready to run backup job, BackupClient1, that backs up the local File Daemon to the file based Storage. Run it now at full level and wait for it to finish:
printf 'run job=BackupClient1 level=Full yes\nwait\nmessages\nquit\n' | sudo bconsole
Bacula queues the job, connects the Director to the Storage Daemon and File Daemon over TLS, writes the data to a volume, and reports Termination: Backup OK with the number of files and bytes written.

Step 6: Inspect the catalog
Every job and volume is recorded in the catalog. List the completed jobs and the backup volumes:
printf 'list jobs\nquit\n' | sudo bconsole
printf 'list volumes\nquit\n' | sudo bconsole
list jobs shows each job with its status: T means the job terminated normally. list volumes shows the file based volumes the Storage Daemon has written, with their sizes.

Step 7: Restore files
Restore is driven from the same console. This one line restores everything from the most recent BackupClient1 job into /var/lib/bacula/restores on this machine and waits for it to finish:
sudo mkdir -p /var/lib/bacula/restores
printf 'restore client=bacula-fd fileset="Full Set" where=/var/lib/bacula/restores select all done\nyes\nwait\nmessages\nquit\n' | sudo bconsole
Bacula reads the volume back through the Storage Daemon and writes the files under the where directory. Confirm the restored files landed:
echo "restored files: $(sudo find /var/lib/bacula/restores -type f | wc -l)"
For a selective restore, run restore interactively in bconsole and use the file tree browser (mark, unmark, estimate, done) to pick exactly which files or directories to recover, and set where=/ to restore in place.
Step 8: Back up your own servers (remote File Daemons)
To protect other machines, install bacula-fd on each one and add a matching Client and Job to this Director. For security the appliance binds every daemon to loopback by default; to accept connections from remote File Daemons, bind the Storage Daemon to the VM's address and open the daemon ports (9101–9103) only to your backup network. The following is illustrative — adapt the names, addresses and passwords to your environment:
# 1. On THIS Director, add a Client + Job in /etc/bacula/bacula-dir.conf:
Client {
Name = webserver-fd
Address = 10.0.0.20 # the remote server's address
FDPort = 9102
Catalog = MyCatalog
Password = "<a-strong-shared-password>" # must match the remote bacula-fd.conf
}
Job {
Name = "Backup-webserver"
JobDefs = "DefaultJob"
Client = webserver-fd
}
# 2. On the REMOTE server (bacula-fd installed), in /etc/bacula/bacula-fd.conf,
# add a Director resource with the SAME name + password as this Director.
# 3. Bind this appliance's SD to the VM address so remote FDs can reach it:
# edit SDAddress in /etc/bacula/bacula-sd.conf, then restart, and open the
# NSG ports 9101-9103 to your backup network only.
After editing the configuration, apply it:
printf 'reload\nquit\n' | sudo bconsole
Step 9: Retrieve this VM's unique credentials
The per instance Director, Storage, File daemon and catalog passwords generated on first boot are stored in a root only file. You do not need them for day to day console use (bconsole reads its own configured password), but they are there when you need to connect to the catalog directly or reconfigure a daemon:
sudo cat /root/bacula-credentials.txt
You can also query the catalog directly with the per instance database password (loopback only). This reads the unique password from the credentials file at runtime:
DBPW=$(sudo grep '^BACULA_DB_PASSWORD=' /root/bacula-credentials.txt | cut -d= -f2-)
PGPASSWORD="$DBPW" psql -h 127.0.0.1 -U bacula -d bacula \
-c "SELECT jobid, name, level, jobstatus FROM job ORDER BY jobid DESC LIMIT 5;"

Step 10: Security recommendations
- Keep the Bacula daemons and the PostgreSQL catalog bound to loopback. Only expose the Storage and File daemon ports (9101–9103) to your backup network, via a tightly scoped NSG rule, when you add remote clients.
- The per instance passwords in
/root/bacula-credentials.txtare unique to this VM. Treat that file as sensitive and keep it0600. - Store backup volumes on dedicated data disks for production. The demo Storage writes to
/var/lib/bacula/backupson the OS disk; attach Azure managed disks, mount them, and point the Storage Daemon'sArchive Deviceat them so backups have real capacity. - Keep the OS patched. The image ships fully updated and with unattended security upgrades enabled.
Step 11: Support and Licensing
Bacula is free and open source software distributed under the GNU Affero General Public License, version 3 (AGPL-3.0). This image bundles Bacula unmodified; your use of Bacula is governed by its license.
cloudimg images include 24/7 support. If you need help deploying or configuring Bacula on Azure, contact us.
Deploy on Azure
Find this image on the Azure Marketplace and deploy in minutes.
Need Help?
Email support@cloudimg.co.uk and our team will help you get up and running.