feat: add vaultwarden-with-backup template

Adds a new Vaultwarden template with automated backups to Cloudflare R2 storage.

Services:
- vaultwarden/server:1.34.3 - password manager
- alpine:3.20 - configurator that generates rclone.conf for R2
- ttionya/vaultwarden-backup:1.26.2 - scheduled backups

Includes configurable SMTP, timezone, admin token, and R2 credentials.
This commit is contained in:
CarlosHugoRodriguezC
2026-02-23 15:55:28 -06:00
parent 38e417b194
commit 711cd3482d
4 changed files with 158 additions and 18 deletions
@@ -0,0 +1,69 @@
services:
vaultwarden:
image: vaultwarden/server:1.34.3
restart: always
environment:
- DOMAIN=${DOMAIN}
- TZ=${TZ}
- ADMIN_TOKEN=${ADMIN_TOKEN}
- WEBSOCKET_ENABLED=${WEBSOCKET_ENABLED}
- SIGNUPS_ALLOWED=${SIGNUPS_ALLOWED}
- INVITATIONS_ALLOWED=${INVITATIONS_ALLOWED}
- SHOW_PASSWORD_HINT=${SHOW_PASSWORD_HINT}
- SMTP_HOST=${SMTP_HOST}
- SMTP_FROM=${SMTP_FROM}
- SMTP_PORT=${SMTP_PORT}
- SMTP_SECURITY=${SMTP_SECURITY}
- SMTP_USERNAME=${SMTP_USERNAME}
- SMTP_PASSWORD=${SMTP_PASSWORD}
volumes:
- vaultwarden:/data
expose:
- 80
configurator:
image: alpine:3.20
restart: "no"
entrypoint: ["/bin/sh", "-c"]
command:
- |
echo "Generating Rclone config for Cloudflare R2..."
cat <<EOF > /config/rclone.conf
[r2backup]
type = s3
provider = Cloudflare
access_key_id = ${R2_ACCESS_KEY_ID}
secret_access_key = ${R2_SECRET_ACCESS_KEY}
endpoint = https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com
acl = private
no_check_bucket = true
EOF
echo "Configuration generated successfully."
volumes:
- vaultwarden-rclone-config:/config
backup:
image: ttionya/vaultwarden-backup:1.26.2
restart: always
depends_on:
configurator:
condition: service_completed_successfully
environment:
- TIMEZONE=${TZ}
- CRON=${BACKUP_CRON}
- BACKUP_KEEP_DAYS=${BACKUP_KEEP_DAYS}
- DATA_DIR=/data
- ZIP_PASSWORD=${ZIP_PASSWORD}
- RCLONE_CONFIG=/config/rclone.conf
- RCLONE_REMOTE_NAME=r2backup
- RCLONE_REMOTE_DIR=${R2_BUCKET_NAME}/backups
- RCLONE_GLOBAL_FLAG=--s3-no-check-bucket
volumes:
- vaultwarden:/data
- vaultwarden-backups:/backup
- vaultwarden-rclone-config:/config
volumes:
vaultwarden:
vaultwarden-backups:
vaultwarden-rclone-config:
@@ -0,0 +1,34 @@
[variables]
main_domain = "${domain}"
admin_token = "${password:48}"
zip_password = "${password:32}"
[config]
mounts = []
[[config.domains]]
serviceName = "vaultwarden"
port = 80
host = "${main_domain}"
[config.env]
DOMAIN = "https://${main_domain}"
TZ = "UTC"
ADMIN_TOKEN = "${admin_token}"
WEBSOCKET_ENABLED = "true"
SIGNUPS_ALLOWED = "false"
INVITATIONS_ALLOWED = "true"
SHOW_PASSWORD_HINT = "false"
SMTP_HOST = ""
SMTP_FROM = ""
SMTP_PORT = "587"
SMTP_SECURITY = "starttls"
SMTP_USERNAME = ""
SMTP_PASSWORD = ""
R2_ACCESS_KEY_ID = ""
R2_SECRET_ACCESS_KEY = ""
R2_ACCOUNT_ID = ""
R2_BUCKET_NAME = ""
BACKUP_CRON = "0 5 * * *"
BACKUP_KEEP_DAYS = "30"
ZIP_PASSWORD = "${zip_password}"
@@ -0,0 +1,19 @@
<svg width="276" height="280" viewBox="0 0 276 280" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#a)">
<mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="-21" y="-21" width="322" height="322">
<path d="M-18.7-18.7h317.883v317.883H-18.699z" fill="#fff" stroke="#fff" stroke-width="2.671"/>
<path d="M146.92 33.39a6.678 6.678 0 1 1-13.357 0 6.678 6.678 0 0 1 13.357 0Zm97.007 80.184a6.678 6.678 0 1 1-4.127-12.702 6.678 6.678 0 1 1 4.127 12.702Zm-46.282 117.038a6.678 6.678 0 1 1 10.805-7.851 6.678 6.678 0 1 1-10.805 7.851Zm-125.612-7.851a6.678 6.678 0 1 1 10.806 7.851 6.678 6.678 0 0 1-10.806-7.851ZM40.684 100.872a6.678 6.678 0 1 1-4.127 12.702 6.678 6.678 0 1 1 4.127-12.702Z" fill="#000" stroke="#fff" stroke-width="2.671"/>
</mask>
<g mask="url(#b)" stroke="#fff">
<path d="m56.974 49.917 70.778 198.18h24.981l70.778-198.18H197.42l-44.687 127.124q-4.441 12.213-7.495 23.038-3.052 10.546-4.996 20.262-1.942-9.715-4.996-20.54-3.052-10.825-7.494-23.315L83.342 49.917z" fill="#fff" stroke-width="12.052"/>
<path d="M140.242 255.107c-63.438 0-114.865-51.427-114.865-114.865S76.804 25.377 140.242 25.377c63.439 0 114.865 51.427 114.865 114.865s-51.426 114.865-114.865 114.865Z" stroke-width="24.042"/>
<path d="M17.363 132.228v16.028l-13.356-8.014zm.798 24.127 3.127 15.719-14.663-5.254zm5.489 23.507 6.133 14.808-15.407-2.293zm9.97 21.985 8.905 13.326-15.558.757zm14.067 19.617 11.333 11.333-15.111 3.778zM65.31 237.96l13.327 8.904-14.084 6.654zm20.505 12.741 14.807 6.133-12.515 9.273zm22.595 8.496 15.72 3.126-10.466 11.537zm23.819 3.924h16.027l-8.014 13.357zm24.125-.798 15.72-3.126-5.254 14.663zm23.508-5.489 14.808-6.133-2.293 15.406zm21.985-9.969 13.326-8.905.757 15.558zm19.617-14.068 11.333-11.333 3.778 15.111zm16.496-17.624 8.904-13.326 6.654 14.083zm12.741-20.503 6.134-14.808 9.273 12.515zm8.495-22.596 3.127-15.719 11.536 10.465zm3.925-23.818v-16.028l13.357 8.014zm-.798-24.127-3.127-15.719 14.664 5.254zm-5.489-23.507L250.7 85.814l15.407 2.293zm-9.97-21.985-8.904-13.326 15.557-.757zM232.797 59.02l-11.333-11.333 15.111-3.778zm-17.624-16.496-13.327-8.904 14.084-6.654zM194.67 29.783l-14.808-6.133 12.515-9.273zm-22.596-8.495-15.72-3.127L166.82 6.624zm-23.818-3.925h-16.028l8.014-13.356zm-24.126.797-15.72 3.128 5.254-14.664zm-23.508 5.49-14.808 6.133 2.293-15.406zm-21.984 9.97L65.31 42.524l-.757-15.558zM59.02 47.687 47.688 59.02 43.91 43.91zM42.524 65.31 33.62 78.638l-6.653-14.083zM29.783 85.814l-6.133 14.808-9.273-12.515zm-8.496 22.596-3.127 15.719-11.536-10.465z" fill="#fff" stroke-width="8.014" stroke-linejoin="round"/>
<path d="M121.543 28.048h37.398l-18.699 18.7zm-93.781 95.308 11.556-35.568 12.006 23.562zM89.425 242l-30.256-21.982 26.119-4.137zm131.891-21.982L191.061 242l4.136-26.119zm19.851-132.23 11.557 35.568-23.562-12.006z" fill="#fff" stroke-width="16.028" stroke-linejoin="round"/>
</g>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h276v280H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

+36 -18
View File
@@ -5858,6 +5858,24 @@
"open-source"
]
},
{
"id": "strapi",
"name": "Strapi",
"version": "v5.33.0",
"description": "Open-source headless CMS to build powerful APIs with built-in content management.",
"logo": "strapi.svg",
"links": {
"github": "https://github.com/strapi/strapi",
"discord": "https://discord.com/invite/strapi",
"docs": "https://docs.strapi.io",
"website": "https://strapi.io"
},
"tags": [
"headless",
"cms",
"content-management"
]
},
{
"id": "streamflow",
"name": "StreamFlow",
@@ -5877,24 +5895,6 @@
"media"
]
},
{
"id": "strapi",
"name": "Strapi",
"version": "v5.33.0",
"description": "Open-source headless CMS to build powerful APIs with built-in content management.",
"logo": "strapi.svg",
"links": {
"github": "https://github.com/strapi/strapi",
"discord": "https://discord.com/invite/strapi",
"docs": "https://docs.strapi.io",
"website": "https://strapi.io"
},
"tags": [
"headless",
"cms",
"content-management"
]
},
{
"id": "supabase",
"name": "SupaBase",
@@ -6351,6 +6351,24 @@
"open-source"
]
},
{
"id": "vaultwarden-with-backup",
"name": "Vaultwarden with R2 Backup",
"version": "1.34.3",
"description": "Vaultwarden password manager with automated backups to Cloudflare R2 storage.",
"logo": "vaultwarden.svg",
"links": {
"github": "https://github.com/dani-garcia/vaultwarden",
"website": "",
"docs": "https://github.com/dani-garcia/vaultwarden/wiki"
},
"tags": [
"password-manager",
"security",
"backup",
"open-source"
]
},
{
"id": "vikunja",
"name": "Vikunja",