Setup Guide
This page will show you how to set up a local Bitwarden server for development purposes.
The Bitwarden server is comprised of several services that can run independently. For a basic development setup, you will need the Api and Identity services.
There are two ways to run the server locally:
- Aspire (recommended): the
AppHostproject in the server repository uses .NET Aspire to start the supporting containers, apply your user secrets, migrate the database, and run every server service from a single command. - Manual setup: you start the Docker Compose containers, run the helper scripts, and launch each service yourself. Use this if you need an Entity Framework database or another container that Aspire doesn't manage.
Both approaches share the same first steps and use the same dev/secrets.json file, so you can
switch between them.
Before you start: make sure you’ve installed the recommended Tools and Libraries, including:
- Docker Desktop
- Visual Studio 2022
- Powershell
- .NET 10 SDK
- Rust latest stable version - (preferably installed via rustup)
- Your preferred database management tool
Clone the repository
Clone the Bitwarden Server project and navigate to the root of the cloned repository:
git clone https://github.com/bitwarden/server.git
cd server
Configure Git
-
Configure Git to ignore the Prettier revision:
git config blame.ignoreRevsFile .git-blame-ignore-revs -
(Optional) Set up the pre-commit
dotnet formathook:git config --local core.hooksPath .git-hooksFormatting requires a full build, which may be too slow to do every commit. As an alternative, you can run
dotnet formatfrom the command line when convenient (e.g. before requesting a PR review).
Configure user secrets
User secrets
are a method for managing application settings on a per-developer basis. They override the settings
in appSettings.json of each project. Your user secrets file should match the structure of the
appSettings.json file for the settings you intend to override.
We provide a helper script which simplifies setting user secrets for all projects in the server repository.
-
Get a template
secrets.json. We need to get an initial version ofsecrets.json, which you will modify for your own secrets values.Navigate to the
devfolder in your server repo and copy the examplesecrets.jsonfile.cd devcp secrets.json.example secrets.json -
Choose a password for your local SQL Server. You will use it for the SQL Server
saaccount in either setup.cautionYour MSSQL password must comply with the following password complexity guidelines
- It must be at least eight characters long.
- It must contain characters from three of the following four categories:
- Latin uppercase letters (A through Z)
- Latin lowercase letters (a through z)
- Base 10 digits (0 through 9)
- Non-alphanumeric characters such as: exclamation point (!), dollar sign ($), number sign (#), or percent (%).
-
Update
secrets.jsonwith your own values:sqlServer>connectionString: insert your SQL Server password where indicated
installation>idandkey: request a hosting installation Id and Key and insert them herelicenseDirectory: set this to an empty directory, this is where uploaded license files will be stored.
-
Once you have your
secrets.jsoncomplete, run the below command from thedevfolder to add the secrets to each Bitwarden server project.pwsh setup_secrets.ps1
The helper script also supports an optional -clear switch which removes all existing settings
before re-applying them:
pwsh setup_secrets.ps1 -clear
Aspire runs setup_secrets.ps1 -clear every time it starts. If you use Aspire, make your changes in
dev/secrets.json rather than with dotnet user-secrets set on an individual project, because
per-project changes are cleared on the next run.
Run with Aspire
The AppHost project orchestrates the whole local environment. When you start it, Aspire:
- starts SQL Server, Azurite, MailCatcher, and Redis containers
- applies
dev/secrets.jsonto every project by runningsetup_secrets.ps1 -clear - creates and migrates the database by running
migrate.ps1 - bootstraps Azurite by running
setup_azurite.ps1 - starts the Admin, Api, Billing, Events, EventsProcessor, Icons, Identity, Notifications, Scim, and Sso services once their dependencies are ready
The AppHost README contains the full configuration reference.
Set up Aspire
-
Stop any Docker Compose containers from a previous manual setup. Aspire uses the same host ports (for example 1433 for SQL Server and 1080 for MailCatcher) and won't start while they are in use. From the
devfolder, run:docker compose --profile cloud --profile mail --profile idp downnoteAspire creates its own SQL Server data volume. Data in your Docker Compose database is not carried over.
-
Install the PowerShell
Azmodule, which the Azurite setup script needs. This may take a few minutes to complete without providing any user feedback (it may appear frozen).pwsh -Command "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force" -
Trust the ASP.NET Core development certificate, which the Aspire dashboard uses for HTTPS:
dotnet dev-certs https --trust -
From the
devfolder, navigate to theAppHostfolder and store your SQL Server password in the AppHost's user secrets. This must be the same password you put in thesqlServerconnection string insecrets.json.cd ../AppHostdotnet user-secrets set "Database:Password" "<your SQL Server password>"warningKeep passwords and tokens in user secrets. Don't add them to
AppHost/appsettings.Development.json, which is checked in.
Start the server
-
From the
AppHostfolder, run:dotnet runtipIf you have the Aspire CLI installed, you can run
aspire runfrom the root of the repository instead. -
The Aspire dashboard opens in your browser at https://localhost:17271. It shows the status, logs, traces, and environment variables of every resource.
-
Wait for
setup-secretsandrun-db-migrationsto finish. The services wait for both and then start. -
Test that the Identity service is alive by navigating to http://localhost:33656/.well-known/openid-configuration
-
Test that the Api service is alive by navigating to http://localhost:4000/alive
Aspire runs the database migrations and re-applies dev/secrets.json on every start. After you pull
changes or edit secrets.json, restart the AppHost, or restart the setup-secrets or
run-db-migrations resource from the dashboard.
To stop the server, press Ctrl+C in the terminal running the AppHost. The SQL Server, Azurite,
MailCatcher, and Redis containers are persistent and keep running between sessions, so later starts
are faster.
Optional resources
Some resources don't start automatically. Start them from the Aspire dashboard when you need them:
web-frontendruns the web vault from a siblingclientscheckout. You still need to complete the web vault setup, includingnpm ci.idpruns a SAML identity provider for SSO development.
To tunnel the Billing service through ngrok for Stripe webhooks, see Ingress Tunnels.
Change Aspire settings
Override AppHost settings with user secrets from the AppHost folder. For example, to move the Api
service to another port:
dotnet user-secrets set "Services:api:BasePort" "4001"
Common settings include:
| Setting | Purpose |
|---|---|
Services:<name>:BasePort | Port for a service, if the default conflicts with something on your machine |
ClientsPath | Path to the clients repository's apps folder for web-frontend |
SelfHost | Run in a self-hosted configuration |
AdditionalProjects:<name>:Path | Add another project to the orchestration without changing code |
AdditionalProjects:<name>:ReferencedBy:0 | Give an existing service a reference to the additional project |
Restart the AppHost to apply changes. Path settings are relative to the AppHost folder, so use
absolute paths if you work from a Git worktree.
Run manually
If you aren't using Aspire, start the dependencies and services yourself.
Configure Docker
We provide a Docker Compose configuration, which is used during development to provide the required dependencies. This is split up into multiple service profiles to facilitate easy customization.
-
Some Docker settings are configured in the environment file,
dev/.env. Copy the example environment file:cd devcp .env.example .env -
Open
.envwith your preferred editor. -
Set the
MSSQL_PASSWORDvariable to the SQL Server password you chose when you configured user secrets. -
You can change the other variables or use their default values. Save and quit this file.
-
Start the Docker containers.
Using PowerShell, navigate to the cloned server repo location, into the
devfolder and run the docker command below.docker compose --profile mssql --profile mail up -dWhich starts the MSSQL and local mail server containers, which should be suitable for most community contributions.
After you’ve run the docker compose command, you can use the
Docker Dashboard to manage your containers. You should
see your containers running under the bitwardenserver group.
Changing MSSQL_PASSWORD variable after first running docker compose will require a re-creation of
the storage volume.
Warning: this will delete your development database.
To do this, run
docker compose --profile mssql down
docker volume rm bitwardenserver_mssql_dev_data
After that, rerun the docker compose command from Step 5.
Create database
You now have the MSSQL server running in Docker. The next step is to create the database that will be used by the Bitwarden server.
We provide a helper script which will create the development database vault_dev and also run all
migrations.
Navigate to the dev folder in your server repo and perform the following steps:
-
Create the database and run all migrations:
pwsh migrate.ps1 -
You should receive confirmation that the migration scripts have run successfully:
info: Bit.Migrator.DbMigrator[12482444]Migrating database.info: Bit.Migrator.DbMigrator[12482444]Migration successful.
You’ll need to re-run the migration helper script regularly to keep your local development database up-to-date. See MSSQL Database for more information.
Build and run the server
You are now ready to build and run your development server.
-
Open a new terminal window in the root of the repository.
-
Restore the nuget packages required for the Identity service:
cd src/Identitydotnet restore -
Start the Identity service:
dotnet run -
Test that the Identity service is alive by navigating to http://localhost:33656/.well-known/openid-configuration
-
In another terminal window, restore the nuget packages required for the Api service:
cd src/Apidotnet restore -
Start the Api Service:
dotnet run -
Test that the Api service is alive by navigating to http://localhost:4000/alive
Local services
Both setups provide the following local services.
SQL Server
You can connect to the Microsoft SQL Server using your preferred database management tool with the following credentials:
- Server: localhost
- Port: 1433
- Username: sa
- Password: the SQL Server password you chose when you configured user secrets
Mailcatcher
The server uses emails for many user interactions. We provide a pre-configured instance of MailCatcher, which catches any outbound email and prevents it from being sent to real email addresses. You can open its web interface at http://localhost:1080.
Redis
Redis provides distributed caching capabilities. Available caching configurations have specific fallbacks including process-scoped, in-memory caching, or database store for self-hosted configurations.
For details on which features can take advantage of Redis and available configurations, including
connection string setting in secrets.json, see
CACHING.md.
(Optional) Monitor Redis activity using the Redis
CLI. With the manual setup, run this from the dev folder:
docker compose exec redis redis-cli
With Aspire, open the redis resource in the dashboard to find its container, then use
docker exec with that container name.
Azurite
This section applies to Bitwarden developers only.
Azurite is an emulator for Azure Storage API and supports Blob, Queues and Table storage. We use it to minimize the online dependencies required for developing in a cloud environment.
Aspire bootstraps Azurite for you with its azurite-setup resource. With the manual setup, navigate
to the dev directory in your server repo and run the following commands:
-
Install the
Azmodule. This may take a few minutes to complete without providing any user feedback (it may appear frozen).pwsh -Command "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force" -
Run the setup script:
pwsh setup_azurite.ps1
Client connection
Connect a client to your local server by configuring the client’s Api and Identity endpoints. Refer to https://bitwarden.com/help/article/change-client-environment/ and the instructions for each client in the Contributing Documentation.
Now that the client is configured to use your local development server, you can proceed to use the client to create an account and validate your local server changes.
If you cannot connect to the Api or Identity projects, check the terminal output or the Aspire dashboard to confirm the ports they are running on.
We recommend continuing with the Web Vault afterwards, since many administrative operations can only be performed in it.
Debugging
On macOS, you must run dotnet restore for each Project before it can be launched in the a
debugger.
Aspire
Debug the AppHost project from your IDE. Visual Studio and Rider attach the debugger to each
service that the AppHost starts, so breakpoints in Api, Identity, and the other services work
without launching them separately. Rider requires the Aspire plugin.
Visual Studio
To debug:
- On Windows, right-click on each project > click Debug > click Start New Instance
- On macOS, right-click each project > click Start Debugging Project
Rider
Launch the Api project and the Identity project by clicking the "Play" button for each project separately.