[Инструкция] Vaultwarden и Caddy в Docker - полный цикл с бэкапом и автообновлением

Vaultwarden – это легковесная реализация сервера Bitwarden на языке Rust, идеально подходящая для домашнего сервера или VPS. Использование Caddy в качестве реверс-прокси позволяет автоматически получить и продлевать SSL-сертификаты, обеспечивая безопасный доступ к вашим паролям.

Официальный репозиторий проекта: Vaultwarden на GitHub

Данное руководство охватывает весь цикл работы с сервисом: от чистой установки на Debian до настройки автоматического ежедневного резервного копирования в облако и методов быстрого восстановления данных.

Установка Vaultwarden и Caddy через Docker-Compose

Устанавливаем Docker с помощью официального скрипта:

curl https://get.docker.com -o install.sh && sh install.sh

Добавляем в автозагрузку наш Docker:

systemctl enable docker.service

Проверяем что все установилось:

docker version
docker compose version

Создаем нужные директории и сам docker-compose.yml:

mkdir -p /app/vaultwarden
cd /app/vaultwarden
nano docker-compose.yml

Заполняем его следующим содержимым:


services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    environment:
      DOMAIN: "https://ВАШ_ДОМЕН.RU"
      SIGNUPS_ALLOWED: "true" # Меняем на false для закрытия регистрации
    volumes:
      - ./data:/data

  caddy:
    image: caddy:2
    container_name: caddy
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-config:/config
      - ./caddy-data:/data
    environment:
      DOMAIN: "https://ВАШ_ДОМЕН.RU"
      EMAIL: "ВАША_ПОЧТА@gmail.com"
      LOG_FILE: "/data/access.log"

Создаем и наполняем содержимым наш Caddyfile:

nano Caddyfile
{$DOMAIN} {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }

  tls {$EMAIL}

  encode gzip

  header {
    Strict-Transport-Security "max-age=31536000;"
    X-XSS-Protection "1; mode=block"
    X-Frame-Options "DENY"
    X-Robots-Tag "none"
    -Server
  }

  reverse_proxy vaultwarden:80 {
    header_up X-Real-IP {remote_host}
  }
}

Запускаем наш Docker-Compose.yml файл и завершаем установку:

docker compose up -d

Обновление Vaultwarden

Быстрое обновление (одной строкой)

cd /app/vaultwarden && docker compose down && docker pull vaultwarden/server:latest && docker compose up -d && sleep 5 && docker exec vaultwarden /vaultwarden --version

Пошаговое обновление

Перейти в папку Vaultwarden:

cd /app/vaultwarden

Остановить текущие контейнеры:

docker compose down 

Скачать последнюю версию образа Vaultwarden:

docker pull vaultwarden/server:latest

Перезапустить контейнеры с новым образом:

docker compose up -d

Автоматическое обновление через Watchtower

Чтобы не проверять выход новых версий вручную, мы используем Watchtower. Это утилита, которая автоматически сканирует установленные контейнеры, скачивает свежие образы и перезапускает сервисы, сохраняя все настройки и удаляя за собой старые слои.

Выберите один из двух вариантов настройки: стандартный фоновый контейнер или энергоэффективный запуск через systemd (рекомендуется для слабых серверов с RAM 512 МБ – 1 ГБ).

Вариант 1: Фоновый контейнер (Стандартный способ)

Если вы хотите перенастроить или обновить сам Watchtower, сначала удалите текущий контейнер:

docker rm -f watchtower

Затем выполните команду для запуска Watchtower в универсальном режиме. Он будет проверять обновления для всех контейнеров (Vaultwarden и Caddy) раз в сутки:

docker run -d \
  --name watchtower \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  nickfedor/watchtower \
  --cleanup \
  --interval 86400

Разбор флагов:

Проверка работы

Вы всегда можете посмотреть, что делал Watchtower и не нашёл ли он обновлений, с помощью логов:

docker logs watchtower

Вариант 2: Запуск по расписанию через Systemd (Для слабых серверов)

Зачем это нужно: постоянный фоновый контейнер Watchtower вместе с процессом containerd-shim занимает около 15–20 МБ ОЗУ круглосуточно. На серверах с 512 МБ памяти этот объём критичен. Настройка через systemd-timer запускает Watchtower разово (флаг --run-once) строго по расписанию: он обновляет образы и сразу полностью выгружается из памяти.

Если запущен постоянный контейнер Watchtower, остановите и удалите его:

docker rm -f watchtower

Создайте разовую системную службу:

nano /etc/systemd/system/docker-update.service

Вставьте следующее содержимое:

[Unit]
Description=Docker Containers Auto Update (Watchtower One-Shot)
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=/usr/bin/docker run --rm -v /var/run/docker.sock:/var/run/docker.sock nickfedor/watchtower --cleanup --run-once

Создайте таймер расписания (проверка каждое воскресенье в 04:00 ночи):

nano /etc/systemd/system/docker-update.timer

Вставьте следующее содержимое:

[Unit]
Description=Run Docker update weekly

[Timer]
OnCalendar=Sun *-*-* 04:00:00
Persistent=true

[Install]
WantedBy=timers.target

Примените настройки и включите таймер:

systemctl daemon-reload && systemctl enable --now docker-update.timer

Проверить статус таймера и время следующего срабатывания:

systemctl list-timers docker-update.timer

Посмотреть логи последнего обновления:

journalctl -u docker-update.service

Запуск обновления вручную (здесь и сейчас)

Если вы хотите принудительно обновить все контейнеры прямо сейчас, не дожидаясь плановой проверки, используйте разовый запуск:

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock nickfedor/watchtower --cleanup --run-once

Этот способ гораздо надёжнее и чище, чем ручное пересоздание контейнеров.

Проверка версии Vaultwarden

1. Через логи Docker

docker logs vaultwarden 2>&1 | grep -i "version"

(Замените vaultwarden на имя своего контейнера, если оно другое). В самом начале логов при запуске он всегда пишет свою версию.

2. Через консоль внутри контейнера

docker exec -it vaultwarden /vaultwarden --version

Это выведет точную версию исполняемого файла.

3. Через Docker Inspect

Если вы хотите узнать версию образа (тег):

docker inspect vaultwarden | grep -i "version"

Локальное резервное копирование (Backup на VPS)

Если вы не хотите подключать сторонние облачные хранилища или хотите сохранять копии локально для ручной загрузки на свой ПК через SFTP (MobaXterm / Termius).

Создание папки под бэкапы:

mkdir -p /root/VaultBackups

Создание скрипта для локального бэкапа

Создаём исполняемый файл:

nano /root/backup.sh

Вставляем содержимое (архивирует данные и удаляет копии старше 30 дней):

#!/bin/bash

SOURCE_DIR="/app/vaultwarden/data"
BACKUP_DIR="/root/VaultBackups"
DATE=$(date +%Y-%m-%d_%H-%M)
FILENAME="vaultwarden-backup-$DATE.tar.gz"

# 1. Создаём папку под бэкапы, если её ещё нет
mkdir -p "$BACKUP_DIR"

# 2. Упаковываем все данные (базу, ключи, вложения)
tar -czf "$BACKUP_DIR/$FILENAME" -C "$SOURCE_DIR" .

# 3. Удаляем локальные архивы старше 30 дней
find "$BACKUP_DIR" -type f -name "vaultwarden-backup-*.tar.gz" -mtime +30 -delete

Даём права на запуск:

chmod +x /root/backup.sh

Запуск автоматического резервного копирования каждый день в 03:00 ночи:

crontab -e

Вставьте в конец файла:

0 3 * * * /root/backup.sh

Проверка работы

Выполните тестовый запуск:

/root/backup.sh

Проверьте созданный архив:

ls -lh /root/VaultBackups

Скачивание бэкапа на ПК через SFTP

  1. Откройте MobaXterm или Termius и подключитесь к серверу.
  2. В панели SFTP перейдите в папку /root/VaultBackups.
  3. Перетащите нужный архив .tar.gz на свой рабочий стол или в папку хранения копий.

Настройка резервного копирования (Backup) в Яндекс.Диск

Установка и настройка rclone

Для синхронизации с облаком используем официальный скрипт установки rclone (всегда ставит актуальную версию):

curl https://rclone.org/install.sh | sudo bash

Проверяем, что установилась актуальная версия:

rclone version

Способ №1: Через Полигон Яндекс Диска (Самый надёжный и бесплатный)

[!NOTE] Почему этот способ
Стандартная авторизация rclone часто выдаёт ошибку 410 GoneError, а WebDAV стал платным («Яндекс 360»). Способ через официальный Полигон работает на любых бесплатных аккаунтах и не требует скачивать rclone на свой компьютер.

  1. Перейдите на страницу Полигона Яндекс Диска.
  2. Вверху страницы нажмите жёлтую кнопку «Получить OAuth-токен» и подтвердите доступ к аккаунту.
  3. Скопируйте полученный токен (начинается на y0_...).
  4. На сервере выполните команду (заменив ВАШ_ТОКЕН на скопированный токен):
mkdir -p ~/.config/rclone && cat << 'EOF' > ~/.config/rclone/rclone.conf  
[yandex]  
type = yandex  
token = {"access_token":"ВАШ_ТОКЕН","token_type":"OAuth","refresh_token":"unused","expiry":"2099-01-01T00:00:00Z"}  
EOF
  1. Проверьте доступ к облаку:
rclone lsd yandex:

Способ №2: Через OAuth Токен

Классический метод через официальный API. Пароль здесь не нужен.

rclone config

Ход настройки на сервере:

  1. n) New remote – вводим имя yandex.
  2. Storage – ищем и выбираем yandex.
  3. client_id, client_secret и Edit advanced config – оставляем пустыми (Enter).
  4. Use auto config? – жмём n (нет, так как мы на сервере).
  5. Система предложит ввести результат (токен).

Как добыть токен:
Поскольку на сервере нет браузера, токен нужно получить на своём личном компьютере (ПК):

  1. Перейди на rclone.org/downloads и скачай архив для своей системы (например, Windows).
  2. Распакуй его, открой терминал (PowerShell или CMD) в этой папке.
  3. Введи команду: .\rclone.exe authorize "yandex" (для Windows) или ./rclone authorize "yandex" (для macOS).
  4. В браузере откроется страница Яндекса – нажми «Разрешить».
  5. Вернись в терминал на ПК. Там появится код в фигурных скобках вида {"access_token":"..."}.
  6. Скопируй весь этот код целиком, вставь в поле result> на сервере и нажми Enter.

Способ №3: Через WebDAV

Подготовка Яндекс.Диска

Перед настройкой обязательно создайте Пароль приложения в Яндекс ID:

  1. Зайдите в  Яндекс ID -> Пароли приложений
  2. Нажмите «Создать» -> выбирайте «Файлы».
  3. Назовите его rclone-server и сохраните код. Именно его нужно вводить в пункте password ниже (шаг 6).
rclone config

Ход настройки:

  1. n) New remote – вводим имя yandex.
  2. Storage – ищем и выбираем webdav.
  3. url – вводим: https://webdav.yandex.ru
  4. vendor – выбираем yandex (обычно пункт 5). Или other (обычно пункт 8).
  5. user – вводим твой логин (почту) Яндекса.
  6. password – выбираем y) Yes, type in my own password.
    • Внимание: Сюда вставляем не основной пароль, а Пароль приложения (16 букв), который мы создали в Яндекс ID.
  7. bearer_token – оставляем пустым (просто Enter).
  8. Edit advanced config – жмём n (нет).
  9. Keep this "yandex" remote? – жмём y (да).

Создание скрипта для бэкапа

Создаём файл:

nano /root/backup.sh

Выберите подходящий вариант скрипта:

Вариант А: Только в Яндекс Диск (без сохранения на VPS)
Архив создаётся во временной папке /tmp, выгружается на Яндекс Диск и сразу удаляется с сервера:

#!/bin/bash

SOURCE_DIR="/app/vaultwarden/data"
FILENAME="vaultwarden-backup-$(date +%Y-%m-%d_%H-%M).tar.gz"

# 1. Создаём временный архив
tar -czf /tmp/$FILENAME -C $SOURCE_DIR .

# 2. Копируем на Яндекс Диск
rclone copy /tmp/$FILENAME yandex:VaultBackups

# 3. Чистим за собой временный файл
rm -f /tmp/$FILENAME

# 4. Удаляем бэкапы в облаке старше 30 дней
rclone delete --min-age 30d yandex:VaultBackups

Вариант Б: Гибридный (локальная копия на VPS + копия в Яндекс Диск)
Архив сохраняется в локальную папку, дублируется в облако, а ротация удаляет копии старше 30 дней и на сервере, и на Яндекс Диске:

#!/bin/bash

SOURCE_DIR="/app/vaultwarden/data"
BACKUP_DIR="/root/VaultBackups"
DATE=$(date +%Y-%m-%d_%H-%M)
FILENAME="vaultwarden-backup-$DATE.tar.gz"

# 1. Создаём папку под бэкапы, если её ещё нет
mkdir -p "$BACKUP_DIR"

# 2. Упаковываем все данные в локальную папку
tar -czf "$BACKUP_DIR/$FILENAME" -C "$SOURCE_DIR" .

# 3. Копируем архив на Яндекс Диск
rclone copy "$BACKUP_DIR/$FILENAME" yandex:VaultBackups

# 4. Удаляем архивы старше 30 дней в облаке
rclone delete --min-age 30d yandex:VaultBackups

# 5. Удаляем локальные архивы старше 30 дней на сервере
find "$BACKUP_DIR" -type f -name "vaultwarden-backup-*.tar.gz" -mtime +30 -delete

Даём права на запуск:

chmod +x /root/backup.sh

Автоматизация (Cron)

Заставляем сервер делать бэкап автоматически каждый день в 03:00 ночи:

crontab -e

Добавляем в самый конец:

0 3 * * * /root/backup.sh

Проверка

Для ручного запуска и проверки используйте:

/root/backup.sh
rclone ls yandex:VaultBackups

Восстановление данных (Restore)

Способ 1: Через консоль (с Яндекс.Диска)

Этот метод самый быстрый, если сервер работает и rclone настроен.

Остановите контейнеры:

cd /app/vaultwarden && docker compose down

Посмотрите список доступных бэкапов:

rclone ls yandex:VaultBackups

Скачайте все бэкапы на сервер (флаг -P покажет наглядный прогресс скачивания):

rclone copy yandex:VaultBackups /root/VaultBackups -P

Либо скачайте один конкретный архив (замените имя на своё):

rclone copy yandex:VaultBackups/vaultwarden-backup-ИМЯ_ВАШЕГО_ФАЙЛА.tar.gz /root/VaultBackups -P

Очистите текущую папку данных и распакуйте бэкап:

rm -rf /app/vaultwarden/data/*  
tar -xzf /root/VaultBackups/vaultwarden-backup-ИМЯ_ВАШЕГО_ФАЙЛА.tar.gz -C /app/vaultwarden/data/

Запустите сервис:

docker compose up -d

Способ 2: Через SFTP (MobaXterm / Termius)

Если архив бэкапа лежит у вас на компьютере.

Подключитесь к серверу через MobaXterm или Termius.

Остановите контейнеры в консоли:

cd /app/vaultwarden && docker compose down

Загрузите файл: Просто перетащите ваш архив .tar.gz с компьютера в папку /root/VaultBackups на сервере через графический интерфейс SFTP.

Распакуйте данные (подставив имя своего файла):

rm -rf /app/vaultwarden/data/*
tar -xzf /root/VaultBackups/vaultwarden-backup-ИМЯ_ВАШЕГО_ФАЙЛА.tar.gz -C /app/vaultwarden/data/

[!WARNING] Важно
Не распаковывайте архив на Windows перед загрузкой, чтобы не нарушить права доступа Linux.

Проверьте права (на всякий случай):

chown -R root:root /app/vaultwarden/data

Запустите сервис:

docker compose up -d