Bacula
Overview
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 that restores can be browsed and performed precisely, and everything is driven from the bconsole management console.
This SecureAnyCloud image installs Bacula 13.0.4 from the Ubuntu 24.04 archive and runs the Director, a Storage Daemon, a local File Daemon and a PostgreSQL 16 catalog together on one Azure VM. It is a self-contained backup appliance that backs itself up out of the box with a ready-to-run BackupClient1 job. You point the File Daemons of your other servers at it to protect them too.
What you get:
- 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
BackupClient1demo backup job writing to a file-based Storage volume in/var/lib/bacula/backups, so you can run a real backup and restore in seconds - A first boot that builds a fresh catalog and brings up all three daemons, leaving the appliance ready to run backup, restore and verify jobs from
bconsole. The demo backup job (BackupClient1) and a file-based Storage volume are already configured - Per-instance Director, Storage, File daemon and catalog passwords generated on first boot and written
0600to/root/bacula-credentials.txt. The Ubuntu Bacula packages bake per-install passwords into the daemon configuration files and the catalog. SecureAnyCloud replaces every one of them on the first boot of every VM, so no two instances share a login and no upstream default survives into the image - All daemons and the catalog bound to loopback for a secure default
Prerequisites
- An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
- A subscription to the Bacula listing on Azure Marketplace
- Network security group (NSG) rules that allow TCP 22 for administration. The single-node appliance needs no product ports open to the internet. Backing up remote clients uses daemon ports that 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. Choose a larger size for large catalogs, many concurrent jobs or a heavy backup workload.
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.
Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:bacula-ubuntu-24-04:default:latest
az vm create \
--resource-group my-rg \
--name bacula-01 \
--image sac1647283583153:bacula-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardFirst boot
On the first boot of every VM, bacula-firstboot.service generates unique per-instance daemon and catalog passwords and renders the /etc/bacula configuration from templates. It then 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.
Confirm the daemons are running
SSH in as azureuser. Confirm that 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 bconsoleAll four services should report active, and the Director should report its version, resources and scheduled jobs.
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 bconsoleBacula queues the job, connects the Director to the Storage Daemon and File Daemon over TLS, and writes the data to a volume. It then reports Termination: Backup OK with the number of files and bytes written.
Inspect the catalog
The catalog records every job and volume. List the completed jobs and the backup volumes:
printf 'list jobs\nquit\n' | sudo bconsole printf 'list volumes\nquit\n' | sudo bconsolelist jobs shows each job with its status, where T means the job terminated normally. list volumes shows the file-based volumes that the Storage Daemon has written, with their sizes.
Restore files
Restore runs 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 bconsoleBacula reads the volume back through the Storage Daemon and writes the files under the where directory. Confirm that the restored files are in place:
echo "restored files: $(sudo find /var/lib/bacula/restores -type f | wc -l)"For a selective restore, run restore interactively in bconsole. Use the file tree browser (mark, unmark, estimate, done) to pick exactly which files or directories to recover. Set where=/ to restore in place.
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 example 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 you edit the configuration, apply it:
printf 'reload\nquit\n' | sudo bconsoleRetrieve this VM's unique credentials
First boot stores the per-instance Director, Storage, File daemon and catalog passwords in a root-only file. You do not need them for day-to-day console use, because bconsole reads its own configured password. Use them when you need to connect to the catalog directly or reconfigure a daemon:
sudo cat /root/bacula-credentials.txtYou can also query the catalog directly with the per-instance database password, over loopback only. This command 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;"Security recommendations
- Keep daemons on loopback. Keep the Bacula daemons and the PostgreSQL catalog bound to loopback. When you add remote clients, expose the Storage and File daemon ports (9101-9103) only to your backup network, through a tightly scoped NSG rule.
- Protect the credentials file. The per-instance passwords in
/root/bacula-credentials.txtare unique to this VM. Treat the file as sensitive and keep it0600. - Use dedicated data disks in 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 that backups have real capacity. - Keep the OS patched. The image ships fully updated, with unattended security upgrades enabled.
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.
SecureAnyCloud images include 24/7 support. For 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 sales@secureanycloud.com and our team will help you get up and running.
Deploy on Azure
Launch Bacula 13.0.4 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
Overview
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 that restores can be browsed and performed precisely, and everything is driven from the bconsole management console.
This SecureAnyCloud Amazon Machine Image installs Bacula 13.0.4 and runs the Director, a Storage Daemon, a local File Daemon and a PostgreSQL 16 catalog together on one instance. It is a self-contained backup appliance that backs itself up out of the box with a ready-to-run BackupClient1 job. You point the File Daemons of your other servers at it to protect them too.
What you get:
- Bacula 13.0.4 (Director, Storage Daemon, File Daemon, bconsole), run under systemd
- A PostgreSQL 16 catalog, built fresh with a unique password on each instance's first boot, on a dedicated EBS volume mounted at
/var/lib/postgresql - A ready-to-run
BackupClient1backup job writing to a file-based Storage volume in/var/lib/bacula/backups. Backup volumes and restore staging live on a second dedicated EBS volume mounted at/var/lib/bacula - Both EBS volumes kept separate from the operating system disk and mounted by filesystem UUID, so you can grow, snapshot or move your backup storage independently of the OS
- Per-instance Director, Storage, File daemon and catalog passwords generated on first boot and written
0600to/root/bacula-credentials.txt. The Bacula packages bake per-install passwords into the daemon configuration files and the catalog. SecureAnyCloud replaces every one of them on the first boot of every instance, so no two instances share a login and no upstream default survives into the image - All daemons and the catalog bound to loopback, and the backup ports closed in the shipped Security Group, for a secure default
Connecting to your instance
Connect over SSH on TCP port 22 with your EC2 key pair. The login user depends on the operating system variant you launched.
OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<public-ip>Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for administrator SSH access to the instance
- A VPC and subnet in the target Region, with a Security Group that allows inbound TCP port 22 from your administrator network. The single-node appliance needs no product ports open to the internet. Backing up remote clients uses daemon ports that you open deliberately (see Step 8)
- The AWS CLI version 2 installed locally, if you plan to deploy from the command line
Recommended instance type: m5.large is a sensible starting point for the Director, daemons and catalog on a single node. Choose a larger type for large catalogs, many concurrent jobs or a heavy backup workload.
Launch the Instance from the AWS Marketplace
Subscribe to the product in AWS Marketplace, then choose Continue to Launch. Select your instance type (m5.large is a sensible starting point), your VPC and subnet, and your EC2 key pair. Attach a Security Group that allows inbound TCP 22 from your administrator network. You do not need to open any other ports to launch.
The image provisions the dedicated catalog and backup data volumes automatically, so you do not need to attach them manually. For larger backup storage, increase the size of the backup data volume at launch, or grow it later.
Launch the Instance from the AWS CLI
You can also launch from the command line. Replace the AMI ID, key name, subnet and security group with your own values.
aws ec2 run-instances \
--image-id ami-xxxxxxxxxxxxxxxxx \
--instance-type m5.large \
--key-name your-key \
--subnet-id subnet-xxxxxxxx \
--security-group-ids sg-xxxxxxxx \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=bacula-01}]'First boot
On the first boot of every instance, bacula-firstboot.service generates unique per-instance daemon and catalog passwords and renders the /etc/bacula configuration from templates. It then builds a fresh PostgreSQL catalog on the dedicated data volume and starts the Director, Storage Daemon and File Daemon.
First boot completes in a few seconds. The unique credentials for this instance are written to /root/bacula-credentials.txt.
Confirm the daemons are running
SSH in and confirm that 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 bconsoleAll four services should report active, and the Director should report its version, resources and scheduled jobs.
Run a backup and restore
The appliance ships a ready-to-run backup job, BackupClient1, that backs up the local File Daemon to the file-based Storage on the dedicated backup volume. Run it now and wait for it to finish:
printf 'run job=BackupClient1 yes\nwait\nmessages\nquit\n' | sudo bconsoleBacula queues the job, connects the Director to the Storage Daemon and File Daemon over TLS, and writes the data to a volume. It then reports Termination: Backup OK with the number of files and bytes written.
Restore runs from the same console. This command restores everything from the most recent backup job into /var/lib/bacula/restores, waits for it to finish, then counts the restored files:
JID=$(printf 'list jobs\nquit\n' | sudo bconsole | awk '/BackupClient1/ {j=$1} END{print j}') printf "restore jobid=$JID where=/var/lib/bacula/restores all done\nyes\nwait\nmessages\nquit\n" | sudo bconsole echo "restored files: $(sudo find /var/lib/bacula/restores -type f | wc -l)"Bacula reads the volume back through the Storage Daemon and writes the files under the where directory, then reports Termination: Restore OK. The screenshot below shows a full round trip: a known file is backed up, deleted, restored from the catalog and confirmed identical by SHA-256.
For a selective restore, run restore interactively in bconsole. Use the file tree browser (mark, unmark, estimate, done) to pick exactly which files or directories to recover. Set where=/ to restore in place.
Inspect the catalog
The catalog on the dedicated database volume records every job and volume. List the completed jobs and the backup volumes:
printf 'list jobs\nquit\n' | sudo bconsole printf 'list volumes\nquit\n' | sudo bconsolelist jobs shows each job with its status, where T means the job terminated normally. list volumes shows the file-based volumes that the Storage Daemon has written, with their sizes.
Review the security posture
First boot stores the per-instance Director, Storage, File daemon and catalog passwords in a root-only file. You do not need them for day-to-day console use, because bconsole reads its own configured password. Use them when you need to connect to the catalog directly or reconfigure a daemon. Confirm the file permissions and that every daemon is bound to loopback:
sudo stat -c '%a %U:%G %n' /root/bacula-credentials.txt ss -tln | grep -E '9101|9102|9103|5432'The credentials file is 0600 root:root, and the Director (9101), File Daemon (9102), Storage Daemon (9103) and PostgreSQL catalog (5432) are all bound to 127.0.0.1 only. Nothing backup-related is reachable off the instance until you deliberately open it.
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 instance's address and open the daemon ports (9101-9103) only to your backup network.
The following example 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 instance address so remote FDs can reach it:
# edit SDAddress in /etc/bacula/bacula-sd.conf, then restart, and open
# ports 9101-9103 to your backup network only in the EC2 Security Group.After you edit the configuration, apply it:
printf 'reload\nquit\n' | sudo bconsoleRetrieve this instance's unique credentials
You can query the catalog directly with the per-instance database password, over loopback. This command reads the unique password from the credentials file at runtime, so you never type a secret on the command line:
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;"Security recommendations
- Keep daemons on loopback. Keep the Bacula daemons and the PostgreSQL catalog bound to loopback. When you add remote clients, expose the Storage and File daemon ports (9101-9103) only to your backup network, through a tightly scoped Security Group rule.
- Protect the credentials file. The per-instance passwords in
/root/bacula-credentials.txtare unique to this instance. Treat the file as sensitive and keep it0600. - Use the dedicated volumes. The catalog and backup volumes are already on dedicated EBS data volumes, separate from the OS disk. Grow the backup volume as your footprint increases, and snapshot it for off-instance retention.
- Keep the OS patched. The image ships fully updated, with unattended security upgrades enabled.
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. The verbatim license text and a written offer for the corresponding source are included in the image under /usr/local/share/sac-bacula (LICENSE.AGPL-3.0 and SOURCE_OFFER.txt). You can also get the corresponding source directly on the instance with apt-get source bacula-director, or from the Bacula project at bacula.org.
SecureAnyCloud images include 24/7 support. For help deploying or configuring Bacula on AWS, contact us.
Need Help?
Email sales@secureanycloud.com and our team will help you get up and running.
Deploy on AWS
Launch Bacula on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com