Vaultwardenにはインポート/エクスポート機能があるので基本的に移行時には標準機能を利用し、念の為のバックアップとします。ただデータの取り扱いには十分注意を。
目次
スクリプトの主な機能
バックアップ (backup)
- コンテナを一時停止してからアーカイブを作成(データ整合性確保)
data/とdocker-compose.ymlを一緒にバックアップ- SHA256チェックサムファイルも自動生成
- バックアップ後にコンテナを自動再起動
- 7日以上前のバックアップは削除
復元 (restore)
- ファイル指定省略時は最新バックアップを自動選択
- SHA256チェックサムで破損検証
- 復元前に現在の
data/をdata_before_restore_日時/に退避(ロールバック可能) - 確認プロンプトあり(誤操作防止)
一覧 (list) / クリーンアップ (clean)
- バックアップファイルのサイズ・日時を一覧表示
- 指定日数より古いファイルを対話的に削除
スクリプトファイル:/opt/lxd-data/script/vaultwarden
バックアップ保存先:/opt/lxd-data/vaultwarden
コンテナ内で実行
バックアップスクリプト
sudo mkdir -p /opt/lxd-data/script/vaultwarden
cd /opt/lxd-data/script/vaultwarden
sudo nano vaultwarden-backup.sh
# 下記スクリプトを貼り付け
# 実行権限を付与
chmod +x vaultwarden-backup.sh
#!/bin/bash
set -euo pipefail
# =============================================================
# Vaultwarden バックアップ / 復元スクリプト
#
# 使い方:
# バックアップ : sudo bash vaultwarden-backup.sh backup
# 復元 : sudo bash vaultwarden-backup.sh restore [バックアップファイルパス]
# 一覧表示 : sudo bash vaultwarden-backup.sh list
#
# バックアップ保存先: /opt/lxd-data/vaultwarden/
# バックアップ対象 : /opt/docker/vaultwarden/data/
# =============================================================
VAULTWARDEN_DIR="/opt/docker/vaultwarden"
BACKUP_DIR="/opt/lxd-data/vaultwarden"
CONTAINER_NAME="vaultwarden"
KEEP_DAYS=7 # バックアップの保持日数
# ── カラー出力 ────────────────────────────────────
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
# ── ヘルパー関数 ──────────────────────────────────
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
section() { echo -e "\n${CYAN}==> $*${NC}"; }
print_banner() {
echo ""
echo "════════════════════════════════════════"
echo " Vaultwarden バックアップ管理スクリプト"
echo "════════════════════════════════════════"
echo ""
}
usage() {
print_banner
echo "使い方:"
echo " $0 backup # バックアップを作成"
echo " $0 restore [ファイル] # バックアップから復元"
echo " ファイル省略時は最新を使用"
echo " $0 list # バックアップ一覧を表示"
echo " $0 clean # 古いバックアップを削除 (${KEEP_DAYS}日以上)"
echo ""
echo "保存先: ${BACKUP_DIR}/"
echo ""
}
check_root() {
if [ "$(id -u)" -ne 0 ]; then
error "このスクリプトはrootまたはsudoで実行してください"
exit 1
fi
}
check_vaultwarden_dir() {
if [ ! -d "${VAULTWARDEN_DIR}/data" ]; then
error "Vaultwardenデータディレクトリが見つかりません: ${VAULTWARDEN_DIR}/data"
exit 1
fi
}
# ── バックアップ関数 ──────────────────────────────
do_backup() {
print_banner
check_root
check_vaultwarden_dir
local TIMESTAMP
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
local BACKUP_FILE="${BACKUP_DIR}/vaultwarden_${TIMESTAMP}.tar.gz"
section "[1/4] バックアップディレクトリを準備..."
mkdir -p "${BACKUP_DIR}"
info "保存先: ${BACKUP_DIR}"
section "[2/4] Vaultwardenコンテナを一時停止..."
if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker stop "${CONTAINER_NAME}"
info "コンテナを停止しました"
local CONTAINER_WAS_RUNNING=true
else
warn "コンテナは既に停止しています"
local CONTAINER_WAS_RUNNING=false
fi
section "[3/4] データをアーカイブ..."
# docker-compose.yml も含めてバックアップ
tar -czf "${BACKUP_FILE}" \
-C "${VAULTWARDEN_DIR}" \
data \
docker-compose.yml 2>/dev/null || {
# docker-compose.yml が無い場合は data のみ
tar -czf "${BACKUP_FILE}" \
-C "${VAULTWARDEN_DIR}" \
data
}
local BACKUP_SIZE
BACKUP_SIZE=$(du -sh "${BACKUP_FILE}" | cut -f1)
info "アーカイブ作成完了: ${BACKUP_FILE} (${BACKUP_SIZE})"
# チェックサム生成
sha256sum "${BACKUP_FILE}" > "${BACKUP_FILE}.sha256"
info "チェックサム: ${BACKUP_FILE}.sha256"
section "[4/4] Vaultwardenコンテナを再起動..."
if [ "${CONTAINER_WAS_RUNNING}" = true ]; then
cd "${VAULTWARDEN_DIR}"
docker compose up -d
info "コンテナを再起動しました"
else
warn "コンテナは停止したままです (元々停止していたため)"
fi
# 古いバックアップを自動削除 (cronでの自動実行対応)
local OLD_FILES
OLD_FILES=$(find "${BACKUP_DIR}" -name "vaultwarden_*.tar.gz" \
-mtime +${KEEP_DAYS} 2>/dev/null || true)
if [ -n "${OLD_FILES}" ]; then
local OLD_COUNT
OLD_COUNT=$(echo "${OLD_FILES}" | wc -l)
echo "${OLD_FILES}" | while read -r F; do
rm -f "${F}" "${F}.sha256"
info "古いバックアップを削除: $(basename "${F}")"
done
info "${OLD_COUNT} 件の古いバックアップを削除しました (${KEEP_DAYS}日以上前)"
fi
echo ""
echo "════════════════════════════════════════"
echo -e " ${GREEN}✅ バックアップ完了!${NC}"
echo "════════════════════════════════════════"
echo ""
echo " 📦 ファイル : ${BACKUP_FILE}"
echo " 📏 サイズ : ${BACKUP_SIZE}"
echo " 📅 日時 : $(date '+%Y-%m-%d %H:%M:%S')"
echo ""
}
# ── 復元関数 ──────────────────────────────────────
do_restore() {
print_banner
check_root
local BACKUP_FILE="${1:-}"
# ファイル指定がなければ最新を使用
if [ -z "${BACKUP_FILE}" ]; then
section "最新バックアップを検索..."
BACKUP_FILE=$(find "${BACKUP_DIR}" -name "vaultwarden_*.tar.gz" \
-printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -d' ' -f2-)
if [ -z "${BACKUP_FILE}" ]; then
error "バックアップファイルが見つかりません: ${BACKUP_DIR}"
exit 1
fi
info "最新バックアップ: ${BACKUP_FILE}"
fi
# ファイル存在確認
if [ ! -f "${BACKUP_FILE}" ]; then
error "バックアップファイルが見つかりません: ${BACKUP_FILE}"
exit 1
fi
# チェックサム検証
local SHA256_FILE="${BACKUP_FILE}.sha256"
if [ -f "${SHA256_FILE}" ]; then
section "チェックサムを検証..."
if sha256sum -c "${SHA256_FILE}" --quiet 2>/dev/null; then
info "チェックサム OK"
else
error "チェックサム検証に失敗しました!ファイルが破損している可能性があります"
exit 1
fi
else
warn "チェックサムファイルが見つかりません。スキップします"
fi
# アーカイブ内容確認
section "バックアップ内容を確認..."
echo ""
tar -tzf "${BACKUP_FILE}" | head -20
echo ""
# 確認プロンプト
local BACKUP_SIZE
BACKUP_SIZE=$(du -sh "${BACKUP_FILE}" | cut -f1)
warn "以下の内容で復元します:"
echo " バックアップファイル : ${BACKUP_FILE} (${BACKUP_SIZE})"
echo " 復元先 : ${VAULTWARDEN_DIR}/data/"
echo ""
read -rp " 現在のデータが上書きされます。続行しますか? [y/N]: " CONFIRM
if [[ ! "${CONFIRM}" =~ ^[Yy]$ ]]; then
warn "復元をキャンセルしました"
exit 0
fi
section "[1/4] Vaultwardenコンテナを停止..."
if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker stop "${CONTAINER_NAME}"
info "コンテナを停止しました"
else
warn "コンテナは既に停止しています"
fi
section "[2/4] 現在のデータをバックアップ (退避)..."
local ESCAPE_TIMESTAMP
ESCAPE_TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
local ESCAPE_DIR="${VAULTWARDEN_DIR}/data_before_restore_${ESCAPE_TIMESTAMP}"
if [ -d "${VAULTWARDEN_DIR}/data" ]; then
mv "${VAULTWARDEN_DIR}/data" "${ESCAPE_DIR}"
info "退避先: ${ESCAPE_DIR}"
fi
section "[3/4] バックアップを展開..."
mkdir -p "${VAULTWARDEN_DIR}"
tar -xzf "${BACKUP_FILE}" -C "${VAULTWARDEN_DIR}"
info "展開完了"
section "[4/4] Vaultwardenコンテナを起動..."
cd "${VAULTWARDEN_DIR}"
docker compose up -d
info "コンテナを起動しました"
echo ""
echo "════════════════════════════════════════"
echo -e " ${GREEN}✅ 復元完了!${NC}"
echo "════════════════════════════════════════"
echo ""
echo " 📦 復元元 : ${BACKUP_FILE}"
echo " 🗂️ 退避先 : ${ESCAPE_DIR}"
echo " 📅 日時 : $(date '+%Y-%m-%d %H:%M:%S')"
echo ""
warn "復元後の動作確認が取れたら、退避データを削除してください:"
echo " rm -rf ${ESCAPE_DIR}"
echo ""
}
# ── 一覧表示関数 ──────────────────────────────────
do_list() {
print_banner
if [ ! -d "${BACKUP_DIR}" ]; then
warn "バックアップディレクトリが存在しません: ${BACKUP_DIR}"
exit 0
fi
local FILES
FILES=$(find "${BACKUP_DIR}" -name "vaultwarden_*.tar.gz" \
-printf '%T@ %p\n' 2>/dev/null | sort -rn | cut -d' ' -f2-)
if [ -z "${FILES}" ]; then
warn "バックアップファイルが見つかりません"
exit 0
fi
echo "バックアップ一覧: ${BACKUP_DIR}"
echo ""
printf " %-50s %8s %s\n" "ファイル名" "サイズ" "作成日時"
echo " $(printf '─%.0s' {1..75})"
while IFS= read -r FILE; do
local BASENAME SIZE MTIME
BASENAME=$(basename "${FILE}")
SIZE=$(du -sh "${FILE}" | cut -f1)
MTIME=$(stat -c '%y' "${FILE}" | cut -d'.' -f1)
printf " %-50s %8s %s\n" "${BASENAME}" "${SIZE}" "${MTIME}"
done <<< "${FILES}"
echo ""
local TOTAL_COUNT TOTAL_SIZE
TOTAL_COUNT=$(echo "${FILES}" | wc -l)
TOTAL_SIZE=$(du -sh "${BACKUP_DIR}" | cut -f1)
echo " 合計: ${TOTAL_COUNT} 件 / ${TOTAL_SIZE}"
echo ""
}
# ── 古いバックアップ削除関数 ──────────────────────
do_clean() {
print_banner
check_root
local OLD_FILES
OLD_FILES=$(find "${BACKUP_DIR}" -name "vaultwarden_*.tar.gz" \
-mtime +${KEEP_DAYS} 2>/dev/null || true)
if [ -z "${OLD_FILES}" ]; then
info "${KEEP_DAYS}日以上前のバックアップはありません"
exit 0
fi
warn "以下のファイルを削除します (${KEEP_DAYS}日以上前):"
echo "${OLD_FILES}" | while read -r F; do
echo " - $(basename "${F}") ($(du -sh "${F}" | cut -f1))"
done
echo ""
read -rp " 削除しますか? [y/N]: " CONFIRM
if [[ ! "${CONFIRM}" =~ ^[Yy]$ ]]; then
warn "キャンセルしました"
exit 0
fi
echo "${OLD_FILES}" | while read -r F; do
rm -f "${F}" "${F}.sha256"
info "削除: $(basename "${F}")"
done
info "クリーンアップ完了"
echo ""
}
# ── メイン ────────────────────────────────────────
COMMAND="${1:-}"
case "${COMMAND}" in
backup)
do_backup
;;
restore)
do_restore "${2:-}"
;;
list)
do_list
;;
clean)
do_clean
;;
*)
usage
exit 1
;;
esac
バックアップ作成
sudo bash vaultwarden-backup.sh backup
バックアップ一覧表示
sudo bash vaultwarden-backup.sh list
最新バックアップから復元
sudo bash vaultwarden-backup.sh restore
特定のバックアップから復元
sudo bash vaultwarden-backup.sh restore /opt/lxd-data/vaultwarden/vaultwarden_20250101_120000.tar.gz
古いバックアップを削除(自動で7日以上前を削除しています)
sudo bash vaultwarden-backup.sh clean
cronで自動バックアップ
crontab -e
crontab -e で追加(毎日午前2時に実行)
# Vaultwarden
0 2 * * * bash /opt/lxd-data/script/vaultwarden/vaultwarden-backup.sh backup >> /var/log/vaultwarden-backup.log 2>&1


