Windows Offline Deployment
This article will walk you through the procedure to install and deploy Bitwarden to your own Windows server in an offline or air-gapped environment. Please review Bitwarden software release support documentation.
warning
Manual installations should be conducted by advanced users only. Only proceed if you are very familiar with Docker technologies and desire more control over your Bitwarden installation.
Manual installations lack the ability to automatically update certain dependencies of the Bitwarden installation. As you upgrade from one version of Bitwarden to the next you will be responsible for changes to required environment variables, changes to nginx default.conf
, changes to docker-compose.yml
, and so on.
We will try to highlight these in the release notes on GitHub. You can also monitor changes to the dependency templates used by the Bitwarden installation script on GitHub.
Before proceeding with the installation, please ensure the following requirements are met:
Docker Engine and Docker Compose are installed and ready to use on your server. During this setup, you must uncheck the Use WSL2 instead of Hyper-V (recommended) option.
Using a machine with internet access, you have downloaded the latest
docker-stub.zip
file from the Bitwarden Server repository's releases page and transferred this file to your server.An offline SMTP server is setup and active in your environment.
(Optional) OpenSSL Windows binaries are installed and ready to use on your server. You may use a self-signed certificate instead of OpenSSL if you wish.
Minimum | Recommended | |
---|---|---|
Processor | x64, 1.4GHz | x64, 2GHz Dual Core |
Memory | 6GB RAM | 8+ GB RAM |
Storage | 76GB | 90GB |
Docker Version | Engine 19+ and Compose 1.24+ | Engine 19+ and Compose 1.24+ |
Running Bitwarden on a Windows Server requires use of nested virtualization. Please check your Hypervisor's documentation to find out if nested virtualization is supported and how to enable it.
tip
If you are running Windows Server as an Azure VM, we recommend a Standard D2s v3 Virtual Machine running Windows Server 2022, which meets all system requirements including support for nested virtualization. You will also need to select Security Type: Standard rather than the default Trusted launch virtual machines.
By default, Bitwarden will be served through ports 80 (http
) and 443 (https
) on the host machine. Open these ports so that Bitwarden can be accessed from within and/or outside the network. You may opt to choose different ports during installation.
tip
If you are using Windows Firewall, Docker Desktop for Windows will not automatically add an exception for itself in Windows Firewall. Add exceptions for TCP ports 80 and 443 (or chosen alternative ports) to prevent related errors.
We recommend configuring a domain name with DNS records that point to your host machine (for example, bitwarden.example.com
), especially if you are serving Bitwarden over the internet.
Open PowerShell and create a Bitwarden local user by running the following command:
PS C:\> $Password = Read-Host -AsSecureString
After running the above command, enter the desired password in the text input dialog. After specifying a password, run the following command:
New-LocalUser "Bitwarden" -Password $Password -Description "Bitwarden Local Admin"
As the newly created user, create a Bitwarden folder under C:\
:
PS C:\> mkdir Bitwarden
Once you install Docker Desktop, navigate to Settings → Resources → File Sharing and add the created directory (C:\Bitwarden
) to the Resources list. Select Apply & Restart to apply your changes.
To configure your machine with the assets required for your Bitwarden server:
tip
If you have created a Bitwarden user & directory, complete the following as the Bitwarden
user.
Create a new directory in
C:\Bitwarden
namedbwdata
and extractdocker-stub.zip
to it.
Once unzipped, thebwdata
directory will match what thedocker-compose.yml
file's volume mapping expects. You may, if you wish, change the location of these mappings on the host machine.In
bwdata\env\global.override.env
, edit the following environment variables:globalSettings__baseServiceUri__vault=
: Enter the domain of your Bitwarden instance.globalSettings__sqlServer__ConnectionString=
: Replace theRANDOM_DATABASE_PASSWORD
with a secure password for use in a later step.globalSettings__identityServer__certificatePassword=
: Set a secure certificate password for use in a later step.globalSettings__internalIdentityKey=
: ReplaceRANDOM_IDENTITY_KEY
with a random key string.globalSettings__oidcIdentityClientKey=
: ReplaceRANDOM_IDENTITY_KEY
with a random key string.globalSettings__duo__aKey=
: ReplaceRANDOM_DUO_AKEY
with a random key string.globalSettings__installation__id=
: Enter an installation id retrieved from https://bitwarden.com/host.globalSettings__installation__key=
: Enter an installation key retrieved from https://bitwarden.com/host.globalSettings__pushRelayBaseUri=
: This variable should be blank. See Configure Push Relay for more information.tip
At this time, consider also setting values for all
globalSettings__mail__smtp__
variables and foradminSettings__admins
. Doing so will configure the SMTP mail server used to send invitations to new organization members and provision access to the System Administrator Portal.
Generate a
identity.pfx
certificate for the identity container. You can do using OpenSSL or using any tool to generate a self-signed certificate. If you're using OpenSSL, run the following commands:openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout identity.key -out identity.crt -subj "/CN=Bitwarden IdentityServer" -days 10950
and
openssl pkcs12 -export -out ./identity/identity.pfx -inkey identity.key -in identity.crt -passout pass:IDENTITY_CERT_PASSWORD
In the above command, replace
IDENTITY_CERT_PASSWORD
with the certificate password created and used in Step 2.Move
identity.pfx
to the mapped volume directory (by default,.\bwdata\identity
).Copy
identity.pfx
to the.\bwdata\ssl
directory.Create a subdirectory in
.\bwdata\ssl
named for your domain.Provider a trusted SSL certificate and private key in the newly created
.\bwdata\ssl\bitwarden.example.com
subdirectory.note
This directory is mapped to the NGINX container at
\etc\ssl
. If you can't provide a trusted SSL certificate, front the installation with a proxy that provides an HTTPS endpoint to Bitwarden client applications.In
.\bwdata\nginx\default.conf
:Replace all instances of
bitwarden.example.com
with your domain, including in theContent-Security-Policy
header.Set the
ssl_certificate
andssl_certificate_key
variables to the paths of the certificate and private key provided in Step 6.Take one of the following actions, depending on your certificate setup:
If using a trusted SSL certificate, set the
ssl_trusted_certificate
variable to the path to your certificate.If using a self-signed certificate, comment out the
ssl_trusted_certificate
variables.
In
.\bwdata\env\mssql.override.env
, replaceRANDOM_DATABASE_PASSWORD
with the password created in Step 2.In
.\bwdata\web\app-id.json
, replacebitwarden.example.com
with your domain.
To get docker images for use on your offline machine:
From an internet-connected machine, download all
bitwarden/xxx:latest
docker images, as listed in thedocker-compose.yml
file indocker-stub.zip
.Save each image to a
.img
file, for example:docker image save -o mssql.img bitwarden/mssql:version
Transfer all
.img
files to your offline machine.On your offline machine, load each
.img
file to create your local docker images, for example:docker image load -i mssql.img
Start your Bitwarden server with the following command:
docker-compose -f ./docker/docker-compose.yml up -d
Verify that all containers are running correctly:
docker ps

Congratulations! Bitwarden is now up and running at https://your.domain.com
. Visit the web vault in your browser to confirm that it's working.
You may now register a new account and log in. You will need to have configured SMTP environment variables (see Environment Variables) in order to verify the email for your new account.
If you are planning to self-host a Bitwarden organization, see self-host an organization to get started.
For additional information see self hosting FAQs.
Updating a self-hosted server that has been installed and deployed manually is different from the standard update procedure. To update your manually-installed server:
Download the latest
docker-stub.zip
archive from the releases pages on GitHub.Unzip the new
docker-stub.zip
archive and compare its contents with what's currently in yourbwdata
directory, copying anything new to the pre-existing files inbwdata
.
Do not overwrite your pre-existingbwdata
directory with the contents of the newerdocker-stub.zip
archive, as this would overwrite any custom configuration work you've done.Download the latest container images and transfer them to your offline machine as documented above.
Run the following command to restart your server with your updated configuration and the latest containers:
docker-compose -f ./docker/docker-compose.yml down && docker-compose -f ./docker/docker-compose.yml up -d