Skip to content
appsgit

Deploy guide

How to self-host Vaultwarden with Docker Compose

Deploy Vaultwarden, the lightweight Bitwarden-compatible server, with Docker Compose: HTTPS setup, Argon2 admin token, signups, backups and safe upgrades.

  • Updated
  • Beginner
  • About 15 minutes

You will need

  • 1 vCPU / 512 MB RAM
  • Docker + Docker Compose v2
  • A domain name with HTTPS (required by Bitwarden clients)

What is Vaultwarden?

Vaultwarden is an alternative server for the Bitwarden password manager, written in Rust and designed to run on very small machines. It is open source under the GPL-3.0 license and works with the official Bitwarden browser extensions, desktop apps and mobile apps. It is not affiliated with Bitwarden, Inc.

Requirements

  • Any Linux server: 1 vCPU and 512 MB of RAM is plenty for a family or small team.
  • Docker Engine and Docker Compose v2.
  • A domain name and HTTPS. The web vault uses browser crypto APIs that only work in a secure context, so plain HTTP does not work except on localhost.

Step 1: Prepare the server

This guide assumes Ubuntu 24.04 with Docker installed. If not, follow the Docker Engine install guide. Create a folder:

mkdir -p ~/vaultwarden && cd ~/vaultwarden

Before writing the Compose file, generate a hashed admin token. Vaultwarden supports Argon2 hashes for ADMIN_TOKEN, so the plain password is never stored on disk:

docker run --rm -it vaultwarden/server:latest /vaultwarden hash

Enter a strong admin password twice. The command prints a string starting with $argon2id$. Keep the password in your password manager. You will type it on the /admin page.

Step 2: Create the Docker Compose file

Save this as docker-compose.yml:

services:
  vaultwarden:
    image: vaultwarden/server:1.37.4
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.example.com"
      SIGNUPS_ALLOWED: "true"
      INVITATIONS_ALLOWED: "true"
      SHOW_PASSWORD_HINT: "false"
      ADMIN_TOKEN: "CHANGE_ME"
      LOG_FILE: "/data/vaultwarden.log"
      TZ: "Europe/London"
    volumes:
      - ./vw-data:/data
    ports:
      - "127.0.0.1:8080:80"

Replace CHANGE_ME with the Argon2 string from Step 1. Docker Compose treats $ as the start of a variable, so double every dollar sign in the hash ($argon2id$v=19$... becomes $$argon2id$$v=19$$...). If you prefer to keep it out of the Compose file, put ADMIN_TOKEN='...' in a .env file with single quotes and reference it as ${ADMIN_TOKEN}. DOMAIN must match the exact public URL, including https://, or attachments, WebAuthn and email links will break.

The port is bound to 127.0.0.1 on purpose: Vaultwarden should only be reached through the HTTPS proxy.

Step 3: Start and open the app

docker compose up -d
docker compose logs -f vaultwarden

Vaultwarden starts in a second or two. Complete Step 4, then open https://vault.example.com and click "Create account". This account is a normal user. The admin panel is separate, at https://vault.example.com/admin, and uses the admin password you hashed.

Once your own account and your family or team accounts exist, set SIGNUPS_ALLOWED: "false" and run docker compose up -d again. New users can then join only by invitation from an organization or the admin panel. Configure SMTP in the admin panel so invitations and two-step login emails work.

Step 4: Put it behind HTTPS

With Caddy on the host:

vault.example.com {
    encode zstd gzip
    reverse_proxy 127.0.0.1:8080 {
        header_up X-Real-IP {remote_host}
    }
}

Caddy obtains the certificate automatically. Since version 1.29, Vaultwarden serves WebSocket notifications on the same port, so no extra route for port 3012 is needed. With Nginx Proxy Manager, point a proxy host at port 8080, request a Let's Encrypt certificate, and enable "Websockets Support".

Backups and upgrades

Everything lives in ./vw-data: the SQLite database db.sqlite3, attachments/, sends/, config.json (settings saved from the admin panel) and rsa_key* files. For a consistent database copy while the container runs, use the built-in backup command:

docker compose exec vaultwarden /vaultwarden backup

Then copy the whole vw-data folder off-site with restic, Borg or rclone, encrypted. Test a restore at least once.

Upgrade with:

docker compose pull && docker compose up -d

If you pinned a version, change the tag first after reading the release notes.

Troubleshooting

  • Web vault shows a blank page or crypto error: you are on plain HTTP. Use your HTTPS domain.
  • Admin page says the token is invalid: the $ signs in the Argon2 hash were not doubled in the Compose file, so Compose mangled the value. Check with docker compose config.
  • Settings in docker-compose.yml are ignored: values saved in the admin panel go into config.json and override environment variables. Change them in the panel or delete the key from config.json.
  • Mobile app cannot log in: make sure the self-hosted server URL in the app exactly matches DOMAIN.

Next steps

Enable two-step login for every account, set up an organization for shared passwords, add fail2ban rules against the Vaultwarden log, and schedule automatic encrypted backups.

Spotted something out of date? Tell us and we will update the guide.

FAQ

Vaultwarden questions

Still curious? Email info@appsgit.com.

What port does Vaultwarden use?

Inside the container Vaultwarden listens on port 80. You normally map it to a local port such as 8080 and put an HTTPS reverse proxy in front, because Bitwarden clients and the web vault require HTTPS.

Is Vaultwarden free?

Yes. Vaultwarden is free and open source under the GPL-3.0 license, and it unlocks Bitwarden features such as organizations and TOTP storage without a paid plan.

Is Vaultwarden safe to use?

Vaultwarden stores only end-to-end encrypted vault data, so the server never sees your master password. Your real risk is server hygiene: use HTTPS, disable open signups, hash the admin token and keep backups.

Vaultwarden vs Bitwarden: what is the difference?

Vaultwarden is an unofficial, community-written server that implements the Bitwarden API in Rust. It uses a fraction of the resources of the official Bitwarden server and works with the official Bitwarden apps and browser extensions.

How do I hash the Vaultwarden ADMIN_TOKEN?

Run docker run --rm -it vaultwarden/server /vaultwarden hash, enter a password, and paste the resulting Argon2 PHC string into ADMIN_TOKEN. In a Compose file, escape every dollar sign as a double dollar sign.