This page covers the two deployment paths. Pick the one that fits your workflow and infrastructure.
-
Clone the repository:
git clone https://github.com/your-username/warden-worker.git cd warden-worker -
Create a D1 Database:
wrangler d1 create warden-db
-
(Optional) Enable R2 Bucket for Attachments:
Warden uses KV for attachments storage by default. If you want to use R2 as storage backend:
# Create the production bucket wrangler r2 bucket create warden-attachmentsThen enable the R2 binding in
wrangler.tomlby uncommenting the R2 bucket configuration sections.Note: Attachments are optional. If you remove both KV and R2 bindings, attachment functionality will be disabled but all other features will work normally.
-
Configure your Database ID:
When you create a D1 database, Wrangler will output the
database_id. To avoid committing this secret to your repository, this project uses an environment variable to configure the database ID.You have two options:
Option 1: (Recommended) Use a
.envfile:Create a file named
.envin the root of the project and add the following line, replacing the placeholder with your actualdatabase_id:D1_DATABASE_ID="your-database-id-goes-here"Make sure to add the
.envfile to your.gitignorefile to prevent it from being committed to git.Option 2: Set an environment variable in your shell:
You can set the environment variable in your shell before deploying:
export D1_DATABASE_ID="your-database-id-goes-here" wrangler deploy
-
Download the frontend (Web Vault):
# Default pinned version (override by exporting BW_WEB_VERSION) BW_WEB_VERSION="${BW_WEB_VERSION:-v2025.12.0}" if [ "${BW_WEB_VERSION}" = "latest" ]; then BW_WEB_VERSION="$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest | jq -r .tag_name)" fi # Download and extract wget "https://github.com/dani-garcia/bw_web_builds/releases/download/${BW_WEB_VERSION}/bw_web_${BW_WEB_VERSION}.tar.gz" tar -xzf "bw_web_${BW_WEB_VERSION}.tar.gz" -C public/ rm "bw_web_${BW_WEB_VERSION}.tar.gz" # Remove large source maps to satisfy Cloudflare static asset per-file limits find public/web-vault -type f -name '*.map' -delete
Optional: Apply lightweight UI overrides to generate
public/web-vault/css/vaultwarden.css:bash scripts/apply-web-vault-overrides.sh public/web-vault
-
Set up database and deploy the worker:
# Only run once before first deployment wrangler d1 execute vault1 --file sql/schema.sql --remote # For migrations wrangler d1 migrations apply vault1 --remote # (Optional) Seed global equivalent domains into D1 # This downloads Vaultwarden's global_domains.json by default. bash scripts/seed-global-domains.sh --db vault1 --remote wrangler deploy
This will deploy the worker and set up the necessary database tables.
-
Set environment variables as
Secret
ALLOWED_EMAILSyour-email@example.com (supports glob patterns like*@example.com)JWT_SECRETa long random stringJWT_REFRESH_SECRETa long random string
-
Configure your Bitwarden client:
In your Bitwarden client, go to the self-hosted login screen and enter the URL of your deployed worker.
By default, the
*.workers.devdomain is disabled, since it may throw 1101 error. It's highly recommended to use a custom domain instead; see Configure Custom Domain for more details.
This project includes GitHub Actions workflows for automated deployment. This is the recommended approach for production environments as it ensures consistent builds and deployments.
Add the following secrets to your GitHub repository (Settings > Secrets and variables > Actions):
| Secret | Required | Description |
|---|---|---|
CLOUDFLARE_API_TOKEN |
yes | Your Cloudflare API token |
CLOUDFLARE_ACCOUNT_ID |
yes | Your Cloudflare account ID |
D1_DATABASE_ID |
yes | Your production D1 database ID |
D1_DATABASE_ID_DEV |
no | Dev D1 database ID (required only if you use the Deploy Dev workflow on the dev branch) |
- Log in to the Cloudflare Dashboard
- Select your account
- Your Account ID is displayed in the right sidebar of the Overview page, or in the URL:
https://dash.cloudflare.com/<account-id>
The CLOUDFLARE_API_TOKEN requires the following permissions:
- Edit Cloudflare Workers: Required for deploying the Worker
- Edit D1: Required for database migrations and backups
- Edit KV: Required for attachments storage (if using KV)
- Visit https://dash.cloudflare.com/profile/api-tokens
- Click Create Token
- Use the Edit Cloudflare Workers template
- Add Account → D1 under
Permissions - Select
Account ResourcesandZone Resources - Click Continue to Summary and then Create Token
You can pin/override the bundled Web Vault (bw_web_builds) version via GitHub Actions Variables:
| Variable | Applies to | Default | Example | Notes |
|---|---|---|---|---|
BW_WEB_VERSION |
prod (main/uat/release*) |
v2025.12.0 |
v2025.12.0 |
Set to latest to follow upstream latest release |
BW_WEB_VERSION_DEV |
dev (dev) |
v2025.12.0 |
v2025.12.0 |
Set to latest to follow upstream latest release |
Bitwarden clients use globalEquivalentDomains for URI matching across well-known domain groups.
To avoid bundling a large JSON file into the Worker, the dataset can be stored in D1 and seeded during deploy.
| Variable | Applies to | Default | Example | Notes |
|---|---|---|---|---|
SEED_GLOBAL_DOMAINS |
prod + dev | true |
false |
Set to false to skip seeding (API returns empty list) |
GLOBAL_DOMAINS_URL |
prod | (empty) | raw GitHub URL | Optional: pin a specific Vaultwarden tag/commit for reproducible deploys |
GLOBAL_DOMAINS_URL_DEV |
dev | (empty) | raw GitHub URL | Same as prod, but for dev workflow |
If you skip seeding, /api/settings/domains and /api/sync will return globalEquivalentDomains: [].
-
Fork or clone the repository to your GitHub account
-
Configure the required secrets in your repository settings
-
(Optional) Enable R2 bucket for attachments:
Warden uses KV for attachments storage by default. If you want to use R2 as storage backend:
-
Create R2 buckets in Cloudflare Dashboard before running the action:
- Go to Storage & databases → R2 → Create bucket
- Create a production bucket (e.g.,
warden-attachments)
-
Add the bucket names as GitHub Action secrets:
R2_NAME→ production bucket name
The workflows will auto-append the
ATTACHMENTS_BUCKETbinding intowrangler.tomlwhen these secrets are present - no manual binding in the Cloudflare console is required. -
-
Manually trigger the
BuildAction from the GitHub Actions tab in your repository -
Monitor the deployment in the Actions tab of your repository
-
Set environment variables as
secretin the Cloudflare dashboard (following the command line deployment steps):ALLOWED_EMAILSyour-email@example.com (supports glob patterns like*@example.com, comma separated)JWT_SECRETa long random stringJWT_REFRESH_SECRETa long random string
Important
The server can't work without these three environment variables. If you forget to set them, the server will crash.
If you want to show a 'Create account' button in frontend, you can add DISABLE_USER_REGISTRATION as text and set it to false. Check Environment Variables for more details.
By default, the *.workers.dev domain is disabled, since it may throw 1101 error. It's highly recommended to use a custom domain instead; see Configure Custom Domain for more details.