# Vaultwarden: Self-Hosted Password Management with Docker

[Vaultwarden](https://github.com/dani-garcia/vaultwarden) is **an open-source, community-maintained implementation of the Bitwarden server API, written in Rust**. It is fully compatible with all official Bitwarden clients (web, browser extension, desktop, and mobile), runs on minimal hardware, and uses under 100 MB of RAM. All features that Bitwarden reserves for paid tiers, including TOTP storage and the CLI, are available without restriction.

![Vaultwarden GitHub page showing its open-source community-driven development](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/8be24c72-0be2-4d99-e0e7-3daadd7e9d00/lg2x =1280x720)

## Why self-host instead of using a cloud password manager

<iframe width="100%" height="315" src="https://www.youtube.com/embed/NLmYjFe_Gg4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>



Commercial password managers store your encrypted vault on their servers. For most users this is acceptable, but it introduces a third-party dependency and ongoing subscription costs. Bitwarden's official self-hosted option exists but is designed for enterprise deployments and requires more resources than an individual or small team typically needs.

Vaultwarden targets a different use case: a single developer or small team who wants complete data ownership, zero per-month cost, and the ability to run the server on a Raspberry Pi or a local development machine.

The tradeoff is infrastructure responsibility. You manage the server, backups, and updates.

### What a developer's vault typically contains

![Graphic illustrating the types of credentials a developer manages: logins, tokens, SSH keys, and 2FA codes](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/81ebe7d6-40cd-4206-5fcf-ab83b762e000/lg1x =1280x720)

Beyond website logins, a developer's vault typically holds API tokens, SSH keys, TOTP secrets for two-factor authentication, and secure notes containing database credentials or configuration details. Having programmatic access to these through a CLI is what makes Vaultwarden particularly useful in a development workflow.

## Setting up Vaultwarden with Docker

### Prerequisites

[Docker](https://docs.docker.com/get-docker/) and Docker Compose are required. A basic understanding of the command line is assumed.

### Project directory and compose file

Create a dedicated directory for the configuration and data:

```command
mkdir ~/vaultwarden
```

```command
cd ~/vaultwarden
```

Create `docker-compose.yml`:

```command
nano docker-compose.yml
```

```yaml
[label docker-compose.yml]
version: '3.8'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - ./vw-data:/data
    environment:
      - DOMAIN=http://localhost:8080
      - SIGNUPS_ALLOWED=true
      - ADMIN_TOKEN=YOUR_SECURE_TOKEN_HERE
```

![The docker-compose.yml file displayed in the nano text editor](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/a0241013-304f-44fa-1f14-4b6340566000/lg2x =1280x720)

Key points in this configuration:

- `restart: unless-stopped` ensures the container restarts after a system reboot unless manually stopped.
- `ports: "8080:80"` maps host port `8080` to container port `80`. Change `8080` to any available host port.
- `volumes: ./vw-data:/data` persists vault data to `./vw-data` on the host. Without this, all data is lost if the container is removed.
- `SIGNUPS_ALLOWED=true` should be set to `false` after creating your own account to prevent unauthorized registrations.
- `ADMIN_TOKEN` sets the password for the admin panel at `/admin`.

### Generating a secure admin token

Replace `YOUR_SECURE_TOKEN_HERE` with the output of:

```command
openssl rand -base64 48
```

Copy the generated string into `docker-compose.yml` and save the file.

### Starting the container

```command
docker compose up -d
```

Docker downloads the image on first run, then starts the container in the background. Verify it is running:

```command
docker ps
```

![Terminal output showing "Container vaultwarden Started" confirming a successful launch](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/42c69ce6-e615-4bee-9b78-2e29e29b3200/lg2x =1280x720)

## Accessing the vault

### Creating an account

Navigate to `http://localhost:8080` and click **Create account**. Choose a strong master password. Vaultwarden is a zero-knowledge system: the server cannot recover a forgotten master password. If you lose it, the vault data is irrecoverable.

![Main Vaultwarden web interface after login showing an empty vault ready for use](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/1c5ede95-e61d-4db8-84a0-9d8887a1ff00/lg1x =1280x720)

### Browser extension setup

Install the official [Bitwarden extension](https://bitwarden.com/download/) from your browser's extension store. By default it connects to Bitwarden's cloud. Click the gear icon in the extension's login window and set the **Server URL** to `http://localhost:8080`, then save.

![Bitwarden extension settings page highlighting the Server URL field where the self-hosted address is entered](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/f335ebe7-2d8a-4bf7-2d06-6a61f94ff900/lg2x =1280x720)

Log in with the credentials from the web vault. The extension will now auto-fill and save credentials against your local instance.

## CLI integration

The Bitwarden CLI (`bw`) connects to any Bitwarden-compatible server and allows programmatic access to vault contents, which is useful for scripting and automation.

### Installation

On macOS with Homebrew:

```command
brew install bitwarden-cli
```

On other systems via npm:

```command
npm install -g @bitwarden/cli
```

### Configuring and logging in

Point the CLI at the local server:

```command
bw config server http://localhost:8080
```

Log in:

```command
bw login your.email@example.com
```

After a successful login, the CLI outputs a session key. Export it to keep the vault unlocked for the current terminal session:

```command
export BW_SESSION="your_session_key_here"
```

### Fetching credentials

With the session key set, credentials are accessible by name:

```command
bw get password Github
```

![Terminal showing the command bw get password Github and the resulting password output](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/1bf19dd8-40fd-4764-e507-fa9360d5f200/orig =1280x720)

This makes it practical to pull credentials into deployment scripts without hardcoding them:

```bash
[label deploy.sh]
DOCKER_USER=$(bw get username "My Docker Hub Login")
DOCKER_PASS=$(bw get password "My Docker Hub Login")

echo $DOCKER_PASS | docker login --username $DOCKER_USER --password-stdin my.private.registry.com
```

Credentials are fetched at runtime from the vault rather than stored in the script or in environment files.

## Final thoughts

Vaultwarden is a practical choice for developers who want the Bitwarden client ecosystem without a cloud dependency or recurring cost. **The Docker setup takes a few minutes, the resource footprint is minimal, and the CLI integration covers most automation use cases**.

The main ongoing commitment is keeping the container updated and maintaining a backup strategy for the `./vw-data` directory. For a single developer, a periodic backup of that directory to an encrypted off-site location is sufficient.

Full configuration options, including HTTPS setup, SMTP for email notifications, and multi-organization support, are documented in the [Vaultwarden wiki](https://github.com/dani-garcia/vaultwarden/wiki).