Bitwarden is an open-source password manager with end-to-end encrypted vaults and clients for browsers, desktop and mobile. In this tutorial you will install the official self-hosted Bitwarden server on Ubuntu 24.04 using the bitwarden.sh installer, which runs the whole stack (web vault, API, identity service, SQL Server and Nginx) in Docker and obtains a Let's Encrypt certificate. You will then configure email, create your account, close public registration and back up the data.
NoteIf you want something lighter for a few users, Vaultwarden is a community server compatible with the Bitwarden clients that runs in a single small container. This guide covers the official server.
Prerequisites
To follow this guide you need:
- A server running Ubuntu 24.04 LTS (x86_64) with at least 2 GB of RAM (4 GB recommended) and 12 GB of free disk, for example a CubePath VPS. The bundled Microsoft SQL Server container is the reason for the memory requirement.
- A non-root user with
sudoprivileges. - A domain name, referred to as
your_domain(for examplevault.example.com), with a DNS A record pointing toyour_server_ip. - Ports 80 and 443 free on the server. Bitwarden runs its own Nginx container, so don't install another web server on these ports.
- An SMTP account to send email. Bitwarden uses email for account verification, invitations and passwordless login to the admin portal.
Step 1 - Installing Docker Engine and Docker Compose
The installer requires Docker Engine and the Compose plugin. Install them from Docker's official repository, starting with the repository key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
Add the repository and install the packages:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Verify the installation:
sudo docker compose version
Docker Compose version v2.x.x
Step 2 - Opening the firewall
Allow SSH, HTTP (needed for the Let's Encrypt challenge) and HTTPS:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Step 3 - Creating a dedicated bitwarden user
Bitwarden recommends running the installation under its own account rather than root. Create the user and add it to the docker group so it can manage the containers:
sudo adduser bitwarden
sudo usermod -aG docker bitwarden
Create the installation directory and restrict it to that user:
sudo mkdir /opt/bitwarden
sudo chmod 700 /opt/bitwarden
sudo chown bitwarden:bitwarden /opt/bitwarden
Switch to the new user; the login shell picks up the docker group membership:
sudo -iu bitwarden
cd /opt/bitwarden
docker ps
docker ps should print an empty table header instead of a permission error.
Step 4 - Getting an installation ID and key
Every self-hosted server needs an installation ID and key, which are free. Open bitwarden.com/host, enter an email address, choose your data region (US or EU), and copy the Installation ID and Installation Key it shows. The installer asks for both values.
Step 5 - Running the installer
As the bitwarden user, download the installer script from Bitwarden:
curl -Lso bitwarden.sh "https://func.bitwarden.com/api/dl/?app=self-host&platform=linux"
chmod 700 bitwarden.sh
It is a shell script, so read it before running it:
less bitwarden.sh
Start the installation:
./bitwarden.sh install
Answer the prompts:
- Domain name:
your_domain. - Use Let's Encrypt:
y, then the email address for expiry notices. The installer requests the certificate through port 80 and renews it when you run the update command. - Database name: a name for the database, for example
vault. - Installation ID and Installation Key: the values from Step 4.
- Region:
USorEU, the one you picked on the website.
The installer pulls the images and writes all configuration and data under /opt/bitwarden/bwdata.
Step 6 - Configuring SMTP and the admin account
Bitwarden reads environment overrides from bwdata/env/global.override.env. Open it:
nano /opt/bitwarden/bwdata/env/global.override.env
Set the SMTP values from your mail provider, and list the email addresses that may sign in to the System Administrator Portal:
[email protected]
globalSettings__mail__smtp__host=smtp.example.com
globalSettings__mail__smtp__port=587
globalSettings__mail__smtp__ssl=false
globalSettings__mail__smtp__username=your_smtp_user
globalSettings__mail__smtp__password=your_smtp_password
[email protected]
Use ssl=false with port 587 (STARTTLS is negotiated automatically) or ssl=true with port 465. Leave the other lines in the file as the installer wrote them.
Start Bitwarden:
./bitwarden.sh start
The first start takes a few minutes while SQL Server initialises and the database is created. Check the containers:
docker ps --format 'table {{.Names}}\t{{.Status}}'
You should see containers such as bitwarden-nginx, bitwarden-web, bitwarden-api, bitwarden-identity, bitwarden-admin and bitwarden-mssql, all Up and eventually (healthy).
Step 7 - Creating your account
Open https://your_domain in a browser. The certificate should be valid and issued by Let's Encrypt. Click Create account, enter your email and a strong master password, and log in.
The master password encrypts your vault on the client side. Nobody, including the server administrator, can recover it, so store it somewhere safe and enable two-step login under Settings > Security > Two-step login once you are in.
Check the admin portal at https://your_domain/admin. Enter an address from adminSettings__admins and Bitwarden emails you a one-time login link. This also confirms that SMTP works.
Step 8 - Disabling public sign-ups
After you and your team have accounts, stop strangers from registering on your server. Add this line to global.override.env:
globalSettings__disableUserRegistration=true
Restart to apply it:
./bitwarden.sh restart
New users can still join through an invitation to an organization. Free organizations are limited to two members; larger teams, groups and SSO require a paid license file, which you upload in the admin portal.
Step 9 - Backing up the vault data
Everything Bitwarden needs to restore the server lives in /opt/bitwarden/bwdata: configuration, certificates, attachments and the database. The bitwarden-mssql container also writes a nightly database backup to bwdata/mssql/backups.
Copy the whole bwdata directory to another location regularly. For example, exit the bitwarden shell and create a compressed archive as root:
exit
sudo tar -czf /var/backups/bitwarden-$(date +%F).tar.gz -C /opt/bitwarden bwdata
To schedule it, create a cron file that archives every night and keeps two weeks:
echo '30 3 * * * root tar -czf /var/backups/bitwarden-$(date +\%F).tar.gz -C /opt/bitwarden bwdata && find /var/backups -name "bitwarden-*.tar.gz" -mtime +14 -delete' | sudo tee /etc/cron.d/bitwarden-backup
The archive contains the vault encryption keys and database, so copy it to an encrypted, off-server location.
Updating Bitwarden
Update the script itself first, then the containers. The update also renews the Let's Encrypt certificate when needed:
sudo -iu bitwarden
cd /opt/bitwarden
./bitwarden.sh updateself
./bitwarden.sh update
Run it at least monthly: Bitwarden releases security fixes frequently, and certificates expire after 90 days if you never run update.
Troubleshooting
- The Let's Encrypt step fails during install: DNS for
your_domaindoes not point to the server yet, or port 80 is blocked or used by another web server. Fix it and run./bitwarden.sh installagain. - Containers restart repeatedly: usually SQL Server running out of memory. Check
docker logs bitwarden-mssqland make sure the server has at least 2 GB of RAM plus swap. - No verification or admin login emails arrive: check the SMTP values and
docker logs bitwarden-apifor mail errors, and confirm your provider allows outbound SMTP on the port you chose. - Changes in
global.override.envhave no effect: run./bitwarden.sh restart. For changes inbwdata/config.yml, run./bitwarden.sh rebuildand then./bitwarden.sh start.
Conclusion
The official Bitwarden server is now running on Ubuntu 24.04 with a valid certificate, working email, closed registration and a nightly backup of bwdata. Next, install the browser extension and mobile apps and point them to https://your_domain in the region/server selector at login, turn on two-step login for every user, and schedule ./bitwarden.sh update so the server stays patched.
