Author | Nejat Hakan |
nejat.hakan@outlook.de | |
PayPal Me | https://paypal.me/nejathakan |
Password Manager Vaultwarden
Introduction
Welcome to this comprehensive guide on self-hosting Vaultwarden, a lightweight, open-source password manager compatible with the official Bitwarden clients. Bitwarden itself is a highly respected password management solution, offering features like secure password storage, generation, and sharing. Vaultwarden provides an alternative server implementation written in Rust, making it significantly less resource-intensive than the official server (which requires Microsoft SQL Server and ASP.NET Core). This makes Vaultwarden an ideal choice for individuals, families, or small organizations looking to host their own password management solution on modest hardware, like a Raspberry Pi or a small Virtual Private Server (VPS).
Self-hosting your password manager offers several compelling advantages:
- Data Sovereignty: You retain complete control over your sensitive password data. It resides on hardware you manage, not on third-party servers. This eliminates reliance on the security practices and privacy policies of external companies.
- Enhanced Privacy: By hosting it yourself, you minimize the metadata footprint associated with cloud services. Your usage patterns, login times, and IP addresses are not logged by an external provider.
- Cost-Effectiveness: While official Bitwarden offers free tiers, premium features require a subscription. Vaultwarden enables access to many of these premium features (like organization support, TOTP authenticator key storage, file attachments) without any subscription fees, aside from your hosting costs (which can be minimal).
- Customization and Flexibility: You have greater control over the server configuration, backup strategies, and update schedules. You can tailor the environment precisely to your needs.
- Learning Opportunity: Setting up and managing Vaultwarden provides invaluable hands-on experience with technologies like Docker, reverse proxies, HTTPS/SSL certificates, data persistence, and server administration – skills highly relevant in modern computing.
However, self-hosting also comes with responsibilities:
- Security: You are solely responsible for securing the server, keeping the operating system and Vaultwarden software updated, managing firewalls, and implementing HTTPS.
- Backups: You must implement a robust backup and recovery strategy to prevent data loss.
- Maintenance: Regular updates and monitoring are required to ensure smooth operation and security.
This guide will walk you through the process, starting with the basics and progressing to more advanced configurations. We assume you have a target server environment (like a Linux VPS or a home server) and basic familiarity with the command line. Each theoretical section is followed by a practical workshop to solidify your understanding. Let's begin securing your digital life with your own Vaultwarden instance!
1. Getting Started with Docker and Vaultwarden
This initial section focuses on the foundational steps: understanding the containerization technology we'll use (Docker) and deploying a basic Vaultwarden instance. This provides a quick win and familiarizes you with the core components.
Understanding Docker Basics
Before deploying Vaultwarden, it's essential to grasp the basics of Docker, the containerization platform we'll be using. Docker simplifies the process of packaging, distributing, and running applications by using containers.
Think of a container as a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries, and settings. Unlike traditional Virtual Machines (VMs) which virtualize the entire hardware stack including the operating system, containers virtualize the operating system level. They run directly on the host machine's kernel but are isolated from each other and the host system.
Key Docker concepts:
- Docker Engine: The core component that runs on your host machine. It builds and runs containers.
- Image: A read-only template containing the application and its dependencies. Images are used to create containers. You can think of an image as a blueprint or a class in object-oriented programming. Vaultwarden provides an official Docker image.
- Container: A runnable instance of an image. You can create, start, stop, move, or delete containers. It's the actual running application. Think of a container as an object or instance created from a class.
- Dockerfile: A text file containing instructions on how to build a Docker image. It specifies the base image, commands to run, files to copy, ports to expose, etc. While you don't need to write a Dockerfile to run Vaultwarden (we'll use a pre-built image), understanding its purpose is helpful.
- Docker Hub/Registries: A cloud-based repository (like Docker Hub) where Docker images are stored and shared. This is where we will pull the official Vaultwarden image from.
Why Docker for Vaultwarden?
- Simplicity: Docker encapsulates Vaultwarden and all its dependencies. You don't need to manually install Rust, web servers, or specific libraries on your host system.
- Consistency: The Vaultwarden container will run identically regardless of the underlying host OS environment (as long as Docker is installed), reducing compatibility issues.
- Isolation: Vaultwarden runs in its own isolated environment, preventing conflicts with other applications running on the same server.
- Ease of Updates: Updating Vaultwarden often involves simply pulling the latest image and recreating the container.
Understanding these fundamentals will make the deployment process much clearer.
Workshop Docker Installation and Hello World
Goal: Install Docker Engine on your Linux server and verify the installation by running a simple test container.
Prerequisites:
- A Linux server (e.g., Ubuntu 20.04/22.04 or Debian 10/11).
- Access to the server via SSH or direct console.
- Root or
sudo
privileges.
Steps:
-
Update Package Index: Ensure your server's package list is up-to-date. Open your terminal and run:
Explanation:sudo
executes the command with administrative privileges.apt update
refreshes the list of available packages from the repositories defined in your system's sources lists. -
Install Prerequisite Packages: Docker requires a few packages to allow
Explanation:apt
to use repositories over HTTPS:apt install -y
: Installs packages; the-y
flag automatically confirms any prompts.apt-transport-https
: Allowsapt
to retrieve packages over HTTPS.ca-certificates
: Allows the system to check security certificates.curl
: A tool to transfer data from or to a server (used to download the GPG key).software-properties-common
: Adds helper scripts for managing software sources.gnupg
: GNU Privacy Guard, used for securely signing software packages.
-
Add Docker's Official GPG Key: Download and add Docker's official GPG key to ensure the authenticity of the Docker packages:
Explanation:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
curl -fsSL ...
: Downloads the key.-f
fails silently,-s
is silent mode,-S
shows errors,-L
follows redirects.|
: Pipes the downloaded key to the next command.sudo gpg --dearmor -o ...
: Decrypts and converts the key (--dearmor
) and saves it (-o
) to the specified location forapt
to use.
-
Set Up the Stable Repository: Add the official Docker repository to your system's sources. Replace
$(lsb_release -cs)
with your distribution's codename if needed (e.g.,focal
for Ubuntu 20.04,jammy
for Ubuntu 22.04,bullseye
for Debian 11).Explanation:echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
echo "..."
: Creates the repository definition string.$(dpkg --print-architecture)
: Automatically determines your system's architecture (e.g.,amd64
,arm64
).signed-by=...
: Tellsapt
where to find the GPG key for verifying packages from this repo.$(lsb_release -cs)
: Automatically determines your Ubuntu/Debian version codename.stable
: Specifies that we want the stable release channel of Docker.| sudo tee ...
: Writes the string to the specified file (/etc/apt/sources.list.d/docker.list
) withsudo
privileges.> /dev/null
discards the standard output oftee
.
-
Install Docker Engine: Update the package index again (to include the new Docker repo) and install Docker Engine, Containerd, and Docker Compose:
Explanation: Installs the Docker Community Edition (docker-ce
), the command-line interface (docker-ce-cli
), the containerd runtime (containerd.io
), and the Docker Compose plugin (docker-compose-plugin
). -
Verify Docker Installation: Run the
Explanation:hello-world
image to confirm Docker is installed and working correctly:docker run hello-world
tells Docker Engine to:- Check if the
hello-world
image is available locally. - If not, pull it from Docker Hub.
- Create and run a new container based on that image.
- The
hello-world
container simply prints a confirmation message and exits.
You should see output similar to:
- Check if the
-
(Optional but Recommended) Add User to Docker Group: To run Docker commands without
Explanation:sudo
every time, add your user to thedocker
group. Note: This has security implications, as users in this group effectively have root-equivalent privileges.usermod -aG docker $USER
adds (-a
) your current user ($USER
) to the supplementary group (-G
) nameddocker
.- Important: You need to log out and log back in (or run
newgrp docker
) for this change to take effect. After logging back in, test withdocker run hello-world
(withoutsudo
).
- Important: You need to log out and log back in (or run
Outcome: You have successfully installed Docker Engine and verified its operation. You are now ready to deploy containerized applications like Vaultwarden.
Deploying Vaultwarden with Docker Run
The simplest way to get Vaultwarden running is using the docker run
command. This command pulls the official vaultwarden/server
image from Docker Hub and starts a container from it.
Here's a breakdown of a basic docker run
command for Vaultwarden:
Let's dissect this command:
docker run
: The fundamental command to create and start a new container.-d
or--detach
: Runs the container in the background (detached mode) and prints the container ID. Without this, your terminal would be attached to the container's log output.--name vaultwarden
: Assigns a specific, human-readable name (vaultwarden
) to the container. This makes it easier to manage (e.g.,docker stop vaultwarden
). If you don't specify a name, Docker assigns a random one.-p 8080:80
: This maps ports between the host machine and the container. The format isHOST_PORT:CONTAINER_PORT
.80
: Inside the container, the Vaultwarden web server listens on port 80 by default.8080
: This is the port on your host machine that will forward traffic to the container's port 80. So, you'll access Vaultwarden viahttp://<your_server_ip>:8080
. You can change8080
to another available port on your host if needed (e.g.,-p 8000:80
). Avoid using port 80 directly on the host at this stage, as it's often reserved or might be used by a reverse proxy later.
-v vw-data:/data/
: This is crucial for data persistence. It mounts a Docker volume namedvw-data
to the/data
directory inside the container./data
: This is the directory inside the container where Vaultwarden stores all its persistent data (database, attachments, configuration, keys).vw-data
: This is the name of the Docker named volume on your host system. Docker manages this volume. When the container is stopped, removed, or updated, the data in thevw-data
volume persists. If you omit this-v
flag, all your Vaultwarden data (users, passwords, settings) will be lost when the container is removed. We will cover volumes in more detail in the intermediate section, but it's good practice to include it from the start.
vaultwarden/server:latest
: This specifies the image to use.vaultwarden/server
: The name of the official Vaultwarden image on Docker Hub.:latest
: The tag specifying which version of the image to use.latest
pulls the most recently pushed stable version. While convenient for starting, it's generally recommended to pin to a specific version tag (e.g.,vaultwarden/server:1.30.1
) in production for more predictable updates.
When you execute this command, Docker will:
- Check if the
vaultwarden/server:latest
image exists locally. - If not, download (pull) it from Docker Hub.
- Create a Docker named volume called
vw-data
if it doesn't already exist. - Create a new container named
vaultwarden
. - Configure port mapping (host 8080 -> container 80).
- Mount the
vw-data
volume to/data
inside the container. - Start the container in the background.
This basic deployment gets Vaultwarden running, but it lacks HTTPS encryption, which is essential for security. We will address this in the intermediate section.
Workshop Basic Vaultwarden Deployment
Goal:
Deploy a functional Vaultwarden instance using the docker run
command and access its web interface.
Prerequisites:
- Docker installed and running (from the previous workshop).
- Access to the server's terminal.
- Port 8080 (or your chosen host port) must be open on your server's firewall if accessing remotely.
Steps:
-
Pull the Latest Vaultwarden Image (Optional but Recommended): While
Explanation: This command downloads thedocker run
will pull the image if it's not present, pulling it explicitly first can be good practice.latest
tagged image forvaultwarden/server
from Docker Hub to your local machine. -
Run the Vaultwarden Container: Execute the
Explanation: As detailed in the theory section, this starts Vaultwarden in detached mode, names itdocker run
command discussed previously. We'll use port 8080 on the host.vaultwarden
, maps host port 8080 to container port 80, uses a named volumevw-data
for persistence, and uses the latest server image. -
Verify the Container is Running: Check the status of your Docker containers.
Explanation:docker ps
lists all currently running containers. You should see an entry forvaultwarden
, showing it'sUp
and listing the port mapping (0.0.0.0:8080->80/tcp
).- If you don't see it, use
docker ps -a
to list all containers (including stopped ones) anddocker logs vaultwarden
to check for errors.
- If you don't see it, use
-
Check Container Logs (Optional): To see the startup messages from Vaultwarden:
Explanation: This command fetches and displays the standard output and standard error streams from thevaultwarden
container. You should see messages indicating the Rocket web server has started. -
Access the Vaultwarden Web UI: Open a web browser on your computer (or any device that can reach your server). Navigate to:
http://<your_server_ip>:8080
Replace<your_server_ip>
with the actual IP address of the server where you ran the Docker command.- If you are running this on your local machine, you might use
http://localhost:8080
orhttp://127.0.0.1:8080
. - If you are using a cloud VPS, use its public IP address.
- Firewall Note: If you cannot connect, ensure that port 8080 (or the host port you chose) is allowed through any firewalls running on the server (e.g.,
ufw
,firewalld
) or provided by your cloud provider. Forufw
:sudo ufw allow 8080/tcp
.
- If you are running this on your local machine, you might use
Outcome: You should see the Vaultwarden web vault interface load in your browser, presenting you with options to log in or create an account. You have successfully deployed a basic Vaultwarden instance! The next step is to create your account.
Initial Vaultwarden Setup and Account Creation
Once you have accessed the Vaultwarden web UI via http://<your_server_ip>:8080
, the first and most crucial step is to create your primary account. This account will serve as your entry point to managing your passwords.
Key Considerations:
- Master Password: This is the single most important piece of information.
- Complexity: Choose a very strong, unique master password. It should ideally be long (15+ characters), complex (mix of upper/lower case letters, numbers, symbols), and not reused anywhere else. Consider using a passphrase (a sequence of random words) for memorability and strength.
- Security: Vaultwarden (like Bitwarden) uses your master password to encrypt and decrypt your vault data locally on your client device. The server never stores your master password directly, only a heavily salted and hashed version used for authentication. If you forget your master password, there is no recovery mechanism provided by Vaultwarden. Your encrypted data will be inaccessible. Store your master password securely (e.g., written down in multiple secure physical locations).
- Password Hint: You can optionally provide a hint. Make sure the hint doesn't give away the password itself.
- Email Address: This email address is used for account identification and potential communication features (like email verification if enabled, though not by default in the basic setup).
- First User Significance: By default, Vaultwarden allows anyone who can access the web UI to create an account (
SIGNUPS_ALLOWED=true
). The first user created doesn't automatically gain special administrative privileges within the Vaultwarden application itself (though there is a separate admin panel we'll cover later). It's recommended to disable open signups after you've created your necessary accounts, which we will cover in the advanced section.
The Creation Process:
- Navigate: Go to
http://<your_server_ip>:8080
. - Click "Create Account": Locate and click the "Create Account" button or link on the main page.
- Fill in the Form:
- Enter your desired Email Address.
- Enter a Master Password. Pay close attention to the strength indicator.
- Confirm your Master Password.
- Optionally, enter a Master Password Hint.
- Submit: Click the "Create Account" or "Submit" button.
Upon successful creation, you will typically be automatically logged into your new, empty vault. You can now start adding login credentials, secure notes, cards, and identities.
Workshop First Login and Basic Usage
Goal: Create your first Vaultwarden account, log in, and add a sample password entry.
Prerequisites:
- Vaultwarden container running and accessible via the web browser (from the previous workshop).
Steps:
-
Access Vaultwarden: Open your web browser and navigate to
http://<your_server_ip>:8080
(replace<your_server_ip>
accordingly). -
Initiate Account Creation: Click on the "Create Account" button.
-
Enter Account Details:
- Email Address: Enter your email address (e.g.,
student@example.com
). - Master Password: Create a strong, unique master password. For this workshop, you can use something temporary like
CorrectHorseBatteryStaple123!
, but remember to change it to a truly secure one later if you plan to use this instance seriously. Note it down temporarily if needed for this workshop only. - Confirm Master Password: Re-enter the master password.
- Master Password Hint (Optional): You can skip this for now or add a simple hint.
- Email Address: Enter your email address (e.g.,
-
Submit the Form: Click the "Create Account" button at the bottom of the form.
-
Log In: You should be redirected to the login page or possibly logged in automatically. If on the login page, enter the email address and master password you just created and click "Log In".
-
Explore the Interface: You are now inside your empty Vaultwarden web vault. Familiarize yourself briefly with the layout:
- Folders: Left-hand pane for organizing items.
- Item Types: Middle pane (usually shows "All Items" initially).
- Add Item: A button (often
+
or "Add Item") to create new entries. - Settings: Usually accessible via your email address or an icon in the top-right corner.
-
Add a Sample Login Item:
- Click the "Add Item" button (likely a
+
symbol). - Type: Select "Login" (this is usually the default).
- Name: Enter a descriptive name (e.g.,
My Test Website
). - Username: Enter a sample username (e.g.,
testuser
). - Password: Enter a sample password (e.g.,
SampleP@ssw0rd
). You can also click the "generate password" icon (often a refresh/circular arrow symbol) to see Vaultwarden's password generator. - URI 1: Enter a sample URL (e.g.,
https://test.example.com
). Adding the correct URI helps browser extensions auto-fill credentials. - Save: Click the "Save" button (usually at the top or bottom).
- Click the "Add Item" button (likely a
-
View the Saved Item: Your new item (
My Test Website
) should now appear in the middle pane. Click on it to view its details. You can copy the username or password using the provided icons.
Outcome: You have successfully created your primary Vaultwarden account, logged into the web vault, and added your first password entry. You now have a basic, functioning, self-hosted password manager. Remember the importance of your master password and the need for further configuration (like HTTPS) for real-world use.
2. Enhancing Your Vaultwarden Instance
With the basics covered, this section focuses on making your Vaultwarden instance more robust, manageable, and secure for real-world usage. We'll tackle persistent storage properly, simplify management with Docker Compose, and crucially, enable HTTPS encryption via a reverse proxy.
Persistent Data Storage with Volumes
In the basic deployment workshop, we already used the -v vw-data:/data/
flag. Let's delve deeper into why this is absolutely essential and explore Docker volumes more formally.
The Problem with Ephemeral Containers:
By default, the filesystem inside a Docker container is ephemeral. If you stop and remove a container (docker stop vaultwarden && docker rm vaultwarden
) without having configured persistent storage, any data created or modified inside that container's filesystem is permanently lost. For Vaultwarden, this means losing your entire password database, user accounts, settings, attachments – everything stored in the /data
directory within the container. Recreating the container from the same image will start it fresh, without any of your previous data.
The Solution Docker Volumes:
Docker offers several ways to persist data generated by containers. The preferred mechanism for databases, configuration files, and application data is Docker Volumes.
- What are Volumes? Volumes are directories (or files) that exist outside the container's Union File System but are mounted into the container at a specified path. They are managed by Docker itself and stored in a dedicated area on the host filesystem (e.g.,
/var/lib/docker/volumes/
on Linux). - Named Volumes: When we used
-v vw-data:/data/
, we created a named volume.vw-data
: The name you give the volume. This makes it easy to reference and manage.:/data/
: The path inside the container where the volume should be mounted.- Docker automatically creates the named volume on the host the first time a container starts using it.
- Benefits of Named Volumes:
- Managed by Docker: Easier to back up, migrate, and manage volumes using Docker CLI commands (e.g.,
docker volume ls
,docker volume inspect
,docker volume rm
). - Decoupled Lifecycle: Volumes exist independently of containers. You can remove a container, update the image, start a new container, and attach the same volume to it, preserving all your data.
- Performance: Docker volumes often provide better I/O performance compared to bind mounts (another persistence method) for write-heavy workloads.
- Cross-Platform Compatibility: Volumes work consistently across different Docker environments (Linux, Windows, macOS).
- Managed by Docker: Easier to back up, migrate, and manage volumes using Docker CLI commands (e.g.,
Bind Mounts (Alternative, Use with Caution):
Another option is using bind mounts: -v /path/on/host:/data/
. This directly mounts a specific directory from your host machine into the container. While useful for development (e.g., mounting source code) or providing specific configuration files, it's generally less recommended for application data like Vaultwarden's database because:
- It tightly couples the container to the host's filesystem structure.
- Permissions management can be more complex.
- It bypasses Docker's volume management features.
For Vaultwarden's /data
directory, always use a named volume unless you have a very specific reason not to.
Ensuring you use -v <volume_name>:/data/
(or the equivalent in Docker Compose) guarantees that your precious vault data survives container restarts, updates, and removals.
Workshop Implementing Persistent Storage
Goal: Explicitly demonstrate data persistence using a named Docker volume. We will create an item, stop and remove the container, then start a new container using the same volume and verify the item is still present.
Prerequisites:
- A running Vaultwarden container, preferably the one created in the previous workshop (named
vaultwarden
) which should already be using thevw-data
volume. If you didn't use-v
before, your data will be lost in this workshop, highlighting the importance of volumes. - Access to the server's terminal.
Steps:
-
Ensure Vaultwarden is Running with a Volume: If you followed the previous workshop, your container should already be using the
Explanation:vw-data
volume. Verify this:docker inspect vaultwarden
outputs detailed information about the container in JSON format.grep -A 5 Mounts
searches for the line containing "Mounts" and shows that line plus the next 5 lines. Look for an entry showing"Type": "volume"
,"Name": "vw-data"
, and"Destination": "/data"
.- If you don't have a volume mounted to
/data
, stop and remove the container (docker stop vaultwarden && docker rm vaultwarden
) and restart it using the command from the previous workshop:docker run -d --name vaultwarden -p 8080:80 -v vw-data:/data/ vaultwarden/server:latest
. You will need to create a new account and item in this case.
- If you don't have a volume mounted to
-
Add or Confirm a Test Item:
- Log in to your Vaultwarden instance (
http://<your_server_ip>:8080
). - If you don't have the "My Test Website" item from the previous workshop, create a new Login item now (e.g., Name:
Persistence Test
, Username:tester
). - Ensure the item is saved and visible in your vault.
- Log in to your Vaultwarden instance (
-
Stop the Vaultwarden Container:
Explanation: Gracefully stops the container namedvaultwarden
. -
Remove the Vaultwarden Container:
Explanation: Removes the stopped container. Crucially, this does not remove the named volumevw-data
. -
Verify Container Removal:
Explanation: Lists all containers, running and stopped. Thevaultwarden
container should no longer be listed. -
Verify Volume Existence:
Explanation: Lists all Docker volumes managed by Docker. You should seevw-data
(or whatever name you used) in the list. This confirms the volume and its data still exist independently of the container. -
Restart Vaultwarden Using the Same Volume: Run the exact same
Explanation: Docker detects that a volume nameddocker run
command you used initially, ensuring the volume name (vw-data
) is identical:vw-data
already exists and mounts it to/data
in the new container instance. -
Verify Data Persistence:
- Wait a few seconds for the container to start. Check with
docker ps
. - Access Vaultwarden again in your browser:
http://<your_server_ip>:8080
. - Log in using the same email and master password you created earlier.
- Check your vault items. The "My Test Website" or "Persistence Test" item you created or confirmed in Step 2 should still be there.
- Wait a few seconds for the container to start. Check with
Outcome: You have successfully demonstrated that using a named Docker volume ensures your Vaultwarden data persists even when the container itself is stopped and removed. This is fundamental for reliable operation and allows for safe updates and restarts. If the data was not present, it means you likely didn't use the -v
flag correctly in the initial run.
Using Docker Compose for Easier Management
While docker run
is fine for single containers, managing applications, their configurations, volumes, and networks becomes cumbersome as complexity increases. Docker Compose is a tool designed to define and run multi-container Docker applications using a simple YAML file.
What is Docker Compose?
Docker Compose uses a docker-compose.yml
file to configure your application's services, networks, and volumes. Instead of typing long docker run
commands with many flags, you define the desired state in the YAML file, and Compose handles the creation and management.
Benefits of using Docker Compose for Vaultwarden:
- Declarative Configuration: The
docker-compose.yml
file clearly describes your Vaultwarden setup (image, ports, volumes, environment variables, networks). This file acts as documentation and makes the setup reproducible. - Simplicity: Starting, stopping, and restarting your application becomes much simpler:
docker compose up
,docker compose down
. - Easier Configuration Management: Modifying configurations (e.g., adding environment variables, changing ports) involves editing the YAML file and recreating the services, rather than complex
docker run
commands. - Networking: Compose automatically sets up a dedicated network for your application's services, allowing containers to easily communicate with each other using their service names. This is crucial when adding a reverse proxy in a later step.
- Readability: YAML is human-readable and well-structured, making it easier to understand the setup compared to long shell commands.
Basic docker-compose.yml
for Vaultwarden:
Here's an example docker-compose.yml
file that replicates our previous docker run
command:
version: '3.8' # Specifies the Compose file format version
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden # Explicitly sets the container name
restart: unless-stopped # Policy for restarting the container
volumes:
- vw-data:/data/ # Mounts the named volume 'vw-data' to /data in the container
ports:
- "8080:80" # Maps host port 8080 to container port 80
environment:
# Environment variables can be added here later (e.g., for HTTPS, admin token)
- WEBSOCKET_ENABLED=true # Enable websockets for real-time client sync (optional but recommended)
volumes:
vw-data: # Declares the named volume 'vw-data'
# driver: local (default) - You can specify volume drivers if needed
Explanation:
version: '3.8'
: Defines the version of the Compose file syntax.services:
: Defines the containers (services) that make up your application.vaultwarden:
: The name of our service.image:
: Specifies the Docker image to use.container_name:
: Sets a specific name for the container (optional, but helpful).restart: unless-stopped
: Defines the restart policy.unless-stopped
ensures the container restarts automatically if it crashes or if the Docker daemon restarts, unless it was manually stopped. Other options includeno
,on-failure
,always
.volumes:
: Defines volume mounts for this service.- vw-data:/data/
: Mounts the named volumevw-data
(defined below) to/data
inside the container.
ports:
: Defines port mappings (HOST:CONTAINER
).- "8080:80"
: Maps host port 8080 to container port 80.
environment:
: Used to set environment variables inside the container. We addedWEBSOCKET_ENABLED=true
as it improves client synchronization performance and is needed for some reverse proxy setups.
volumes:
: Top-level key to define named volumes used by the services.vw-data:
: Declares the named volumevw-data
. Docker Compose will create it if it doesn't exist.
Using Docker Compose provides a much cleaner and more maintainable way to manage your Vaultwarden deployment.
Workshop Migrating to Docker Compose
Goal: Transition from managing Vaultwarden with docker run
to using Docker Compose, ensuring data persistence.
Prerequisites:
- Vaultwarden previously started with
docker run
using the named volumevw-data
. - Docker Compose installed (usually included with Docker Desktop or installed as
docker-compose-plugin
in the first workshop). Verify withdocker compose version
. - Access to the server's terminal.
- A text editor on the server (like
nano
orvim
).
Steps:
-
Stop and Remove the Existing Container: If your
Verify removal:vaultwarden
container started withdocker run
is still running, stop and remove it. Ensure it was started with-v vw-data:/data/
so your data is safe in the volume.docker ps -a
should not showvaultwarden
. Verify volume:docker volume ls
should still showvw-data
. -
Create a Directory for Compose File: It's good practice to keep your
Explanation: Creates a directory nameddocker-compose.yml
file in a dedicated directory.vaultwarden
in your home directory and navigates into it. -
Create the
docker-compose.yml
File: Use a text editor to create thedocker-compose.yml
file. -
Paste the Compose Configuration: Copy the following YAML content and paste it into the
nano
editor: -
Save and Close the File:
- In
nano
: PressCtrl+X
, thenY
to confirm saving, andEnter
to save with the namedocker-compose.yml
.
- In
-
Start Vaultwarden with Docker Compose: While inside the
Explanation:~/vaultwarden
directory (where thedocker-compose.yml
file is located), run:docker compose
: Invokes the Docker Compose tool.up
: Builds (if necessary), creates, starts, and attaches to containers for a service.-d
: Detached mode - runs containers in the background.- Compose reads the
docker-compose.yml
file in the current directory. It will detect the existingvw-data
volume and attach it to the newvaultwarden
container.
-
Verify the Container:
You should see thevaultwarden
container running, managed by Docker Compose. You might notice the container name is prefixed with the directory name (e.g.,vaultwarden-vaultwarden-1
) if you didn't specifycontainer_name
. If you did usecontainer_name: vaultwarden
as in the example, it should just be namedvaultwarden
. -
Verify Data Persistence and Access:
- Access Vaultwarden in your browser:
http://<your_server_ip>:8080
. - Log in with your existing credentials.
- Verify that your previously saved items (e.g., "My Test Website", "Persistence Test") are still present.
- Test adding a new item to ensure write access is working.
- Access Vaultwarden in your browser:
Outcome: You have successfully migrated your Vaultwarden instance to be managed by Docker Compose. Future management actions like stopping (docker compose down
), starting (docker compose up -d
), restarting (docker compose restart vaultwarden
), and updating (pulling a new image and running docker compose up -d
) are now streamlined using Compose commands within the ~/vaultwarden
directory. Your data remains persistent in the vw-data
volume.
Setting Up HTTPS with a Reverse Proxy (e.g., Nginx Proxy Manager)
Running Vaultwarden over plain HTTP (http://...
) is highly insecure. Your login credentials (including your master password) and all vault data would be transmitted unencrypted over the network, making them vulnerable to interception. Enabling HTTPS is mandatory for any real-world use.
Vaultwarden itself doesn't handle HTTPS/TLS termination directly. The standard practice is to run Vaultwarden listening only on the local Docker network (or localhost
within the container) and place a reverse proxy in front of it.
What is a Reverse Proxy?
A reverse proxy is a server that sits in front of web servers (like Vaultwarden) and forwards client requests (from web browsers, apps) to those web servers. It acts as an intermediary, providing several benefits:
- SSL/TLS Termination: The reverse proxy handles the complexity of obtaining, managing, and renewing SSL/TLS certificates (e.g., from Let's Encrypt) and encrypting traffic between the client and the proxy (HTTPS). Communication between the proxy and the backend Vaultwarden container can then happen over plain HTTP within the secure Docker network.
- Load Balancing: Can distribute incoming traffic across multiple backend server instances (not typically needed for a single Vaultwarden instance).
- Security: Hides the internal structure and IP addresses of your backend servers. Can provide additional security layers like rate limiting or web application firewalls (WAF).
- Centralized Access: Allows you to host multiple web applications on the same server using the same IP address and standard ports (80 for HTTP, 443 for HTTPS), routing traffic based on domain names (e.g.,
vaultwarden.mydomain.com
,blog.mydomain.com
).
Popular Reverse Proxy Options:
- Nginx: A powerful, high-performance web server and reverse proxy. Requires manual configuration file editing.
- Apache: Another widely used web server with reverse proxy capabilities. Also requires manual configuration.
- Traefik: A modern, cloud-native reverse proxy designed specifically for containers. Automatically discovers services and handles SSL via Docker labels. Can have a steeper learning curve initially.
- Caddy: A modern web server known for its automatic HTTPS configuration. Simple to configure.
- Nginx Proxy Manager (NPM): A user-friendly web interface built on top of Nginx. Makes setting up proxy hosts, redirection, and Let's Encrypt SSL certificates incredibly easy via a GUI. Excellent choice for beginners.
General Workflow (using Nginx Proxy Manager as example):
- Set up DNS: Configure a DNS A record for your desired domain (e.g.,
vaultwarden.yourdomain.com
) pointing to the public IP address of your server. - Deploy Nginx Proxy Manager: Run NPM as a Docker container (often using Docker Compose). It needs ports 80, 443, and a port for its own admin UI (e.g., 81).
- Modify Vaultwarden Deployment:
- Remove the direct port mapping (
ports:
section) from Vaultwarden'sdocker-compose.yml
. It no longer needs to be exposed directly to the host. - Ensure both Vaultwarden and NPM are on the same Docker network so NPM can reach Vaultwarden by its service name (
vaultwarden
). - Add necessary environment variables to Vaultwarden if required by the proxy setup (e.g.,
DOMAIN=https://vaultwarden.yourdomain.com
).
- Remove the direct port mapping (
- Configure NPM:
- Log in to the NPM web UI.
- Add a new Proxy Host:
- Domain Names:
vaultwarden.yourdomain.com
- Scheme:
http
- Forward Hostname / IP:
vaultwarden
(the service name from yourdocker-compose.yml
) - Forward Port:
80
(the port Vaultwarden listens on inside the container) - Enable
Block Common Exploits
. - Enable
Websockets Support
.
- Domain Names:
- Go to the SSL tab:
- Select "Request a new SSL Certificate" with Let's Encrypt.
- Enable "Force SSL".
- Agree to the Let's Encrypt ToS.
- Save.
- Test: Access
https://vaultwarden.yourdomain.com
. You should be redirected to HTTPS and see the Vaultwarden login page with a valid SSL certificate (lock icon in browser).
This setup ensures secure, encrypted access to your self-hosted password manager.
Workshop Securing Vaultwarden with HTTPS via NPM
Goal: Set up Nginx Proxy Manager (NPM) and configure it to provide secure HTTPS access to your Vaultwarden instance using a custom domain name and a Let's Encrypt SSL certificate.
Prerequisites:
- Vaultwarden running via Docker Compose (from the previous workshop).
- A registered domain name (e.g.,
yourdomain.com
). - Ability to add DNS records for your domain.
- Your server's public IP address.
- Ports 80 and 443 open on your server's firewall (e.g.,
sudo ufw allow 80/tcp
,sudo ufw allow 443/tcp
). Port 81 also needs to be open for the NPM admin interface.sudo ufw allow 81/tcp
. - Docker and Docker Compose installed.
Steps:
-
Configure DNS:
- Go to your domain registrar or DNS provider's control panel.
- Create an A record pointing a subdomain (e.g.,
vaultwarden
) to your server's public IP address.- Type:
A
- Name/Host:
vaultwarden
(or your preferred subdomain) - Value/Points to:
<your_server_public_ip>
- TTL: Set to the lowest possible value (e.g., 1 minute or 60 seconds) initially for faster propagation, you can increase it later.
- Type:
- Wait for DNS propagation (can take minutes to hours). You can check using
ping vaultwarden.yourdomain.com
or an online DNS checker.
-
Prepare Docker Network: We need both Vaultwarden and NPM to be on the same custom Docker network so they can communicate using service names.
- Edit your Vaultwarden
docker-compose.yml
(~/vaultwarden/docker-compose.yml
): -
Modify it to look like this (changes highlighted):
Replaceversion: '3.8' services: vaultwarden: image: vaultwarden/server:latest container_name: vaultwarden restart: unless-stopped volumes: - vw-data:/data/ # ports: <-- REMOVE OR COMMENT OUT THIS SECTION # - "8080:80" <-- REMOVE OR COMMENT OUT networks: # <-- ADD - npm_network # <-- ADD (Name of the network) environment: - WEBSOCKET_ENABLED=true - DOMAIN=https://vaultwarden.yourdomain.com # <-- ADD YOUR FULL DOMAIN HERE volumes: vw-data: networks: # <-- ADD THIS ENTIRE BLOCK npm_network: # <-- ADD external: true # <-- ADD (Specifies we'll use a pre-existing network)
vaultwarden.yourdomain.com
with your actual domain. -
Save and close the file (
Ctrl+X
,Y
,Enter
).
- Edit your Vaultwarden
-
Create the Docker Network: Before starting NPM or restarting Vaultwarden, create the network we referenced:
Explanation: Creates a Docker bridge network namednpm_network
. -
Restart Vaultwarden: Navigate back to the Vaultwarden directory and apply the changes:
-
Create Docker Compose File for Nginx Proxy Manager (NPM):
- Create a separate directory for NPM:
- Create the
docker-compose.yml
file for NPM: -
Paste the following configuration:
version: '3.8' services: npm: image: 'jc21/nginx-proxy-manager:latest' container_name: npm restart: unless-stopped ports: # Public HTTP Port: - '80:80' # Public HTTPS Port: - '443:443' # Admin Web Port: - '81:81' volumes: - npm-data:/data - npm-letsencrypt:/etc/letsencrypt networks: # <-- ADD - npm_network # <-- ADD (Connect NPM to the same network) volumes: npm-data: npm-letsencrypt: networks: # <-- ADD THIS ENTIRE BLOCK npm_network: # <-- ADD external: true # <-- ADD (Connect to the network created earlier)
-
Save and close the file.
-
Start Nginx Proxy Manager: While inside the
~/npm
directory: -
Access NPM Admin Interface:
- Wait a minute for NPM to initialize.
- Open your web browser and navigate to
http://<your_server_ip>:81
. - Default Login:
- Email:
admin@example.com
- Password:
changeme
- Email:
- You will be forced to change the email and password immediately. Do this now and use a strong password.
-
Configure Proxy Host in NPM:
- Log in to NPM with your new credentials.
- Navigate to
Hosts
->Proxy Hosts
. - Click
Add Proxy Host
. - Fill in the Details tab:
- Domain Names: Enter
vaultwarden.yourdomain.com
(your actual domain). - Scheme:
http
- Forward Hostname / IP:
vaultwarden
(This is the service name of your Vaultwarden container as defined in itsdocker-compose.yml
file. Docker's internal DNS resolves this because they are on the samenpm_network
). - Forward Port:
80
(The port Vaultwarden listens on inside its container). - Enable
Block Common Exploits
. - Enable
Websockets Support
.
- Domain Names: Enter
- Click on the SSL tab:
- Under
SSL Certificate
, selectRequest a new SSL Certificate
. - Enable
Force SSL
. - Enable
HTTP/2 Support
(optional but recommended). - Agree to the Let's Encrypt Terms of Service.
- Click
Save
.
- Under
-
Test HTTPS Access:
- NPM will now attempt to obtain the SSL certificate from Let's Encrypt. This might take a minute. You should see the status change in the NPM interface.
- Open a new browser tab and navigate to
https://vaultwarden.yourdomain.com
(using HTTPS). - You should see the Vaultwarden login page.
- Check your browser's address bar for a padlock icon, indicating a secure connection. Click it to view the certificate details – it should be issued by Let's Encrypt for your domain.
Outcome: You have successfully secured your Vaultwarden instance with HTTPS using Nginx Proxy Manager. All traffic between your browser/clients and the server is now encrypted. You access Vaultwarden via your custom domain name over HTTPS, and direct access via IP address and port 8080 should no longer work (or be necessary). This setup is suitable for real-world use.
3. Advanced Vaultwarden Configuration and Features
Now that you have a secure, persistent, and manageable Vaultwarden instance, we can explore advanced configurations and features to further customize, secure, and maintain your setup. This includes tweaking server behavior, enabling two-factor authentication, setting up backups, and managing users or organizations.
Understanding Vaultwarden Environment Variables
One of the primary ways to configure Vaultwarden within a Docker environment is through environment variables. These are key-value pairs passed to the container upon startup, allowing you to modify various settings without altering the container image itself.
You typically define these variables within the environment:
section of your docker-compose.yml
file for the vaultwarden
service.
Why Use Environment Variables?
- Flexibility: Easily change settings without rebuilding the image.
- Security: Keep sensitive information (like SMTP passwords or admin tokens) out of version-controlled
docker-compose.yml
files by using.env
files (though we won't cover.env
files in extreme detail here, know they exist for this purpose). - Standardization: It's the conventional way to configure Dockerized applications.
Key Vaultwarden Environment Variables:
Here are some of the most commonly used and important environment variables (refer to the official Vaultwarden Wiki for a complete, up-to-date list):
SIGNUPS_ALLOWED=true|false
: (Default:true
) Controls whether new users can register. Set tofalse
after creating necessary accounts to prevent unwanted signups. Highly recommended to set tofalse
for security.ADMIN_TOKEN=<your_secure_random_token>
: (Default: not set) Sets a password/token required to access the admin interface at/admin
. Use a long, random string generated with a password manager oropenssl rand -base64 48
. Accessing/admin
allows managing users, settings, and organizations directly. Highly recommended to set this.DOMAIN=https://yourdomain.com
: (Default: not set) Specifies the public URL of your Vaultwarden instance. This is often required for features like YubiKey U2F/FIDO2 authentication, email link generation, and sometimes reverse proxy setups. Set this to your full HTTPS domain.WEBSOCKET_ENABLED=true|false
: (Default:false
, but we enabled it earlier) Enables WebSocket connections for real-time synchronization between clients and the server (e.g., changes made in the web vault reflect instantly in the browser extension). Requires reverse proxy configuration (like theWebsockets Support
toggle in NPM). Generally recommended (true
).LOG_LEVEL=info|warn|error|debug|trace
: (Default:info
) Controls the verbosity of Vaultwarden's logs. Useful for troubleshooting (debug
ortrace
).SMTP_HOST=<smtp.server.com>
: Hostname or IP of your SMTP server for sending emails (e.g., invitations, password hints).SMTP_FROM=<vaultwarden@yourdomain.com>
: The "From" address for outgoing emails.SMTP_PORT=587|465|25
: Port for the SMTP server (e.g., 587 for TLS, 465 for SSL).SMTP_SECURITY=starttls|force_tls|off
: Security protocol (STARTTLS, SSL/TLS, or none).SMTP_USERNAME=<your_smtp_username>
: Username for SMTP authentication.SMTP_PASSWORD=<your_smtp_password>
: Password for SMTP authentication. (Consider using secrets management or.env
files for sensitive values like this).INVITATIONS_ALLOWED=true|false
: (Default:true
if SMTP is configured,false
otherwise) Allows administrators or organization owners to invite new users via email. Requires SMTP configuration.SHOW_PASSWORD_HINT=true|false
: (Default:true
) Whether to allow users to request their password hint via email. Requires SMTP configuration. Set tofalse
if you don't configure SMTP or want to disable this feature.PUSH_ENABLED=true|false
: (Default:false
) Enables push notifications to mobile clients via Bitwarden's push relay service. Requires obtaining specific keys (PUSH_INSTALLATION_ID
,PUSH_INSTALLATION_KEY
) from Bitwarden (requires an account athttps://bitwarden.com/host
).
By strategically setting these variables, you can tailor Vaultwarden's behavior precisely to your requirements, enhancing security and functionality. Remember to restart the Vaultwarden container (docker compose down && docker compose up -d
) after modifying environment variables in your docker-compose.yml
file.
Workshop Customizing Vaultwarden Settings
Goal: Modify your Vaultwarden configuration using environment variables to disable signups and set an admin token.
Prerequisites:
- Vaultwarden running via Docker Compose and accessible via HTTPS (from previous workshops).
- Access to the server's terminal and your Vaultwarden
docker-compose.yml
file (~/vaultwarden/docker-compose.yml
). - A tool to generate a random string (like a password manager or the
openssl
command).
Steps:
-
Generate an Admin Token: Use a secure method to generate a long, random string. Using
Explanation:openssl
on your server is a convenient option:openssl rand
generates random bytes,-base64
encodes them into a printable string,48
specifies the number of random bytes (resulting in a 64-character base64 string).- Copy the generated string. Treat this like a password. Example output (yours will be different):
aVeryLong+Random/StringGeneratedByOpenSSL12345==
- Copy the generated string. Treat this like a password. Example output (yours will be different):
-
Edit the Docker Compose File: Open your Vaultwarden
docker-compose.yml
file for editing: -
Add Environment Variables: Locate the
environment:
section under thevaultwarden
service. Add the following variables, replacing<your_secure_random_token>
with the token you just generated:version: '3.8' services: vaultwarden: image: vaultwarden/server:latest container_name: vaultwarden restart: unless-stopped volumes: - vw-data:/data/ networks: - npm_network environment: - WEBSOCKET_ENABLED=true - DOMAIN=https://vaultwarden.yourdomain.com # Ensure this is correct # --- ADD THESE LINES --- - SIGNUPS_ALLOWED=false # Disable new user registrations - ADMIN_TOKEN=<your_secure_random_token> # Set the admin panel token # --- END ADDED LINES --- volumes: vw-data: networks: npm_network: external: true
- Ensure correct indentation (usually 2 spaces under
environment:
).
- Ensure correct indentation (usually 2 spaces under
-
Save and Close the File:
- In
nano
:Ctrl+X
,Y
,Enter
.
- In
-
Apply Configuration Changes: Navigate to the directory containing the
Explanation:docker-compose.yml
file and restart the container:docker compose down
stops and removes the old container.docker compose up -d
creates and starts a new container using the updated configuration from thedocker-compose.yml
file, including the new environment variables. The persistent data from thevw-data
volume is automatically re-attached. -
Verify Signup Disabled:
- Open an incognito/private browser window.
- Navigate to your Vaultwarden instance:
https://vaultwarden.yourdomain.com
. - Look for the "Create Account" button or link. It should now be missing or disabled. This confirms
SIGNUPS_ALLOWED=false
is active.
-
Access the Admin Panel:
- In your browser, navigate to
https://vaultwarden.yourdomain.com/admin
. - You should be prompted to enter the admin token.
- Paste the secure random token you generated in Step 1 into the field and click
Login
.
- In your browser, navigate to
-
Explore the Admin Panel: You should now have access to the Vaultwarden admin interface. Briefly explore the sections available (Users, Settings, Organizations). You can see your own user account listed under Users.
Outcome: You have successfully customized your Vaultwarden instance using environment variables. You've enhanced security by disabling public signups and protecting the administrative interface with a strong token. You are now familiar with the process of modifying the configuration and applying changes using Docker Compose.
Enabling Two-Factor Authentication (2FA)
Two-factor authentication (2FA) adds a critical layer of security to your Vaultwarden account. Even if your master password becomes compromised, an attacker would still need your second factor (e.g., a code from an authenticator app, a hardware key) to log in.
Vaultwarden (like Bitwarden) supports several 2FA methods for user accounts:
- Authenticator App (TOTP): Time-based One-Time Passwords using apps like Google Authenticator, Authy, Aegis Authenticator (Android), or Raivo OTP (iOS). This is the most common method. Users scan a QR code or enter a secret key into their app, which then generates rotating 6-digit codes.
- FIDO2 WebAuthn: Uses hardware security keys (like YubiKey) or platform authenticators (like Windows Hello or Touch ID) based on the FIDO2/WebAuthn standard. This offers very strong phishing resistance. Requires
DOMAIN
environment variable to be set correctly. - YubiKey OTP: Uses the OTP generation feature of YubiKey hardware tokens via Yubico's cloud validation service. Requires obtaining API credentials from Yubico.
- Duo Security: Integrates with Duo's push notification and authentication service. Requires a Duo account and API credentials.
- Email: Sends a code via email for verification. Requires SMTP to be configured correctly in Vaultwarden's environment variables. Generally considered less secure than TOTP or FIDO2 due to potential email account compromise.
Enabling 2FA (User Perspective):
Individual users enable and manage their 2FA methods within their own account settings after logging into Vaultwarden (web vault, desktop app, or browser extension).
- Log in to the Vaultwarden Web Vault (
https://vaultwarden.yourdomain.com
). - Go to
Settings
(usually top-right). - Select
Two-step Login
from the left-hand menu. - Choose a provider (e.g., "Authenticator App").
- Click "Manage" and follow the on-screen instructions (e.g., enter your master password, scan the QR code with your authenticator app, enter the generated verification code).
- Crucially, save the provided Recovery Code in a safe place. This code allows you to regain access if you lose your second factor device. Store it as securely as your master password.
Server-Side Configuration (Optional but Recommended):
While users enable 2FA individually, administrators can influence 2FA policies through the Admin Panel (/admin
), especially within Organizations (which we'll touch on later).
You can also enforce certain server-level requirements via environment variables, for example:
DISABLE_2FA_REMEMBER=true
: Prevents users from checking the "Remember Me" box on the 2FA prompt, forcing them to enter a 2FA code more frequently.
Recommendation: Encourage all users to enable at least one 2FA method, preferably Authenticator App (TOTP) or FIDO2 WebAuthn, for significantly enhanced account security.
Workshop Setting Up Server-Side 2FA (User Account TOTP)
Goal: Enable and configure Two-Factor Authentication using an Authenticator App (TOTP) for your own Vaultwarden user account.
Prerequisites:
- Your Vaultwarden instance is running and accessible via HTTPS.
- You have successfully logged into your user account in the Vaultwarden Web Vault (
https://vaultwarden.yourdomain.com
). - An authenticator app installed on your smartphone (e.g., Authy, Google Authenticator, Aegis, Raivo OTP).
Steps:
-
Log In to Vaultwarden Web Vault: Ensure you are logged into
https://vaultwarden.yourdomain.com
with your user account (not the admin panel). -
Navigate to Account Settings: Click on your email address or profile icon in the top-right corner and select
Account Settings
. -
Navigate to Two-step Login: In the Settings menu on the left, click on
Two-step Login
. -
Select Authenticator App: Find the "Authenticator App" provider in the list. It will likely show as "Not Enabled". Click the
Manage
button next to it. -
Enter Master Password: For security, you will be prompted to re-enter your Vaultwarden Master Password. Enter it and click
Continue
. -
Scan the QR Code:
- A screen will appear displaying a QR code and a secret key (text string).
- Open your authenticator app on your smartphone.
- Choose the option to add a new account (usually a
+
icon). - Select the option to scan a QR code.
- Point your phone's camera at the QR code displayed in the Vaultwarden web vault.
- Your authenticator app should recognize it and add a new entry, typically named after your email address and the Vaultwarden domain. It will start generating 6-digit codes that refresh every 30 seconds.
- (Alternative) Manual Entry: If you cannot scan the QR code, you can manually enter the secret key provided below the QR code into your authenticator app.
-
Enter Verification Code:
- Look at the 6-digit code currently displayed in your authenticator app for the Vaultwarden entry.
- Enter this code into the
Verification Code
field in the Vaultwarden web vault (below the QR code). - Click
Enable
.
-
Save Recovery Code:
- Upon successful enablement, Vaultwarden will display a Recovery Code. This code is critical. If you lose access to your authenticator app (e.g., lose or reset your phone), this recovery code is the ONLY way to disable 2FA and regain access to your account.
- Copy this recovery code immediately.
- Store it in a very safe place, separate from your authenticator device, with the same level of security as your master password (e.g., print it and store securely, save it in another password manager if applicable, write it down in multiple secure locations).
- Check the box confirming "I have saved my recovery code" and click
Close
.
-
Verify 2FA Status: Back on the
Two-step Login
screen, the Authenticator App should now show as "Enabled". -
Test 2FA:
- Log out of your Vaultwarden web vault (Profile Icon -> Log Out).
- Log back in using your email and master password.
- After entering your password, you should now be prompted for the
Authenticator Code
. - Open your authenticator app, find the code for Vaultwarden, and enter it.
- Click
Continue
orLogin
. You should successfully log in.
Outcome: You have successfully enabled TOTP-based two-factor authentication for your Vaultwarden account. Your account is now significantly more secure against unauthorized access, even if your master password were to be compromised. Remember the importance of safeguarding both your master password and your recovery code.
Backup and Restore Strategies
Self-hosting Vaultwarden means you are solely responsible for backups. Losing access to your password vault due to data corruption, hardware failure, accidental deletion, or server compromise can be catastrophic. Implementing a reliable backup strategy is not optional; it's essential.
What Needs to Be Backed Up?
The critical components of your Vaultwarden setup that require backup are:
-
Vaultwarden Data Volume: This is the most important part. The named Docker volume (e.g.,
vw-data
) mounted at/data
inside the container holds:db.sqlite3
: The SQLite database containing all vault items (logins, notes, cards, identities), user accounts, organization details, settings, etc. (unless using an external database like PostgreSQL/MySQL, which would need its own backup procedure).attachments
directory: Stores any file attachments uploaded by users.sends
directory: Stores data related to Bitwarden Send items.rsa_key.pem
andrsa_key.pub.pem
: Private and public RSA keys used for encryption and identification. Losing these keys will render your vault unusable, even if you have the database.config.json
: Some runtime configuration (less critical to back up directly if using environment variables, but included in the volume).- Icons cache (
icon_cache
directory).
-
Configuration Files:
docker-compose.yml
: Your primary configuration file defining the service, volumes, networks, ports (if any), and environment variables..env
file (if used): If you store sensitive environment variables (likeADMIN_TOKEN
, SMTP passwords) in a separate.env
file, this needs to be backed up securely.
-
(Optional) Reverse Proxy Configuration:
- If using Nginx Proxy Manager, back up its Docker volumes (
npm-data
,npm-letsencrypt
) which contain its configuration and SSL certificates. - If using manual Nginx/Apache/Caddy/Traefik configurations, back up those config files.
- If using Nginx Proxy Manager, back up its Docker volumes (
Backup Strategy Considerations:
- Frequency: How often should you back up? Daily is recommended for a password manager, as new credentials might be added frequently. Adjust based on your usage patterns.
- Method:
- Volume Snapshot (If supported): Some filesystems (like ZFS) or VM hypervisors offer snapshot capabilities, which can be very efficient.
- Direct Copy: Stop the Vaultwarden container briefly and copy the contents of the Docker volume directory. Or, copy while running, accepting a minimal risk of inconsistency if the database is being written to at that exact moment (usually acceptable for SQLite).
docker cp
: Copy files directly from the container (less ideal for the whole data directory).- Database-specific tools (if using external DB).
- Automation: Backups must be automated using tools like
cron
(Linux) or Task Scheduler (Windows) running a script. Manual backups are prone to being forgotten. - Storage Location (3-2-1 Rule):
- Keep at least 3 copies of your data.
- Store the copies on 2 different media types (e.g., server disk + external USB drive).
- Keep 1 copy off-site (e.g., encrypted cloud storage, separate physical location). This protects against local disasters (fire, theft).
- Encryption: Encrypt your backups, especially if storing them off-site or in the cloud, as they contain highly sensitive data. Tools like
gpg
orrclone
's encryption features can be used. - Retention: Decide how long to keep backups (e.g., daily backups for 7 days, weekly for 4 weeks, monthly for 6 months).
- Testing: Regularly test your restore process to ensure your backups are valid and you know how to recover from them. A backup is useless if it can't be restored.
Restoring Vaultwarden:
- Stop the Container:
docker compose down
- Restore Volume Data: Locate the Docker volume directory on the host (find path with
docker volume inspect vw-data
) or manage via Docker. Remove any corrupted data and copy the contents from your backup into the volume directory. Ensure file permissions and ownership are correct (usually needs to be owned by UID/GID that Docker runs the container as, often discoverable viadocker inspect
). - Restore Configuration: Ensure your
docker-compose.yml
(and.env
file if used) are correct. - Restart Container:
docker compose up -d
- Test: Log in and verify your data is present and correct.
A robust backup plan is your safety net for self-hosting critical services like Vaultwarden.
Workshop Implementing Automated Backups
Goal: Create a simple automated backup script for the Vaultwarden data volume and schedule it using cron
. This script will copy the volume data, compress it, timestamp it, and store it locally. (Note: Off-site storage is crucial but beyond the scope of this basic workshop).
Prerequisites:
- Vaultwarden running via Docker Compose with the named volume
vw-data
. - Access to the server's terminal with
sudo
or root privileges (to inspect volume path and potentially set cron jobs). tar
andgzip
utilities installed (usually default on Linux).cron
daemon installed and running (usually default).
Steps:
-
Identify the Volume Path on Host: Docker manages the storage for named volumes. We need to find where the
Explanation: This command outputs JSON details about the volume. Look for thevw-data
volume physically resides on the host filesystem."Mountpoint"
value. It will be a path similar to/var/lib/docker/volumes/vw-data/_data
. Copy this path accurately. Let's assume it's/var/lib/docker/volumes/vw-data/_data
for this workshop. -
Create a Backup Directory: Create a directory outside the Docker volume area to store your backups.
Explanation: Creates the directorysudo mkdir -p /opt/vaultwarden-backups sudo chown $USER:$USER /opt/vaultwarden-backups # Optional: Change ownership for easier access by your user
/opt/vaultwarden-backups
. The-p
flag ensures parent directories are created if needed. Changing ownership allows your regular user to write backups there withoutsudo
in the script (adjust user/group if needed). -
Create the Backup Script:
- Create a new file for the script:
-
Paste the following script content into
nano
. Carefully replace/var/lib/docker/volumes/vw-data/_data
with the actualMountpoint
path you found in Step 1.#!/bin/bash # --- Configuration --- # !!! IMPORTANT: Replace with the actual Mountpoint path from 'docker volume inspect vw-data' !!! VAULTWARDEN_VOLUME_PATH="/var/lib/docker/volumes/vw-data/_data" # Directory where backups will be stored BACKUP_DIR="/opt/vaultwarden-backups" # Backup filename format (includes date and time) TIMESTAMP=$(date +"%Y%m%d_%H%M%S") BACKUP_FILENAME="vaultwarden_backup_${TIMESTAMP}.tar.gz" BACKUP_FILE_PATH="${BACKUP_DIR}/${BACKUP_FILENAME}" # Number of days to keep backups (optional: cleanup old backups) RETENTION_DAYS=7 # --- Script Logic --- echo "Starting Vaultwarden backup..." # Check if source volume path exists if [ ! -d "$VAULTWARDEN_VOLUME_PATH" ]; then echo "ERROR: Vaultwarden volume path not found at ${VAULTWARDEN_VOLUME_PATH}" exit 1 fi # Check if backup directory exists if [ ! -d "$BACKUP_DIR" ]; then echo "ERROR: Backup directory not found at ${BACKUP_DIR}" exit 1 fi # Create the compressed backup archive # Using sudo because /var/lib/docker/volumes is often root-owned echo "Creating backup archive at ${BACKUP_FILE_PATH}..." sudo tar -czf "${BACKUP_FILE_PATH}" -C "${VAULTWARDEN_VOLUME_PATH}" . # Explanation: # tar: Tape Archiver utility # -c: Create an archive # -z: Compress using gzip # -f: Specify the filename of the archive (${BACKUP_FILE_PATH}) # -C: Change directory to ${VAULTWARDEN_VOLUME_PATH} before adding files. This prevents including the full path in the archive. # .: Add all files and directories from the current directory (which is now ${VAULTWARDEN_VOLUME_PATH}) # Check if tar command was successful if [ $? -eq 0 ]; then echo "Backup created successfully: ${BACKUP_FILE_PATH}" else echo "ERROR: Backup creation failed." # Optional: Remove partial backup file if it exists [ -f "${BACKUP_FILE_PATH}" ] && sudo rm "${BACKUP_FILE_PATH}" exit 1 fi # Optional: Cleanup old backups if [ "$RETENTION_DAYS" -gt 0 ]; then echo "Cleaning up backups older than ${RETENTION_DAYS} days in ${BACKUP_DIR}..." # Use sudo because the backup files might be owned by root depending on how tar was run sudo find "${BACKUP_DIR}" -name 'vaultwarden_backup_*.tar.gz' -mtime +"${RETENTION_DAYS}" -exec echo "Deleting old backup: {}" \; -exec sudo rm {} \; # Explanation: # find: Search for files # ${BACKUP_DIR}: Directory to search in # -name '...': Match files with this pattern # -mtime +N: Find files modified more than N days ago # -exec ... \;: Execute a command (echo, rm) on each found file fi echo "Vaultwarden backup finished." exit 0
-
Save and close the file (
Ctrl+X
,Y
,Enter
).
-
Make the Script Executable:
-
Perform an Initial Manual Backup: Run the script manually to test it. You might be prompted for your
sudo
password.- Check the output for success messages.
- Verify that a
.tar.gz
file has been created in/opt/vaultwarden-backups
:
-
Schedule Automated Backups with Cron:
- Edit the crontab for the root user (necessary because the script uses
sudo
to access the Docker volume path and potentially delete old backups): - You might be asked to choose an editor (select
nano
if unsure). -
Add the following line to the end of the file. This example schedules the backup to run daily at 2:30 AM. Adjust the path
/home/your_user/backup-vaultwarden.sh
to the actual full path where you saved your script.Explanation:# Example: Run Vaultwarden backup daily at 2:30 AM 30 2 * * * /home/your_user/backup-vaultwarden.sh >> /var/log/vaultwarden_backup.log 2>&1
30 2 * * *
: Cron schedule (Minute=30, Hour=2, DayOfMonth=, Month=, DayOfWeek=*) -> Run at 2:30 AM every day./home/your_user/backup-vaultwarden.sh
: Full path to your backup script. Replaceyour_user
with your actual username.>> /var/log/vaultwarden_backup.log
: Appends the standard output of the script to a log file.2>&1
: Redirects standard error (stderr) to the same place as standard output (stdout), so errors are also logged.- Save and close the crontab file (
Ctrl+X
,Y
,Enter
in nano).
- Save and close the crontab file (
- Edit the crontab for the root user (necessary because the script uses
-
Verify Cron Job (Optional): List the cron jobs for root to ensure yours is listed:
Outcome: You have created a script that backs up your critical Vaultwarden data volume, compresses it, timestamps it, and optionally cleans up old backups. You have scheduled this script to run automatically using cron
. Regularly check the log file (/var/log/vaultwarden_backup.log
) for successful completion or errors. Remember this only creates local backups; implementing an off-site copy (e.g., using rclone
to sync the backup directory to cloud storage) is the critical next step for a complete strategy.
User Administration and Organization Management
While Vaultwarden can be used individually, it also supports multi-user environments and secure sharing through Organizations. Administration tasks are primarily handled through the web-based Admin Panel.
Accessing the Admin Panel:
- Navigate to
https://vaultwarden.yourdomain.com/admin
. - Enter the
ADMIN_TOKEN
you configured via environment variables.
Key Admin Panel Features:
- Dashboard: Overview statistics (users, organizations, etc.).
- Users:
- View all registered users.
- Manually invite new users (requires SMTP configuration and
INVITATIONS_ALLOWED=true
). - Force password resets (sends email if SMTP configured).
- Edit user details (name).
- Delete users (permanently removes the user and their personal vault).
- Disable/Enable users.
- Organizations:
- View existing organizations.
- Manually create new organizations.
- Delete organizations (permanently removes the organization, its collections, and shared items - does not delete member user accounts).
- Settings:
- Configure general server settings (many overlap with environment variables; environment variables usually take precedence). You can disable signups, enable invitations, configure SMTP, etc., directly here if not set via environment variables.
- Manage settings for Duo, YubiKey validation servers if used.
- Diagnostics: View log files and other diagnostic information.
Organizations:
Organizations are the core feature for securely sharing credentials and notes among multiple users (e.g., family members, small teams).
- Structure: An Organization contains Members (users) and Collections.
- Collections: Think of Collections as folders within an Organization. Items (logins, notes) belonging to the Organization are placed into one or more Collections.
- Permissions: Access control is managed by assigning users specific roles within the Organization (e.g., Owner, Admin, User, Manager) and granting them permissions to specific Collections (e.g., Read Only, Hide Passwords, Can Edit).
- Creation: Organizations can be created by users (if allowed by server settings) or by the Admin via the Admin Panel.
- Management: Once created, Organization Owners/Admins manage members, collections, and permissions through the regular Vaultwarden web vault interface (not the
/admin
panel). Users invited to an Organization will see it appear in their vault.
Use Cases:
- Families: Share streaming service logins, Wi-Fi passwords, shared online shopping accounts.
- Small Teams: Share access to development servers, internal tools, group email accounts.
Managing users and organizations allows Vaultwarden to scale beyond individual use, providing a collaborative password management solution under your control.
Workshop Creating Organizations and Managing Users
Goal: Use the Admin Panel to invite a new user (simulated if SMTP isn't configured) and then create an Organization through the regular web vault to share an item.
Prerequisites:
- Vaultwarden running, accessible via HTTPS, with
ADMIN_TOKEN
set. - You can access the Admin Panel (
https://vaultwarden.yourdomain.com/admin
). - You are logged into your primary user account in the regular web vault.
- (Optional but helpful) SMTP configured via environment variables to test actual email invitations.
Steps:
Part 1: User Management (Admin Panel)
-
Access Admin Panel: Navigate to
https://vaultwarden.yourdomain.com/admin
and log in with yourADMIN_TOKEN
. -
Navigate to Users: Click on
Users
in the top navigation bar. You should see your own user account listed. -
Invite a New User (Simulated/Actual):
- Click the
Invite User
button. - Enter an email address for the new user (e.g.,
friend@example.com
). Use a real secondary email you own if SMTP is configured and you want to test the full flow. Otherwise, any fake email works for simulation. - Click
Save
. - If SMTP is configured: The user will receive an email invitation with a link to create their account. They will set their own master password upon registration.
- If SMTP is NOT configured: An invitation entry is created internally, but no email is sent. The user cannot register via this method. This step primarily demonstrates the interface. Alternatively, you could temporarily set
SIGNUPS_ALLOWED=true
, have the user register manually, and then set it back tofalse
. For this workshop, we'll assume the user exists or simulate the invitation.
- Click the
-
(Optional) Observe User List: The invited (or manually registered) user should now appear in the Users list in the Admin Panel. You can click on their email to see details or perform actions like Disable/Delete.
Part 2: Organization Creation and Sharing (Web Vault)
-
Log In to Web Vault: Go to
https://vaultwarden.yourdomain.com
and log in with your primary user account (not the Admin Token). -
Create a New Organization:
- In the main vault view, look for an option to create a new organization. This might be a
+
button next to "Organizations" in the left pane or under Settings. Often, it's via the+ New
dropdown ->Organization
. - Enter an Organization Name (e.g.,
Shared Logins
). - Enter your Billing Email (this is just informational in Vaultwarden, enter your own email).
- Choose a plan: Select the Free plan (Vaultwarden unlocks features often tied to paid plans in official Bitwarden).
- Click
Submit
.
- In the main vault view, look for an option to create a new organization. This might be a
-
Manage the Organization:
- You should be taken to the Organization's management view (or find it listed under "Organizations" in the left pane).
- Select the
Manage
tab within the Organization view. - Invite User: Click
Invite User
. Enter the email address of the user you invited/created in Part 1 (e.g.,friend@example.com
). Choose a User Type (e.g.,User
). Select Access Control (e.g.,Regular user
). ClickInvite
.- (If SMTP configured, the user gets an email to accept the Org invite).
-
Create a Collection:
- Still in the Organization's
Manage
tab, selectCollections
. - Click
New Collection
. - Enter a name (e.g.,
Streaming Services
). - Click
Save
.
- Still in the Organization's
-
Assign User Access to Collection:
- Go back to the
Members
section within the Organization'sManage
tab. - Click on the invited user (
friend@example.com
). - Under
Collection Access
, find the "Streaming Services" collection. - Select the desired permission level from the dropdown (e.g.,
Read Only
orCan Edit
). - Click
Save
.
- Go back to the
-
Add an Item to the Organization/Collection:
- Go back to your main Vault view.
- Click the
+ Add Item
button. - Create a sample Login item (e.g., Name:
Shared Netflix
, User:shared@example.com
, Pass:SharedPass123!
). - Crucially: In the
Ownership
section at the bottom of the item form, select your Organization (Shared Logins
) instead of "My Vault". - Once the Organization is selected, choose the Collection (
Streaming Services
) where this item should reside. - Click
Save
.
-
Verify Item in Organization:
- In your Vault, click on the
Shared Logins
Organization in the left pane. - You should see the "Streaming Services" collection and the "Shared Netflix" item within it.
- In your Vault, click on the
-
(Simulated) User Access: If the invited user (
friend@example.com
) were to log in and accept the Organization invitation, they would see theShared Logins
Organization in their vault. Clicking on it, they would see theStreaming Services
collection and theShared Netflix
item, with permissions according to what you granted in Step 9.
Outcome: You have used the Admin Panel to manage users (simulated invitation) and the regular Web Vault to create an Organization, add a Collection, manage members, and share a vault item securely within that Organization. This demonstrates the collaborative capabilities of Vaultwarden.
Troubleshooting Common Issues
Even with careful setup, you might encounter issues. Here’s a breakdown of common problems and how to diagnose them:
1. Cannot Access Web UI (Connection Refused / Timeout):
- Container Running? Check if the Vaultwarden and Reverse Proxy (NPM) containers are running:
docker ps
. If not, check logs:docker logs vaultwarden
ordocker logs npm
. If stopped, try restarting:docker compose restart vaultwarden
ordocker compose restart npm
. If they fail to start, logs are key. - Port Mapping (If direct access used initially): Double-check the
-p HOST:CONTAINER
mapping indocker run
ordocker-compose.yml
. Is the host port correct? Is it being used by another service (sudo ss -tulnp | grep <port>
)? - Reverse Proxy Config:
- Is NPM running (
docker ps
)? Can you access the NPM admin UI (http://<server_ip>:81
)? - In NPM -> Proxy Hosts, double-check the configuration for your Vaultwarden domain:
- Domain name correct?
- Forward Hostname / IP correct? (Should be the Vaultwarden service name from its
docker-compose.yml
, e.g.,vaultwarden
). - Forward Port correct? (Should be the internal port Vaultwarden listens on, usually
80
). - Scheme correct? (
http
for proxy-to-Vaultwarden traffic).
- Check NPM logs:
docker logs npm
. Look for errors related to your domain or upstream connection failures.
- Is NPM running (
- Firewall: Are ports 80 and 443 (for NPM/HTTPS) and potentially 8080 (if testing direct basic access) allowed on the server's firewall (
sudo ufw status
) and any cloud provider firewall? - DNS: Is your domain name (
vaultwarden.yourdomain.com
) correctly pointing to your server's public IP address? Useping vaultwarden.yourdomain.com
ornslookup vaultwarden.yourdomain.com
from an external machine. Check DNS propagation. - Docker Network: Are Vaultwarden and NPM on the same custom Docker network (e.g.,
npm_network
)? Inspect containers (docker inspect vaultwarden
,docker inspect npm
) and check theNetworks
section. If not, correct yourdocker-compose.yml
files and recreate (docker compose down && docker compose up -d
).
2. HTTPS / SSL Certificate Issues (Security Warnings):
- Certificate Not Issued: Check the NPM UI for the Proxy Host's SSL tab. Did Let's Encrypt issue the certificate successfully? If not, check NPM logs (
docker logs npm
) for errors from Let's Encrypt (often related to DNS not propagating, port 80 not being open/reachable from the internet, or Let's Encrypt rate limits). - Mixed Content Warnings: Usually occurs if the
DOMAIN
environment variable in Vaultwarden'sdocker-compose.yml
is not set correctly to thehttps://
address or if the reverse proxy isn't forcing HTTPS properly. EnsureDOMAIN=https://vaultwarden.yourdomain.com
is set and NPM has "Force SSL" enabled. - Expired Certificate: NPM should automatically renew Let's Encrypt certificates. If it fails, check NPM logs. Ensure the NPM container is running correctly and can reach the internet.
3. Vaultwarden Container Fails to Start:
- Check Logs: The absolute first step:
docker logs vaultwarden
. Look for specific error messages. - Volume Permissions: Sometimes Docker has issues writing to the volume mountpoint, especially if permissions were changed manually. Errors might mention "Permission denied" or database locking issues. Ensure the directory on the host (
/var/lib/docker/volumes/vw-data/_data
) has appropriate ownership/permissions for the user ID the container runs as (often can be found viadocker inspect vaultwarden
or may require research/testing). Using Docker managed volumes usually avoids this. - Incorrect Environment Variables: A typo or invalid value in an environment variable in
docker-compose.yml
can prevent startup. Review recent changes. - Port Conflicts (Internal): Less common, but ensure Vaultwarden isn't configured internally (e.g., via
ROCKET_PORT
env var if you changed it) to use a port already in use within the container's network namespace (unlikely unless complex setup). - Database Corruption: If the server crashed or the container was stopped uncleanly, the
db.sqlite3
file might become corrupted. Logs might indicate database errors. Restoring from backup is the safest solution.
4. Clients Cannot Sync / Websockets Not Working:
WEBSOCKET_ENABLED=true
: Ensure this environment variable is set in Vaultwarden'sdocker-compose.yml
.- Reverse Proxy Websocket Support: Ensure "Websockets Support" is enabled in the NPM Proxy Host settings for your Vaultwarden domain. Check NPM logs if issues persist.
- Firewall/Network: Ensure no intermediate firewall or proxy is blocking WebSocket connections (which use HTTP/S initially but then upgrade the connection).
5. Admin Panel (/admin
) Inaccessible:
- Correct URL: Ensure you're using
https://vaultwarden.yourdomain.com/admin
. ADMIN_TOKEN
Set? Check ifADMIN_TOKEN
is defined in yourdocker-compose.yml
. If not set, the admin panel is disabled by default.- Correct Token: Are you entering the exact token value? Copy-paste carefully.
- Restart Container: If you recently added/changed the
ADMIN_TOKEN
, ensure you restarted the container (docker compose down && docker compose up -d
).
General Troubleshooting Steps:
- Check Logs:
docker logs <container_name>
is your best friend. - Simplify: Temporarily remove complexity. Bypass the reverse proxy? Disable recently added environment variables?
- Check Resources: Is the server out of memory or disk space (
free -h
,df -h
)? - Update: Ensure Docker, Docker Compose, and the Vaultwarden image (
docker pull vaultwarden/server:latest
, thendocker compose up -d
) are reasonably up-to-date. - Consult Documentation: Review the official Vaultwarden Wiki and Nginx Proxy Manager documentation.
- Community: Search online forums or communities for similar error messages.
Workshop Diagnosing a Failed Container
Goal: Simulate a common configuration error in docker-compose.yml
that prevents the Vaultwarden container from starting correctly, and then use diagnostic tools to identify and fix the problem.
Scenario: We will intentionally misconfigure an environment variable with an invalid value, causing Vaultwarden to fail during startup.
Prerequisites:
- Your working Vaultwarden setup managed by
docker-compose
(~/vaultwarden/docker-compose.yml
). - Access to the server's terminal.
Steps:
-
Introduce a Configuration Error:
- Edit your Vaultwarden
docker-compose.yml
file: - Go to the
environment:
section. Add a line with an invalid value for a known variable. For example, let's intentionally setLOG_LEVEL
to an invalid option: - Save and close the file (
Ctrl+X
,Y
,Enter
).
- Edit your Vaultwarden
-
Attempt to Start the Container:
- Navigate to the Vaultwarden directory:
cd ~/vaultwarden
- Run
docker compose up -d
: - You might see an immediate error, or it might seem to start but then exit quickly.
- Navigate to the Vaultwarden directory:
-
Check Container Status:
- Run
docker ps
. You will likely not see thevaultwarden
container listed as running. - Run
docker ps -a
. You should see thevaultwarden
container listed with a status likeExited (1)
or similar, indicating it started but stopped due to an error. Note the Container ID or Name.
- Run
-
Inspect the Logs:
- This is the most critical step for diagnosis. Use the container name (
vaultwarden
) or its ID fromdocker ps -a
: - Read the log output carefully from the beginning or near the end. You should find error messages indicating the problem. In this case, you'll likely see an error related to the
LOG_LEVEL
configuration, possibly mentioning an "unknown variantINVALID_OPTION
" or similar parsing error for the logging configuration. It might look something like: - The logs clearly point to the invalid environment variable value.
- This is the most critical step for diagnosis. Use the container name (
-
Correct the Configuration:
- Re-edit the
docker-compose.yml
file: - Find the line
- LOG_LEVEL=INVALID_OPTION
. -
Either remove the line entirely (to use the default 'info') or set it to a valid value like
warn
: -
Save and close the file.
- Re-edit the
-
Restart the Container:
- Run
docker compose up -d
again: - Docker Compose will notice the configuration change and recreate the container.
- Run
-
Verify Success:
- Check the status:
docker ps
. Thevaultwarden
container should now be listed with statusUp
. - Check the logs again (optional):
docker logs vaultwarden
. You should see normal startup messages without the previous error. - Try accessing your Vaultwarden instance (
https://vaultwarden.yourdomain.com
) and the admin panel (/admin
) to ensure everything is working as expected.
- Check the status:
Outcome: You have successfully simulated a container startup failure due to a configuration error, used docker ps -a
and docker logs
to diagnose the root cause (invalid environment variable), corrected the docker-compose.yml
file, and restarted the container successfully. This demonstrates a fundamental troubleshooting workflow for Dockerized applications.
Conclusion
Congratulations! You have journeyed through setting up, securing, managing, and maintaining your own Vaultwarden password manager instance.
Starting with the Basic deployment using docker run
, you learned the fundamentals of Docker and got Vaultwarden running quickly. You understood the critical importance of persistent storage using Docker volumes, ensuring your data survives container restarts and updates.
Moving to the Intermediate level, you streamlined management by migrating to Docker Compose, making your configuration declarative and easier to handle. Most importantly, you secured your instance by implementing HTTPS using Nginx Proxy Manager as a reverse proxy, encrypting all communication and making it suitable for real-world use with a custom domain.
In the Advanced section, you delved into finer control using environment variables to customize Vaultwarden's behavior, disabling signups, and securing the admin panel. You enhanced account security by enabling Two-Factor Authentication (TOTP) and learned the vital importance of implementing robust, automated backup strategies to protect your sensitive vault data. You also explored user administration and the power of Organizations for secure sharing. Finally, you gained practical experience in troubleshooting common issues by inspecting container status and logs.
Key Takeaways:
- Self-hosting gives you control but demands responsibility. Security, updates, and backups are paramount.
- Docker and Docker Compose significantly simplify deployment and management.
- HTTPS via a reverse proxy is non-negotiable for security.
- Named volumes are essential for data persistence.
- Regular, automated, and tested backups are your safety net.
- Environment variables offer powerful customization.
- Two-Factor Authentication dramatically increases account security.
- Logs (
docker logs
) are crucial for troubleshooting.
You now possess the knowledge and practical skills to confidently host and manage Vaultwarden. Remember that ongoing maintenance – keeping your server OS, Docker, Vaultwarden, and reverse proxy updated, monitoring logs, and verifying backups – is crucial for long-term stability and security.
Continue exploring Vaultwarden's features, refine your backup strategy (especially adding off-site storage), and enjoy the peace of mind that comes with managing your own secure password vault.