Skip to main content
Administrator holding a laptop during a security review

How to Self-Host Bitwarden on a VPS

October 1, 2025 · Blog / Technical Guides

Self-hosting Bitwarden gives the administrator responsibility for the server, domain, TLS, updates, mail delivery, monitoring, and recovery. The safest starting point is Bitwarden's standard Linux deployment rather than mixing that workflow with the separate Unified deployment.

This guide follows the official Linux installation instructions, networking requirements, and server backup guidance.

Plan the deployment

Prepare a dedicated VPS, a domain you control, and DNS records pointing to the server. Bitwarden's standard deployment expects ports 80 and 443 and does not support installation in a domain subdirectory.

Create and securely store the installation ID and key requested by the installer. These values are deployment credentials; do not put them in the article, source control, shell history, or screenshots.

Use an external SMTP provider for invitations and account messages. Virtarix does not provide a managed email-hosting service, so sender authentication, deliverability, and provider credentials remain the administrator's responsibility.

Prepare the host and firewall

Install Docker Engine using Docker's official Linux instructions, then verify it before creating the Bitwarden account:

“`bash title="Verify the Docker service and client" sudo systemctl –no-pager –full status docker sudo docker version


Allow SSH before enabling UFW, then open the web ports required by Bitwarden:

```bash title="Allow SSH HTTP and HTTPS through UFW"
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Docker-published ports can bypass rules that appear to block them in UFW. Apply matching restrictions at the provider firewall and verify public exposure from another network.

Create the dedicated local account and add it to the Docker group:

“`bash title="Create the dedicated Bitwarden service account and directory" sudo adduser bitwarden sudo usermod -aG docker bitwarden sudo install -d -o bitwarden -g bitwarden -m 0750 /opt/bitwarden


Membership in the Docker group is effectively administrative access to the host. Limit the account to Bitwarden maintenance, protect its SSH keys, and do not share it among operators.

## Install Bitwarden

Sign in as the `bitwarden` account, change to `/opt/bitwarden`, download the official helper script over HTTPS, and inspect it before execution:

```bash title="Download protect and inspect the Bitwarden helper script"
cd /opt/bitwarden
curl -Lso bitwarden.sh 'https://func.bitwarden.com/api/dl/?app=self-host&platform=linux'
chmod 700 bitwarden.sh
less bitwarden.sh

Confirm that the final download host and script content match Bitwarden's official installation page. If they do not, remove the file and investigate rather than executing it.

Run the standard deployment installer:

“`bash title="Run the Bitwarden deployment installer" ./bitwarden.sh install


Enter the prepared domain and installation credentials when prompted. Choose Bitwarden's managed certificate option only when DNS is correct and ports 80 and 443 reach this server; otherwise follow the official certificate guidance for the certificate method you control.

## Start and verify the vault

Start the stack and check its container state:

```bash title="Start Bitwarden and list running containers"
./bitwarden.sh start
docker ps --format 'table {{.Names}}\t{{.Status}}'

Open the configured domain over HTTPS and confirm that the certificate matches it. Create the first user through the web vault's normal registration flow if registration is enabled; the /admin area is a separate administration surface and is not the user-account creation workflow.

After account creation, decide whether public registration should remain enabled. Test sign-in, vault lock and unlock, item creation, and synchronization with a non-administrator account before storing important credentials.

Configure mail and administrator access

Set SMTP values through the Bitwarden configuration files and helper workflow documented for the standard deployment. Keep the SMTP password out of screenshots and source control, then send a test message and verify delivery.

Protect the administration portal according to Bitwarden's documentation. Restrict who receives administrator access, use a strong unique token where required, and avoid placing the portal behind an unauthenticated public shortcut.

Review application and container logs from the server when troubleshooting. Do not claim that every event appears in one log file; identify the component involved and use Bitwarden's documented logging paths.

Back up the complete deployment

Bitwarden's bwdata directory contains the deployment configuration and application data that must be considered together. The built-in database job alone is not a complete server recovery plan, so follow the official backup inventory and preserve the full required data set.

Before a maintenance backup, confirm that the target filesystem has enough free space and that a separate copy exists for the previous recovery point. The example below assumes the deployment is running when the procedure begins and that GnuPG is installed. It stops the stack, creates an encrypted archive outside /opt/bitwarden, verifies that the archive decrypts and lists successfully, then restores the running state:

“`bash title="Create and verify an encrypted Bitwarden backup" set -euo pipefail cd /opt/bitwarden BACKUPDIR="${HOME}/bitwarden-backups" BACKUPID="$(date -u +%Y%m%dT%H%M%SZ)" ARCHIVE="${BACKUPDIR}/bwdata-${BACKUPID}.tar.gz.gpg" install -d -m 0700 "${BACKUPDIR}" gpg –version >/dev/null restartbitwarden() { ./bitwarden.sh start || true; } recoveronexit() { exitstatus=$? trap – EXIT if [ "${exitstatus}" -ne 0 ]; then rm -f — "${ARCHIVE}" fi restartbitwarden exit "${exitstatus}" } trap recoveronexit EXIT ./bitwarden.sh stop if ! tar –create –gzip –file – bwdata | gpg –symmetric –cipher-algo AES256 –output "${ARCHIVE}"; then rm -f "${ARCHIVE}" exit 1 fi chmod 0600 "${ARCHIVE}" if ! gpg –decrypt "${ARCHIVE}" | tar –list –gzip –file – >/dev/null; then rm -f "${ARCHIVE}" exit 1 fi ./bitwarden.sh start trap – EXIT docker ps –format 'table {{.Names}}\t{{.Status}}'


GnuPG prompts interactively for the archive passphrase. Use a unique high-entropy secret from an approved password manager or offline escrow; never place it in the command, an environment variable, shell history, or the backup directory. The recovery trap is installed before the stop command, attempts to restart Bitwarden after any unsuccessful state-changing step, and removes a partial or unverifiable archive before preserving the original failure status.

Copy the encrypted archive to a separate backup system through an authenticated encrypted channel, keep the decryption secret under separate custody, and retain the previous recovery point until the new copy is verified off-host. Test restoration on an isolated VPS by decrypting into a temporary path, then verify ownership, configuration, TLS, database state, attachments, and account sign-in before treating the backup as usable. Never overwrite the only working `bwdata` directory during a restore test.

## Update and recover

Read Bitwarden's [on-premises update instructions](https://bitwarden.com/help/updating-on-premise/) and make a verified recovery point before updating. Update the helper script and deployment through the supported commands:

```bash title="Update the Bitwarden helper and deployment"
cd /opt/bitwarden
./bitwarden.sh updateself
./bitwarden.sh update

After the update, check containers, HTTPS, sign-in, synchronization, mail delivery, and logs. If verification fails, preserve the failed state for diagnosis and restore the tested bwdata recovery point on an isolated host before replacing production data.

Do not delete containers, volumes, or bwdata as an early troubleshooting step. Capture the helper output and component logs first, then follow Bitwarden's documented recovery path.

Next steps

Document the domain owner, DNS, installation credential owner, SMTP provider, administrator access, archive location, and restore-test date.

Planning a private Bitwarden vault?

Choose a Virtarix Cloud VPS for the complete Bitwarden stack, application data, and recovery workspace.

VPS S

For small sites, dev servers and Docker

$ 5 .50 /month
  • 3 cores
  • 6 GB
  • 50 GB NVMe
  • Unlimited
Get It Now
BEST SELLER

VPS M

For growing apps, websites and staging

$ 11 .40 /month
  • 6 cores
  • 16 GB
  • 100 GB NVMe
  • Unlimited
Get It Now
Peter French
About the Author Peter Frenchis the Managing Director at Virtarix, with over 17 years in the tech industry. He has co-founded a cloud storage business, led strategy at a global cloud computing leader, and driven market growth in cybersecurity and data protection.