Databasus on Ubuntu 24.04 LTS: deployment guide for Azure
What this image gives you
This is Databasus 3.50.0, unmodified, on Ubuntu 24.04 LTS, packaged by cloudimg for the Azure Marketplace.
Databasus is an open source, self hosted backup tool for PostgreSQL. It takes scheduled physical and logical backups, streams write ahead log data for Point In Time Recovery, verifies that backups can actually be restored, applies retention policies, and pushes the results to storage you control: local disk, S3, Azure Blob Storage, Google Drive, SFTP and more. It also backs up MySQL, MariaDB and MongoDB.
The image ships two things:
| Component | What it is | Where it listens |
|---|---|---|
| Databasus 3.50.0 | The product: web interface plus REST API | Port 4005, all interfaces |
| PostgreSQL 17 | A bundled demo database, there to be backed up | 127.0.0.1 only, port 5432 |
The demo database exists so the appliance is useful the moment it boots: you can take a real backup, watch it succeed and confirm a restore without wiring anything up first. It is configured for Point In Time Recovery, not just simple dumps. When you are ready to protect your own databases you add them in the web interface and the demo database simply stops mattering.
Everything runs on a single VM. There is no cluster to plan and no external dependency.
Security posture, set on first boot
Two things about a stock Databasus install are unsafe on a public IP address, and this image closes both before the port ever accepts a request:
- Databasus creates an administrator called
adminwith no password. The endpoint that sets that password is unauthenticated and stays open until somebody uses it, so on a bare install the first person to reach the VM becomes the administrator. This image sets a unique administrator password on first boot, over the loopback interface, then verifies the endpoint is closed. - Databasus allows open self registration by default. Anyone reaching the VM could create a working account. This image turns self registration off. You can turn it back on in the web interface under Settings whenever you want.
Nothing is baked into the image. Every VM generates its own administrator password, its own demo database password and its own AES-256 encryption key on first boot.
1. Deploy the VM
Launch the image from the Azure Marketplace. A Standard_B2s (2 vCPU, 4 GiB) is the recommended size and is what this guide assumes.
Open port 4005 to the networks that need the web interface, and port 22 for SSH. Keep 4005 restricted to your own IP ranges where you can.
The bundled demo PostgreSQL is published on
127.0.0.1only. It is reachable from the VM itself and from the Databasus container, never from the network, so there is no database port to firewall.
2. Sign in
Your administrator password was generated for this VM. Read it over SSH:
sudo cat /root/databasus-credentials.txt

The file is 0600 root:root and contains the Databasus sign in details and the demo database password.
Now open http://<vm-ip>:4005/ in a browser and sign in with the login admin and the password from that file.

Change the administrator password once you are in, under Settings.
3. Confirm the appliance is healthy
Both services and both containers should be up:
systemctl is-active docker databasus databasus-firstboot
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'

Note the ports: Databasus is published on 0.0.0.0:4005, while the demo database is bound to 127.0.0.1:5432.
The application also answers a health endpoint and reports its version:
curl -s http://127.0.0.1:4005/api/v1/system/health -o /dev/null -w 'health: HTTP %{http_code}\n'
curl -s http://127.0.0.1:4005/api/v1/system/version
4. Verify the security posture
You can confirm both protections yourself. None of these should succeed:
# A protected endpoint with no session must be refused.
curl -s -o /dev/null -w 'no session: HTTP %{http_code}\n' -m 15 \
http://127.0.0.1:4005/api/v1/users/me
# Trying to seize the administrator account must be rejected.
curl -s -m 15 -X POST http://127.0.0.1:4005/api/v1/users/admin/set-password \
-H 'Content-Type: application/json' \
-d '{"password":"attacker-would-own-this-vm"}'
echo
# Trying to self register must be rejected.
curl -s -m 15 -X POST http://127.0.0.1:4005/api/v1/users/signup \
-H 'Content-Type: application/json' \
-d '{"name":"Stranger","email":"stranger@example.invalid","password":"StrangerPass123"}'
echo

You should see HTTP 401, admin password is already set and external registration is disabled.
And your own credentials should work. This reads the real password from the root only file, so it is a genuine end to end check:
sudo bash -c 'PASS=$(grep "^DATABASUS_ADMIN_PASSWORD=" /root/databasus-credentials.txt | cut -d= -f2-); \
TOKEN=$(curl -s -m 20 -X POST http://127.0.0.1:4005/api/v1/users/signin \
-H "Content-Type: application/json" \
-d "{\"email\":\"admin\",\"password\":\"$PASS\"}" | jq -r ".token"); \
[ -n "$TOKEN" ] && [ "$TOKEN" != "null" ] || { echo "sign in FAILED"; exit 1; }; \
echo "signed in, token issued"; \
curl -s -m 20 http://127.0.0.1:4005/api/v1/users/me -H "Authorization: Bearer $TOKEN" | jq -r ".email"'
5. Look at the bundled demo database
The demo database is a real PostgreSQL 17 with a seeded table, configured for Point In Time Recovery:
sudo bash -c 'export PGPASSWORD=$(grep "^DEMO_POSTGRES_PASSWORD=" /root/databasus-credentials.txt | cut -d= -f2-); \
psql -h 127.0.0.1 -p 5432 -U postgres -d demo \
-c "SHOW server_version" -c "SHOW wal_level" -c "SHOW summarize_wal"'

wal_level = logical and summarize_wal = on are what make Point In Time Recovery and PostgreSQL 17 incremental base backups possible. max_wal_senders and replication slots are configured too, and the pg_hba.conf permits password authenticated replication connections from the Databasus container.
The demo database itself starts empty. That is deliberate: the image ships no data of ours, so nothing from the build ever reaches your VM. Give it something to protect before you take your first backup:
sudo bash -c 'export PGPASSWORD=$(grep "^DEMO_POSTGRES_PASSWORD=" /root/databasus-credentials.txt | cut -d= -f2-); \
psql -h 127.0.0.1 -p 5432 -U postgres -d demo -v ON_ERROR_STOP=1 -c \
"CREATE TABLE IF NOT EXISTS cloudimg_demo (id bigserial PRIMARY KEY, payload text NOT NULL, created_at timestamptz NOT NULL DEFAULT now());" -c \
"INSERT INTO cloudimg_demo (payload) SELECT md5(random()::text) FROM generate_series(1, 500);" -c \
"SELECT count(*) AS demo_rows FROM cloudimg_demo;"'
That creates a small table and puts 500 rows in it, so the backup you take in the next step has real content and a measurable size.
6. Add a database and take a backup
In the web interface:
- Create a workspace (a workspace groups databases, storages and notifiers).
- Add a storage under the storage icon in the left rail.
Local diskkeeps backups on this VM's disk and needs no configuration. For anything you care about keeping, add S3, Azure Blob Storage or another off box destination instead, so a lost VM does not take the backups with it.

- Click Add database, give it a name and choose PostgreSQL.
- Choose the backup type:
- Logical runs a native dump. Simple, good under about 50 GB.
- Physical copies the cluster at file level and can stream write ahead log data, which is what gives you Point In Time Recovery and a much lower recovery point objective. Choose
Full + incremental + WALfor the full capability. - Enter the connection. For the bundled demo database, the host is
demo-postgres, the port is5432, the user ispostgresand the password is theDEMO_POSTGRES_PASSWORDfrom your credentials file.
The host is
demo-postgres, not127.0.0.1. Databasus runs in a container and reaches the demo database by its service name on the internal network.127.0.0.1inside the container means the container itself.
- When offered, accept create a replication only user. Databasus then stores a credential that can read your data but never modify it, so even a compromised Databasus cannot corrupt the database it protects.
- Pick your storage, schedule and retention, and save.
Your backup configuration then looks like this:

Click Make backup right now on the Backups tab to run one immediately rather than waiting for the schedule:

A finished backup shows as Successful with its size and duration. That is the whole loop working: Databasus connected to the database, read it, wrote the backup to your storage and recorded it.
7. Turn on restore verification
A backup you have never restored is a hope, not a backup. Databasus can prove it: on the Verifications tab you can have it restore a backup into a temporary copy on a schedule, count the rows in every table and report the result.
Restore verification uses a verification agent. Add one under Settings, in the Verification agents section, and Databasus will walk you through it. Until an agent is registered the Verifications tab tells you so.
8. Point Databasus at your own databases
The demo database is only a starting point. To protect a real database, add it exactly as in step 6 and give Databasus a connection to it. It needs to be reachable from this VM, so allow the Databasus VM's address in the target database's firewall and, for a physical backup, in its pg_hba.conf.
Databasus supports PostgreSQL 14 to 18 for both physical and logical backups, and MySQL, MariaDB and MongoDB for logical backups.
Two things worth doing on day one:
- Send backups off this VM. Add S3 or Azure Blob Storage as a storage destination. Backups on the same disk as the thing being backed up do not survive losing the disk.
- Turn on notifications. Email, Slack, Telegram, Discord and webhooks are all supported, and a failure you are not told about is a backup you do not have.
Databasus encrypts backups with AES-256 when you enable encryption on a backup configuration, so an off box destination stays useless to anyone who gets hold of it. Keep a copy of the encryption key from /databasus-data somewhere safe, because without it those backups cannot be restored.
Where things live
| Path | What |
|---|---|
/etc/databasus/compose.yaml |
Container definitions for both services |
/etc/databasus/databasus.env |
Per VM secrets, 0600 root:root |
/root/databasus-credentials.txt |
Sign in details, 0600 root:root |
/usr/share/doc/cloudimg/third-party-licences/ |
Databasus licence and NOTICE |
Useful commands:
sudo systemctl restart databasus
sudo docker logs --tail 50 databasus-databasus-1
Backups written to the Local disk storage, along with Databasus' own database and encryption key, live in the databasus_databasus_data Docker volume.
Support
Email support@cloudimg.co.uk.
Databasus is free and open source software licensed under the Apache License 2.0. "Databasus" is a trademark of Rostislav Dugin. cloudimg is not affiliated with, endorsed by, or sponsored by the Databasus project. PostgreSQL is a trademark of the PostgreSQL Community Association.