---
navigation: true
title: Vaultwarden
main:
  fluid: false
---
:ellipsis{left=0px width=40rem top=10rem blur=140px}
# Vaultwarden

::alert{type="info"}
🎯 __Goals:__ Install [Vaultwarden](https://github.com/dani-garcia/vaultwarden) to manage your passwords across all your devices (a replacement for Google or Apple password managers).
::

![Vaultwarden](/img/serveex/vaultwarden.png)

[Vaultwarden](https://github.com/dani-garcia/vaultwarden) is a password management solution (generation, autofill...) that you can host directly on your server. This replaces managers like Google, Apple, or Keepass. Vaultwarden synchronizes your passwords across all your devices with end-to-end encryption.

Vaultwarden is a fork of [Bitwarden](https://bitwarden.com/fr-fr/help/).

## Installation
---
Folder structure:

```console
root
└── docker
    └── vaultwarden
        ├── data
        ├── compose.yaml
        └── .env
```

Open Dockge, click on `compose`, name the stack `vaultwarden`, and paste the following:

```yaml
---
services:
  vaultwarden:
    container_name: vaultwarden
    image: vaultwarden/server:latest
    restart: unless-stopped
    env_file:
      - .env
    volumes:
      - ./data/:/data/
    ports:
      - 3050:80
    environment:
      - DOMAIN=${URL}
      - LOGIN_RATELIMIT_MAX_BURST=10
      - LOGIN_RATELIMIT_SECONDS=60
      - ADMIN_RATELIMIT_MAX_BURST=10
      - ADMIN_RATELIMIT_SECONDS=60
      - ADMIN_TOKEN=${TOKEN}
      - SENDS_ALLOWED=true
      - EMERGENCY_ACCESS_ALLOWED=true
      - WEB_VAULT_ENABLED=true
      - SIGNUPS_ALLOWED=false
      - SIGNUPS_VERIFY=true
      - SIGNUPS_VERIFY_RESEND_TIME=3600
      - SIGNUPS_VERIFY_RESEND_LIMIT=5
```

::alert{type="success"}
✨ __Tip:__ Add the Watchtower label in each container to automate updates

```yaml
services:
  vaultwarden:
    #...
    labels:
      - com.centurylinklabs.watchtower.enable=true
```
::

Next, generate a password hash to put in the `TOKEN` variable in `.env`:

```shell
echo -n "yourpassword" | argon2 "$(openssl rand -base64 32)" -e -id -k 65540 -t 3 -p 4
```

Copy the result securely.

In the `.env` file, enter the following variables:

```properties
URL=
TOKEN=
```

| Variable | Value | Example |
|----------|-------|---------|
| `URL`    | The URL of your Vaultwarden server | `https://vault.yourdomain.com` |
| `TOKEN`  | The token you previously copied | `'$argon2id$v=19$m=65540,t=3,p=4$bXBGME...` |

Then deploy the container.

Recently, Vaultwarden requires SSL to be accessed, which prevents access via a local IP. We'll expose it with SWAG, which provides an SSL certificate.

::alert{type="danger"}
:::list{type="danger"}
- __If it fails:__ check your firewall rules.
:::
::

## Exposing Vaultwarden with SWAG
---
The main benefit of Vaultwarden is being able to access it remotely from any device. We'll expose it through [SWAG](/serveex/core/swag).

::alert{type="info"}
✨ __Before you start:__ Make sure you've created a DNS subdomain like `vault.yourdomain.com` with `CNAME` pointing to `yourdomain.com` and (unless using Cloudflare Zero Trust) that you've forwarded port `443` from your router to your server's `443` via [NAT rules](/general/nat).
::

In Dockge, go to the SWAG stack and edit the compose file to add the Vaultwarden network:

```yaml
services:
  swag:
     container_name: # ...
     # ...
     networks:             # Connects container to custom network
      # ...
      - vaultwarden        # Name of the declared network
    
networks:                  # Defines the custom network
  # ...
  vaultwarden:             # Name of the declared network
    name: vaultwarden_default  # Actual name of the external network
    external: true
```

::alert{type="info"}
:::list{type="info"}
- We're assuming the network name is `vaultwarden_default`. You can check connectivity by visiting the SWAG dashboard at http://yourserverip:81.
:::
::

Restart the stack by clicking "Deploy" and wait for SWAG to be fully operational.

In SWAG's config folder, create the file `vault.subdomain.conf`:

::alert{type="success"}
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
::

```shell
sudo vi /docker/swag/config/nginx/proxy-confs/vault.subdomain.conf
```

Press `i` to edit, and paste the following configuration:

```nginx
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name vault.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 128M;

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;

    location / {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }

    location ~ ^(/vaultwarden)?/admin {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }

    location ~ (/vaultwarden)?/api {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }

    location ~ (/vaultwarden)?/notifications/hub {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}
```

Press `Esc`, then type `:x` and press `Enter` to save and exit.

And there you go — Vaultwarden is now exposed! Visit `https://vault.yourdomain.com/admin` to access the admin panel and paste the `ADMIN_TOKEN` you specified in your `compose.yaml`. For more information, see the [Bitwarden documentation](https://bitwarden.com/help/).

Don't forget to install Bitwarden browser extensions (they work with Vaultwarden) for [Chrome](https://chromewebstore.google.com/detail/gestionnaire-de-mots-de-p/nngceckbapebfimnlniiiahkandclblb) and [Firefox](https://addons.mozilla.org/fr/firefox/addon/bitwarden-password-manager/), as well as [iOS](https://apps.apple.com/fr/app/bitwarden/id1137397744) and [Android](https://play.google.com/store/apps/details?id=com.x8bit.bitwarden&hl=fr) apps to sync your passwords.

::alert{type="success"}
✨ __Tip:__ You can protect this app with Authentik by opening `tools.subdomain.conf` and removing the `#` in front of `include /config/nginx/authentik-server.conf;` and `include /config/nginx/authentik-location.conf;`. Don't forget to [create an application and provider in Authentik](/serveex/security/authentik#protecting-an-app-via-reverse-proxy).
::