From 1018dd8c9e1e8bd054b27e2c20a641106aee1132 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 05:19:25 +0000 Subject: [PATCH] vaultwarden: require/enforce an http(s):// scheme on DOMAIN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Confirmed live: a bare hostname in DOMAIN= (typing "vault.example.com" instead of "https://vault.example.com" at the install prompt — easy to do despite the example text showing the scheme) crash-loops the container with no clear startup error, and re-running the installer doesn't fix an already-written .env since "update" mode deliberately never touches it. Two changes, mirroring how the existing SMTP half-state bug is already handled in this file: - Normalize VW_DOMAIN at prompt time — missing scheme gets https:// prefixed automatically instead of writing it verbatim. - New _vaultwarden_fix_domain_scheme() self-heal, called at the same two sites as _vaultwarden_fix_smtp_halfstate() (the "update" path and the fresh-install "start now" path), so a box that already has a scheme-less DOMAIN self-heals on its next start instead of staying stuck. Verified the self-heal function in isolation: vault.mydomain.com -> https://vault.mydomain.com. --- services/vaultwarden.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/services/vaultwarden.sh b/services/vaultwarden.sh index cf2c66d..207e2b2 100644 --- a/services/vaultwarden.sh +++ b/services/vaultwarden.sh @@ -225,6 +225,22 @@ register_service vaultwarden utilities "Bitwarden-compatible password manager (V # live. Called right before every `docker compose up` this file does, not # just at install time, so it self-heals regardless of how the box got into # this state. +# Vaultwarden requires DOMAIN to include an http(s):// scheme — a bare +# hostname crash-loops the container. Called at the same two sites as +# _vaultwarden_fix_smtp_halfstate() below, so a box whose .env got a +# scheme-less DOMAIN written before this fix existed (or hand-edited since) +# self-heals on its next start instead of staying stuck forever. +_vaultwarden_fix_domain_scheme() { + local env_file="$1" + [ -f "$env_file" ] || return 0 + local domain + domain="$(grep '^DOMAIN=' "$env_file" 2>/dev/null | cut -d= -f2-)" + if [ -n "$domain" ] && [[ "$domain" != http://* && "$domain" != https://* ]]; then + log_warning "DOMAIN in $env_file is missing an http(s):// scheme ('$domain') — Vaultwarden requires one to start. Adding https:// automatically." + sed -i "s#^DOMAIN=.*#DOMAIN=https://${domain}#" "$env_file" + fi +} + _vaultwarden_fix_smtp_halfstate() { local env_file="$1" [ -f "$env_file" ] || return 0 @@ -298,6 +314,7 @@ install_vaultwarden() { case "$MODE" in update) log_info "Refreshing the Vaultwarden image only — existing config, port, and Caddy setup are left as-is." + _vaultwarden_fix_domain_scheme "$VW_DIR/.env" _vaultwarden_fix_smtp_halfstate "$VW_DIR/.env" ( cd "$VW_DIR" && docker compose pull && docker compose up -d ) \ && log_success "Vaultwarden image refreshed" \ @@ -336,6 +353,15 @@ install_vaultwarden() { local DEFAULT_DOMAIN="https://vault${INSTANCE_SUFFIX:+-$INSTANCE_SUFFIX}.${SITE_DOMAIN:-example.com}" prompt_text "Vaultwarden public URL (e.g. https://vault.example.com):" "$DEFAULT_DOMAIN" VW_DOMAIN [ -z "$VW_DOMAIN" ] && VW_DOMAIN="$DEFAULT_DOMAIN" + # Vaultwarden requires DOMAIN to include a URL scheme — a bare hostname + # (typing "vault.example.com" instead of "https://vault.example.com" at + # the prompt above, easy to do despite the example text showing the + # scheme) crash-loops the container with no clear startup error. + # Confirmed live. Normalize rather than trust free-form input. + if [[ "$VW_DOMAIN" != http://* && "$VW_DOMAIN" != https://* ]]; then + log_warning "No http(s):// scheme on '$VW_DOMAIN' — Vaultwarden requires one. Prefixing with https://." + VW_DOMAIN="https://$VW_DOMAIN" + fi echo "" echo " SMTP (optional) — for password-reset and invite emails." @@ -487,6 +513,7 @@ MD local START_VW="" prompt_yn "Start Vaultwarden${INSTANCE_SUFFIX:+ ($INSTANCE_SUFFIX)} now? (y/n):" "y" START_VW if [ "$START_VW" = "y" ] || [ "$START_VW" = "Y" ]; then + _vaultwarden_fix_domain_scheme "$VW_DIR/.env" _vaultwarden_fix_smtp_halfstate "$VW_DIR/.env" docker compose up -d \ && log_success "Vaultwarden${INSTANCE_SUFFIX:+ ($INSTANCE_SUFFIX)} started" \