{"id":24619309,"url":"https://github.com/dynamic-stall/vaultwarden-docker","last_synced_at":"2026-04-11T06:40:45.453Z","repository":{"id":273918660,"uuid":"911371375","full_name":"dynamic-stall/vaultwarden-docker","owner":"dynamic-stall","description":"This repository contains scripts and configurations for deploying a self-hosted Vaultwarden instance with Cloudflare Tunnel integration, optional Nginx reverse proxy, and Docker Compose.","archived":false,"fork":false,"pushed_at":"2025-02-14T21:22:33.000Z","size":120,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-14T22:26:34.611Z","etag":null,"topics":["bitwarden","cloudflare","docker","docker-compose","nginx","password-manager","secrets-management","secrets-manager","vaultwarden-docker"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dynamic-stall.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-02T21:26:53.000Z","updated_at":"2025-02-14T21:22:36.000Z","dependencies_parsed_at":"2025-01-23T19:19:53.559Z","dependency_job_id":"988372ac-86ef-4c73-a32d-b295c93582cb","html_url":"https://github.com/dynamic-stall/vaultwarden-docker","commit_stats":null,"previous_names":["dynamic-stall/vaultwarden-docker"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dynamic-stall%2Fvaultwarden-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dynamic-stall%2Fvaultwarden-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dynamic-stall%2Fvaultwarden-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dynamic-stall%2Fvaultwarden-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dynamic-stall","download_url":"https://codeload.github.com/dynamic-stall/vaultwarden-docker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244320322,"owners_count":20434090,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitwarden","cloudflare","docker","docker-compose","nginx","password-manager","secrets-management","secrets-manager","vaultwarden-docker"],"created_at":"2025-01-25T00:28:14.350Z","updated_at":"2025-12-31T00:12:33.801Z","avatar_url":"https://github.com/dynamic-stall.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vaultwarden Deployment with Cloudflare Tunnel, Docker Compose\n\n**BLUF**: This repository contains scripts and configurations for deploying a self-hosted Vaultwarden instance with Cloudflare Tunnel integration and (optional) DuckDNS custom subdomain via Docker Compose.\n\n[Vaultwarden](https://hub.docker.com/r/vaultwarden/server) is an alternative implementation of the **Bitwarden** server API, written in Rust, and compatible with [upstream Bitwarden clients⁠](https://bitwarden.com/download/).\n\nBitwarden/Vaultwarden is capable of [password management](https://bitwarden.com/help/password-manager-overview/) via web app, desktop app, browser extension, mobile app, or CLI.\n\n[DuckDNS](https://hub.docker.com/r/linuxserver/duckdns) is a free dynamic DNS service. It allows users to create custom domain names that automatically update to point to a specific IP address, which is particularly useful for home servers, remote access, or hosting services with changing IP addresses. Users can choose a subdomain under duckdns.org and configure it to always point to their current IP address, making it easier to access their network or servers remotely.\n\nIf you have a registered domain, you can further customize your Bitwarden experience by modifying the server URLs (instructions provided further down).\n\n\u003cbr\u003e\n\n## Prerequisites\n\n- Linux/macOS server (or WSL instance if running Windows)\n- [Docker](https://docs.docker.com/engine/install/) installed\n- [Cloudflare account](https://dash.cloudflare.com/sign-up)\n- [DuckDNS account](https://www.duckdns.org/) + registered subdomain and token \\\u003cOR\\\u003e personal registered domain\n- Basic understanding of networking and Docker concepts\n\n\u003cbr\u003e\n\n## Components\n\n1. **Docker Compose Setup:** Deploys Vaultwarden and Cloudflare Tunnel containers\n2. **(Optional) DuckDNS subdomain:** Allows for secure access to your vault instance without relying on an IP address\n3. **Cloudflare Tunnel:** Provides secure access without exposing ports\n4. **Cloudflare Domain:** Add you own registered domain or DuckDNS subdomain to your Cloudflare dashboard to resolve traffic to your Vaultwarden instance behind the Cloudflare Tunnel\n5. **(Optional) Nginx Configuration:** Nginx reverse proxy for SSL termination (useful if deploying as part of a larger infrastructure, i.e., you already have other containers deployed as part of your infrastructure)\n6. **Admin Token Generation:** Securely creates admin dashboard access\n\n\u003cbr\u003e\n\n## Setup Instructions\n\n### 1. Initial Setup\n\n1. Clone this repository:\n```bash\ngit clone https://github.com/dynamic-stall/vaultwarden-docker\ncd vaultwarden-docker\n```\n\n2. Create `.env` from `example` file (_be sure to add your personalized variables_):\n```bash\ncp .env.example .env\n```\n\nRequired environment variables:\n- `VAULT_NAME`: Vaultwarden container and hostname (used to create `DOMAIN_URL`)\n- `VAULT_VOLUME`: Persistent volume for vaultwarden container and automated back-up locations\n- `VAULT_PORT`: Local port for Vaultwarden (default: 8443)\n- `TUNNEL_TOKEN`: Cloudflare Tunnel token (obtained from your personal Cloudflare account)\n- `SMTP_*`: Email configuration variables (default: smtp.gmail.com)\n- `DDNS_DOMAIN`: (_Optional_) Your DuckDNS subdomain (i.e., `example.ddns.com`; used to create `DOMAIN_URL`)\n- `DDNS_TOKEN`: (_Optional_) DuckDNS subdomain token (obtained from your personal DuckDNS account)\n- `DOMAIN_NAME`: Either your DuckDNS subdomain or your personal registered domain name (used to create `DOMAIN_URL`)\n- `ADMIN_TOKEN`: Generated by `admin-token-create.sh`\n\n_(**NOTE:** More on `DOMAIN_NAME` variable setup further down)_\n\n3. (_Optional_) If deploying with Nginx, you will need to either have your own SSL certificates (i.e., `private.key` and `certificate.crt`) or the `deploy-nginx.sh` script will generate them for you.\n\nCopy the `config/nginx/openssl.cnf.example` file and update with your own values:\n```bash\ncd config/nginx\ncp openssl.cnf.example openssl.cnf\n```\n\n**NOTE:** Before running the `deploy-nginx.sh` script, be sure to have the absolute paths to your SSL certificates.\n\n- The following will be auto-configured for you:\n  - SSL private key and self-signed certificate\n  - `vaultwarden.conf` Nginx configuration file\n  - Nginx server configuration\n\n_(**NOTE II:** If skipping Nginx and SSL configuration, simply run the `deploy-standalone.sh` script.)_\n\n\u003cbr\u003e\n\n### 2. Domain Name Configuration\n\n#### Option 1: Using DuckDNS (Free Domain)\n\n1. Visit [DuckDNS](https://www.duckdns.org/) and sign in using your preferred OAuth provider\n\n![image](https://github.com/user-attachments/assets/581f6db4-0e73-45e5-9e38-91747637223c)\n\n2. Create a subdomain (i.e., _vault.duckdns.org_)\n\n3. Copy your token from the DuckDNS dashboard\n\n![image](https://github.com/user-attachments/assets/3953e37b-be5f-49cd-9ce0-ca62063bcef7)\n\n4. Modify these variables to your `.env` file:\n```bash\nDDNS_DOMAIN=\u003cyour-chosen-subdomain\u003e\nDDNS_TOKEN=\u003cyour-duckdns-token\u003e\n```\n* **NOTE:** If you own `example.duckdns.org`, then set `DDNS_DOMAIN=example`.\n\nThe DuckDNS container will automatically:\n- Update your IP address every 5 minutes\n- Maintain your subdomain registration\n- Handle logging and retry logic\n- Keep your subdomain active (domains remain valid as long as they're updated once every 30 days)\n\n* No additional maintenance is required as long as the container remains running.\n\n#### Option 2: Using Your Own Domain\n\nIf you have a registered domain, you can skip the DuckDNS setup and modify the `vw-compose.yml` file:\n\n1. Remove the DuckDNS service block:\n```yaml\n  # Remove this entire block\n  duckdns:\n    image: linuxserver/duckdns\n    # ...\n```\n\n2. Update the `DOMAIN_NAME` variable in `.env`, either commenting out or deleting the first `DOMAIN_NAME` variable referencing the DuckDNS subdomain:\n\nGet rid of:\n```bash\nDOMAIN_NAME=\"${DDNS_DOMAIN}.duckdns.org\"\n```\n\n...and modify the following variable:\n```bash\n# Remove the \"#\" and enter your personal registered domain\nDOMAIN_NAME=\"example.com\"\n```\n\n**NOTE:** Regardless of whether you use DuckDNS or bring your own domain, the final `DOMAIN_URL` variable will be correctly formatted for use in later configurations:\n```bash\nDOMAIN_URL=\"https://${VAULT_NAME}.${DOMAIN_NAME}\"\n```\n\n\u003cbr\u003e\n\n\n### 3. Cloudflare Domain Zone Setup\n\n⚠️ **Skip this step if using DuckDNS** ⚠️\n\n1. Login to your [Cloudflare account](https://dash.cloudflare.com/)\n\n2. Navigate to **Account Home** → **Domains**\n\n3. Select the blue `+ Add a domain` button to enter your domain name: either your full DuckDNS subdomain or your personal registered domain. Leave default settings as they are.\n\n![image](https://github.com/user-attachments/assets/c29ab84e-5bea-4147-8feb-6c7af702bcf8)\n\n4. In your DNS dashboard, you should see four records: two _A records_ (containing your current public IP address) and two _MX records_ (ignore these...).\n\n5. Save this page for later; we'll come back to it for the next step...\n\n\u003cbr\u003e\n\n### 4. Cloudflare Tunnel Setup\n\n1. Login to your [Cloudflare Zero Trust](https://one.dash.cloudflare.com/) dashboard\n\n2. Navigate to **Networks** → **Tunnels**\n\n3. Create a new tunnel:\n   - Click _Create a tunnel_.\n   - Select _Cloudflared_ on the left.\n   - Name your tunnel (the name is only important to you). Click _Save_ on the bottom-right.\n   - Under the \"Choose your environment\" options, select _Docker_.\n   ![image](https://github.com/user-attachments/assets/28f33bd6-dfdf-48ea-bcf0-0393b9a49143)\n\n   - Under \"Install and run a connector\", copy the `docker run` command provided. Paste this command in a secure note-taking environment to see the full **token**.\n   - Copy this token and paste it into your `.env` file, updating the `TUNNEL_TOKEN` variable.\n   ```bash\n   # Cloudflare Configuration\n   TUNNEL_NAME=\"${VAULT_NAME}-tunnel\"   # NOTE: this variable is for the Docker container name\n   TUNNEL_TOKEN=\"\u003cyour-cloudflare-tunnel-token\u003e\"\n   ```\n   - Back to your Cloudflare dashboard, click _Save_ on the bottom-right.\n\n4. Configure the tunnel's _Public Hostname_:\n   - **Subdomain:** Ensure this value matches your chosen `VAULT_NAME` value in your `.env` file\n   - **Domain:** Either your personal registered domain name (i.e., `example.com`) or your DuckDNS subdomain (i.e., `example.duckdns.org`)\n   - **Path:** _(Leave this field blank)_\n   - **Type:** HTTP\n   - **URL:** localhost:8443  (or your chosen `VAULT_PORT` value, if you changed it)\n  \n  * **NOTE:** If you are using a DuckDNS subdomain, you will not be able to add your subdomain to your Cloudflare dashboard for longer than 28 days (without _NS record_ verification, which isn't possible with DuckDNS). You can still enter a **\"custom domain name\"** in the _Public Hostname_ section. **Be sure to hit the _ENTER_ key when populating this value so it doesn't disappear**. A _warning_ for custom domains will appear. It means nothing configuration-wise, but be mindful:\n\n  ![image](https://github.com/user-attachments/assets/36a60b6a-7276-4bb5-ae1b-e98d0d9b2b4f)\n\n5. (Optional) Configure the tunnel's _Private Network_:\n    - Cloudflare offers an extensive array of features available at free-tier. If you plan on utilizing WARP with your Zero Trust account (which I recommend), you can implement more robust [access policies](https://developers.cloudflare.com/cloudflare-one/policies/access/) as well as custom [private networks/IPs](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/) to access remote resources without requiring a public domain\n    - For the sake of simplicity, these instructions are beyond the scope of this GitHub project, but I suggest you check them out on your own, especially Cloudflare Access -- which can secure access to your self-hosted applications and more via various authentication and posture-assessment methods (i.e., Google OIDC for single sign-on with your Gmail account, restricting access to resources based on public IP or country, and much, much more).\n\n6. Click _Save tunnel_ in the bottom-right.\n\n\u003cbr\u003e\n\n### 5. Deployment\n\nRun one of the main deployment scripts:\n\nIf configuring SSL and Nginx, run:\n```bash\n./deploy-nginx.sh\n```\n\nThis will:\n1. Generate admin token\n2. Create SSL certificates\n3. Configure Nginx\n4. Launch Docker containers\n5. (Optionally,) configure Bitwarden CLI\n\n\u003cbr\u003e\n\nIf deploying without nginx, run:\n```bash\n./deploy-standalone.sh\n```\n\nThis will:\n1. Generate admin token\n2. Launch Docker containers\n3. (Optionally,) configure Bitwarden CLI\n\n\u003cbr\u003e\n\n## Accessing Your Vault\n\n### Configuring Clients\n\n#### Using the Web Vault:\n\n1. Navigate to the admin panel of your Vaultwarden instance (i.e., `vault.example.com/admin`)\n\n2. Use the Admin token you set to authenticate\n\n3. From the admin page, you can create users for general access and password management (access the Web Vault at, i.e., `vault.example.com/#/login`)\n\n#### Using the Desktop App:\n\n1. Open Bitwarden desktop app\n\n2. Expand the _\"Accessing\"_ dropdown menu below your login email\n\n![image](https://github.com/user-attachments/assets/05dac953-5f70-42ff-a83e-6fd63516d5d3)\n\n3. Select _\"Self-hosted\"_ and enter your server URL (ex: ```https://vault.example.com```)\n\n![image](https://github.com/user-attachments/assets/e1fdc52d-3eb4-4459-8629-8d010f399406)\n\n4. Use your created user's **master password** to login\n\n\u003cbr\u003e\n\n### Programmatic Access\n\n#### Using the CLI:\n\nThe main deployment scripts will (optionally) build a _Docker container_ which will allow you to run the Bitwarden CLI -- while also pre-configuring it to use your custom domain.\n\n**NOTE:** If you would prefer a _host installation_ of the CLI, you can use the `scripts/cli-host-config.sh` script instead of the Docker deployment.\n\nReference the below for manual configuration of the CLI:\n```bash\n# Set server URL\nbw config server https://vault.example.com\n\n# Configure individual endpoints\nbw config server \\\n  --api https://vault.example.com/api \\\n  --identity https://vault.example.com/identity \\\n  --web-vault https://vault.example.com \\\n  --icons https://vault.example.com/icons \\\n  --notifications https://vault.example.com/notifications\n```\n\n* **NOTE:** If all of your endpoints use the same domain name, you only need to run the `bw config server` command.\n\n\u003cbr\u003e\n\n## Cloudflare Origin CA Certificate\n\nIf you would like to register your SSL certificate with Cloudflare (or another certificate authority) and obtain an **Origin CA certificate**, you will first need to generate a certificate signing request (CSR). Use the command below (replace with your private key name, if you brought your own):\n```bash\nopenssl req -new -key private.key -out request.csr -config config/nginx/openssl.cnf\n```\n\nAfter you have your CSR, use it to obtain the Origin CA certificate by following the [official documentation](https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/). Once you have registered your SSL certificate with Cloudflare and configured your setup to use them, you can discard the self-signed certificate, `certificate.crt`, **IF** it is no longer being used in your deployment...\n\n\u003cbr\u003e\n\n## File Structure\n\n```\n.\n├── config/\n│   ├── docker/\n│   │   ├── cli.Dockerfile\n|   |   └── vw-compose.yml\n│   └── nginx/\n|       ├── vaultwarden.conf.template\n│       └── openssl.cnf.example\n├── deploy-nginx.sh\n├── deploy-standalone.sh\n├── .env.example\n├── .gitignore\n├── README.md  # this file\n└── scripts/\n    ├── admin-token-create.sh\n    ├── bw-cli-config.sh\n    ├── cli-config-host.sh\n    ├── docker-custom-net.sh\n    ├── nginx-config.sh\n    └── ssl-cert-create.sh\n```\n\n\u003cbr\u003e\n\n## Security Considerations\n\n- Always use strong passwords\n- Keep your system updated\n- Regularly backup the `/opt/bitwarden` directory (automated by default)\n- Monitor logs for suspicious activity\n- Use 2FA where possible\n\n\u003cbr\u003e\n\n## Maintenance\n\n### Backup\n\nBack-ups are AUTOMATED via the `vw_backup` container as part of the `vw-compose.yml` file. Default is set to daily at 5 AM.\n\nFor manual back-ups, you can back up the `/opt/vaultwarden` directory:\n```bash\ntar -czf backup.tar.gz /opt/vaultwarden\n```\n\n### Updates\n\nTo update Vaultwarden:\n```bash\ndocker compose pull\ndocker compose up -d\n```\n\n\u003cbr\u003e\n\n## Troubleshooting\n\n1. Check container logs:\n```bash\ndocker logs \u003cvault_container_name\u003e\ndocker logs \u003ctunnel_container_name\u003e\n```\n\n2. Verify Nginx configuration:\n```bash\nnginx -t\n```\n\n3. Check Cloudflare tunnel status:\n```bash\ndocker logs \u003ctunnel_container_name\u003e\n```\n\n\u003cbr\u003e\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynamic-stall%2Fvaultwarden-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdynamic-stall%2Fvaultwarden-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynamic-stall%2Fvaultwarden-docker/lists"}