If you run Kubernetes, Docker Compose, or other self-hosted apps, you need one secure place for API keys, database credentials, and TLS keys. This guide shows how to self-host OpenBao on Ubuntu as a secrets server, with Raft storage, TLS, policies, auth methods, and backups.
Self-Hosting OpenBao on Ubuntu: TLS, Raft Storage & Backups
Table of Contents
- What OpenBao Is and Why Dev Mode Is Not a Server
- Prerequisites to Self-Host OpenBao on Ubuntu
- Step 1: Install the Latest OpenBao Release
- Step 2: Create a Dedicated Service Account and Directories
- Step 3: Configure Raft Storage and TLS
- Step 4: Create the systemd Service
- Step 5: Initialize and Unseal
- Step 6: Plan Auto-Unseal Before You Go to Production
- Step 7: Enable a Secrets Engine, Policies, and Auth Methods
- Step 8: Automate Snapshot Backups
- Step 9: Verify Recovery From a Snapshot
- Conclusion

What OpenBao Is and Why Dev Mode Is Not a Server
OpenBao is an open-source and Linux Foundation-governed fork of HashiCorp Vault. It stores and encrypts secrets, certificates, and credentials through the bao CLI and API, which work like the vault command.
Most tutorials use bao server -dev, which runs in memory with a fixed root token. It is fine for testing, but everything is lost on restart, and there's no TLS. For real use, you can run bao server -config=<file> with a persistent Raft directory, TLS, and a proper unseal strategy.
Knowing this difference, dev mode vs. a real server, is the key first step before storing any real secrets.
Prerequisites to Self-Host OpenBao on Ubuntu
Before you self-host OpenBao on Ubuntu, make sure you have:
- Ubuntu 22.04 or 24.04 LTS with sudo access. A small VPS is enough for a single-node setup handling typical app and Kubernetes secrets. You can check PerLod's Linux VPS hosting plans for a reliable and low-latency option.
- A DNS record pointing to the server's public IP.
If you expect heavy Raft write traffic, multiple teams, or plan to add HA nodes later, move to a dedicated server instead of a VPS.
Step 1: Install the Latest OpenBao Release
The most reliable way to self-host OpenBao on Ubuntu with the newest stable build is to fetch the precompiled binary directly from GitHub releases. To do this, run the commands below:
In the output, you should see something similar to this:
Step 2: Create a Dedicated Service Account and Directories
Don't run OpenBao as root. Create a limited system user and locked-down data folders instead:
The /opt/openbao/data folder holds the Raft log and encrypted state. It's essentially the whole database, so its permissions matter just as much as your TLS certificates.
Step 3: Configure Raft Storage and TLS
OpenBao's Integrated Storage uses the Raft algorithm to keep a durable and replicated copy of your data on disk. This is the core configuration step for a real persistent backend instead of the in-memory dev store.
Use your favorite text editor to create the /etc/openbao/openbao.hcl file:
Add with your actual domain:
Key settings:
cluster_addris required with Raft storage. OpenBao needs it to coordinate nodes, even with just one.- Don't add a separate
ha_storageblock withstorage "raft"; Raft can't run alongside another HA backend. - Handling TLS inside OpenBao itself, not just at a proxy, means secrets are never sent over plaintext, which is safer for a service built around secrecy.
Obtain a certificate with certbot and copy it into place:
Create the following script on your server, so renewed certificates get picked up automatically:
Make it executable:
Tips: If you prefer not managing certificates yourself, you can put Caddy or another reverse proxy in front, set the listener to 127.0.0.1:8200 with tls_disable = true, and let the proxy handle TLS automatically. Either way, keep port 8200 blocked from the public internet.
Step 4: Create the systemd Service
At this point, use your desired text editor to create the systemd unit file:
Add:
Disable swap, then enable and start the service:
A healthy log shows the listener starting on port 8200 and the node waiting to be unsealed. This sealed state is normal, unlike dev mode, where it unseals itself automatically.
Step 5: Initialize and Unseal
Point the CLI to your TLS endpoint and initialize the cluster. This is the most important step of self-hosting OpenBao on Ubuntu. It generates the unseal keys and root token that control access to everything else.
Save all five unseal key shares and the root token somewhere offline and encrypted. Losing them means losing access to every secret stored on the node.
OpenBao starts sealed by default. It can find its data but cannot decrypt it until you provide enough unseal keys. Use three of your five unseal keys, entering them one at a time:
Log in with the root token and confirm the node is healthy:
Step 6: Plan Auto-Unseal Before You Go to Production
Manually entering three unseal keys after every reboot is not practical. A reboot can leave OpenBao offline until someone unseals it. Auto-unseal solves this by using a trusted external service to unseal OpenBao automatically.
Here are the auto-unseal methods you can use:
With Auto-Unseal, OpenBao gives you recovery keys instead of normal unseal keys. Recovery keys can help with tasks like regenerating the root token, but they cannot decrypt OpenBao if your KMS, HSM, or Transit server is unavailable.
For a self-hosted setup, you can run a small second OpenBao instance as a Transit auto-unseal server for your main OpenBao server.
Add the seal configuration only after choosing your Auto Unseal method. For example, a Transit seal pointed at a second instance:
Moving from normal unseal keys to Auto Unseal needs short downtime. Take a fresh backup first and plan it as a maintenance task.
Step 7: Enable a Secrets Engine, Policies, and Auth Methods
With the node unsealed, turn on the KV v2 engine and write a test secret:
Write a least-privilege policy so applications never touch the root token. Create app-readonly.hcl:
Add:
Apply it and enable an auth method for machines or humans to log in with:
For human access, use userpass or OIDC/JWT login instead of sharing static tokens. Policies and auth methods let Docker Compose, K3s, and ArgoCD access only the secrets they need without hardcoding credentials.
Step 8: Automate Snapshot Backups
Raft stores all OpenBao data, so a Raft snapshot is a full server backup. You do not need to back up a separate database. Start by creating a manual snapshot:
Create a backup token that can only manage snapshots; never use the root token. Then use cron to run the backup every day:
Add:
Copy .snap backups to a different location, such as S3 storage, another server, or a backup VPS. A backup on the same server is useless if that server or disk fails. Before storing real secrets, make sure you have verified off-server backups.
Step 9: Verify Recovery From a Snapshot
A backup is only reliable if you have tested restoring it. Test recovery on the same server or on a separate test server:
With an empty Raft data folder, OpenBao starts as a new and uninitialized server. Initialize and unseal it first, then restore your snapshot:
After the restore completes, confirm your earlier secret and policies came back exactly as they were:
If both commands show the expected data, your backup and recovery process works. This proves you can restore OpenBao successfully after a failure.
Conclusion
You now have OpenBao running with Raft storage, TLS, limited-access policies, and tested backups. Monitor it, keep off-server backups, install updates, and plan Auto Unseal before an unexpected reboot.
We hope you enjoy this guide.
For more details about Raft storage, backups, and cluster management, see the official OpenBao documentation.
Mostly, yes. OpenBao is a Linux Foundation fork of Vault, and its bao CLI and API work similarly, so most Vault setups need only small changes.
No. One node with Raft storage is enough for most self-hosted setups. You can add more nodes later for high availability.
No. Dev mode stores everything in memory, uses no TLS, and resets on every restart. It's only for local testing, never for real secrets.