Cài Vaultwarden trên VPS bằng Docker, bật HTTPS
Cài Vaultwarden tương thích Bitwarden trên VPS với Docker, HTTPS trước lần mở đầu, admin token, Fail2ban và backup đã test restore cho data volume.
Bạn sẽ xây dựng gì
Một password manager do bạn hoàn toàn kiểm soát: Vaultwarden chạy trong một container nhỏ phía sau reverse proxy có TLS termination, cùng các app Bitwarden chính thức trên điện thoại, laptop và trình duyệt được trỏ đến đó. Vaultwarden triển khai lại Bitwarden server API bằng Rust và sử dụng cùng protocol với bitwarden.com. Vì vậy, mọi client chính thức đều hoạt động với nó mà không cần thay đổi. Tuy nhiên, Vaultwarden chỉ dùng khoảng 100 MB RAM thay vì stack chính thức gồm nhiều container.
Phần cài đặt chỉ gồm khoảng một chục dòng Compose. Có 3 việc thực sự quan trọng và thường gây lỗi: TLS phải hoạt động trước khi bạn mở web vault lần đầu, phải đóng đăng ký công khai ngay khi tài khoản của bạn được tạo, và phải backup rồi test restore data volume. Thư mục đó chứa toàn bộ password của bạn.
Điều kiện cần và những điểm dễ vướng cần biết
- Một VPS đã cài Docker Engine và Compose plugin, chạy trên Ubuntu 24.04 mới cài trên máy KVM, có tài khoản root hoặc sudo. 512 MB RAM thực sự là đủ; 1 GB sẽ thoải mái hơn. Đây là một trong những dịch vụ nhẹ nhất bạn có thể chạy và nằm gần đầu danh sách ngắn các dịch vụ đáng tự host. Tuy nhiên, hãy chọn cấu hình VPS dựa trên mọi dịch vụ khác chạy chung: đưa thư viện ảnh tự host như PhotoPrism hoặc Immich lên cùng VPS sẽ nâng mức RAM tối thiểu lên vài GB, trong khi Vaultwarden hầu như không làm tăng mức này. Cách tính tương tự áp dụng cho các media front end bạn gắn thêm sau này, vì biến thư viện Jellyfin thành một cửa hàng cho thuê băng đĩa thập niên 90 có thể đi dạo qua đồng nghĩa với việc chạy thêm một container luôn bật và cần thêm headroom cho transcoding trong cùng ngân sách.
- Một domain có bản ghi A (và AAAA nếu bạn dùng IPv6) trỏ
vault.example.comđến VPS. TLS certificate được cấp cho chính xác tên này, nên DNS phải resolve được trước khi bắt đầu. - Mở port 80 và 443 ra Internet, do reverse proxy xử lý, không bao giờ để Vaultwarden trực tiếp xử lý. Port 80 chỉ dùng cho ACME certificate challenge và redirect từ HTTP sang HTTPS.
- Điểm dễ vướng lớn nhất cần biết ngay từ đầu: các Bitwarden client sẽ từ chối kết nối đến server không dùng HTTPS. Không có cách “thử bằng http trước”; cách đó không hoạt động vì một lý do cụ thể sẽ được giải thích ở phần tiếp theo.
Vì sao chọn Vaultwarden thay vì stack Bitwarden chính thức
Dùng cùng client nhưng nhẹ hơn rất nhiều. Bitwarden self-hosted chính thức được triển khai dưới dạng một bundle gồm nhiều container như MSSQL, Nginx, Identity, Api, Admin và các thành phần khác, đồng thời cần khoảng 2 GB RAM. Vaultwarden là một binary duy nhất. Theo mặc định, nó lưu toàn bộ dữ liệu trong cơ sở dữ liệu SQLite và khi idle chỉ dùng vài chục megabyte. Với một người, một gia đình hoặc một team nhỏ, đây là lựa chọn rõ ràng. Vì Vaultwarden triển khai API Bitwarden một cách tương thích, dữ liệu vẫn có thể chuyển đổi giữa Vaultwarden và bitwarden.com.
Đổi lại, bạn không có phần lớn các tính năng dành cho enterprise: không có SCIM provisioning (dù OpenID Connect SSO thử nghiệm đã có trong 1.35.0). Bạn cũng là người vận hành hệ thống, nên phải tự xử lý việc cập nhật bản vá, HTTPS và backup. Guide này tập trung vào ba việc đó.
HTTPS không phải tùy chọn
Bitwarden web vault và các browser extension dẫn xuất encryption key trong browser bằng Web Crypto API (window.crypto.subtle). Browser chỉ cung cấp crypto.subtle trong secure context, tức HTTPS hoặc trường hợp đặc biệt là http://localhost. Qua http://vault.example.com thuần, việc này là undefined, nên ngay khi app dẫn xuất key, nó sẽ throw và console hiển thị:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'importKey')Trang bị treo hoặc hiển thị lỗi crypto chung, và không đăng nhập được. Các client desktop, mobile và browser tự kiểm tra URL self-hosted. Với endpoint dùng http hoặc không thể truy cập, chúng từ chối kết nối với thông báo:
This is not a recognized Bitwarden server. You may need to check with your provider or update your server.Cả hai đều có cùng nguyên nhân: không có HTTPS hợp lệ. Vì vậy, hãy thiết lập TLS trước và không bao giờ mở vault qua http, kể cả chỉ mở một lần để kiểm tra nhanh.
Bước 1, DNS và reverse proxy (ưu tiên TLS)
Trỏ record đến VPS của bạn và xác nhận record phân giải đến đúng địa chỉ:
dig +short vault.example.comDòng lệnh in ra phải là IP của VPS. Nếu dòng này trống hoặc sai, hãy sửa DNS và chờ hết TTL. Việc cấp certificate sẽ thất bại nếu hostname không phân giải được.
Guide này dùng Traefik cho frontend HTTPS. Traefik tự động cấp và gia hạn certificate Let's Encrypt, đồng thời tích hợp trực tiếp với Compose. Nếu bạn chưa chạy Traefik, hãy làm theo hướng dẫn thiết lập reverse proxy Traefik và TLS tự động trước. Thiết lập này tạo một Docker network bên ngoài (proxy bên dưới) và một ACME resolver (letsencrypt) để service Vaultwarden kết nối vào. nginx thông thường với certificate cấp thủ công cũng hoạt động tương tự ở phía Vaultwarden.
Bạn muốn dùng nginx và Certbot thay vì Traefik? Đặt Vaultwarden vào 127.0.0.1:8080 (thêm ports: ["127.0.0.1:8080:80"] vào service và xóa các label của Traefik), sau đó cấp certificate và proxy đến service này. Phần certificate được trình bày trong hướng dẫn cấp certificate Let's Encrypt bằng Certbot và nginx. Phần bổ sung quan trọng là cấu hình WebSocket upgrade trên path notifications:
server {
listen 443 ssl;
server_name vault.example.com;
client_max_body_size 525M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Chú ý dòng X-Real-IP. Dòng này cho phép Fail2ban sau đó nhìn thấy IP thật của attacker thay vì 127.0.0.1. Mọi phần khác trong guide đều giống nhau, dù phía trước dùng Traefik hay nginx.
Bước 2, file Compose
Trước tiên, tạo thư mục project. Guide này dùng /opt/vaultwarden để tên project Compose và do đó cả data volume là vaultwarden_vw-data, có thể dự đoán được; các bước cấu hình Fail2ban và backup bên dưới phụ thuộc vào đúng tên này.
sudo mkdir -p /opt/vaultwarden
cd /opt/vaultwardenTrong thư mục đó, tạo một .env cho admin secret và file Compose.
# .env
ADMIN_TOKEN=paste-a-strong-token-hereTạo token bằng openssl rand -base64 48 rồi dán token vào file. (Phần tiếp theo sẽ hướng dẫn dạng hash mạnh hơn; để bắt đầu, một chuỗi ngẫu nhiên dài là đủ.)
# docker-compose.yml
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.com"
SIGNUPS_ALLOWED: "true" # closed in Step 4, keep true just to register
ADMIN_TOKEN: "${ADMIN_TOKEN}"
IP_HEADER: "X-Forwarded-For" # X-Real-IP if your proxy sends that instead
LOG_FILE: "/data/vaultwarden.log"
LOG_LEVEL: "warn"
volumes:
- vw-data:/data
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.vw.rule=Host(`vault.example.com`)"
- "traefik.http.routers.vw.entrypoints=websecure"
- "traefik.http.routers.vw.tls.certresolver=letsencrypt"
- "traefik.http.services.vw.loadbalancer.server.port=80"
volumes:
vw-data:
networks:
proxy:
external: trueCó 2 điểm trong file này quyết định toàn bộ thiết kế. Không có mapping ports:, nên chỉ có thể truy cập Vaultwarden thông qua Traefik và TLS của Traefik; publish port của Vaultwarden trên host sẽ khiến người dùng vô tình phục vụ vault qua http. Ngoài ra, DOMAIN phải là URL HTTPS public đầy đủ: giá trị này được tích hợp vào link attachment, WebAuthn 2FA và endpoint notifications, nên giá trị sai hoặc dùng http sẽ làm các chức năng đó hỏng dù website vẫn tải được. Tag latest là ngoại lệ có chủ ý đối với quy tắc thông thường là không bao giờ dùng latest. Vaultwarden phát hành các bản stable dưới dạng một image rolling duy nhất, còn :testing là channel pre-release riêng. Vì vậy, hãy chủ động update và đọc lướt release notes trước khi pull. Tuy nhiên, ngoại lệ này chỉ áp dụng trong phạm vi hẹp: phần lớn container chạy lâu dài nên được pin vào một tag chính xác. Đây là cách giữ cho một agent luôn chạy được self-host trên cùng VPS ổn định qua các lần reboot và pull.
Khởi động stack và theo dõi log:
docker compose up -d
docker compose logs -f vaultwardenNếu khởi động đúng, log sẽ kết thúc bằng một dòng như Rocket has launched from http://0.0.0.0:80. Chờ Traefik vài giây để lấy certificate, sau đó mở https://vault.example.com. Bạn sẽ thấy Bitwarden web vault với biểu tượng ổ khóa hợp lệ và không có cảnh báo certificate.
Bước 3, ADMIN_TOKEN mạnh và bẫy $$
ADMIN_TOKEN bảo vệ /admin, panel có thể đọc mọi user và setting trên instance của bạn, vì vậy hãy xem nó như root password. Có 2 dạng được hỗ trợ.
Dạng đơn giản là chuỗi ngẫu nhiên bạn đã tạo bằng openssl rand -base64 48. Vì base64 không bao giờ chứa $, bạn có thể đưa thẳng chuỗi này vào .env mà không cần escape.
Dạng bảo mật hơn là Argon2 PHC hash, nên token dạng plaintext không bao giờ được lưu trên disk. Tạo hash bằng chính image đó:
docker run --rm -it vaultwarden/server /vaultwarden hash --preset owaspLệnh này hỏi 2 lần rồi in ra một chuỗi bắt đầu bằng $argon2id$v=19$.... Đây là bẫy khiến nhiều người mất cả giờ: Docker Compose coi $ là phép nội suy biến, vì vậy bạn phải nhân đôi mọi $ thành $$ khi dán hash vào file Compose. Đặt hash trực tiếp bên dưới environment:, không thông qua .env, và không đặt trong dấu ngoặc kép:
environment:
ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$c29tZXNhbHQ$$RdescudvJCsgt3ub+b+dWRWJTmaaJObGNếu giữ nguyên các dấu $ đơn, Compose sẽ cảnh báo The "argon2id" variable is not set và xóa token, sau đó /admin sẽ từ chối password chính xác của bạn. Chạy docker compose up -d, rồi lưu plaintext bạn đã nhập tại prompt vào password store riêng của bạn.
Bước 4, đăng ký tài khoản rồi khóa đăng ký
Dùng SIGNUPS_ALLOWED: "true" để mở https://vault.example.com, nhấp Create account, rồi đăng ký bằng email và một master password mạnh. Không thể khôi phục master password này và cũng không có chức năng reset, vì vậy hãy lưu nó ở nơi bền vững trước.
Bây giờ hãy đóng đăng ký. Chỉnh sửa file Compose để tắt đăng ký:
SIGNUPS_ALLOWED: "false"Áp dụng lại bằng docker compose up -d. Đây không phải việc hardening có thể trì hoãn. Nếu để mở, bất kỳ ai tìm thấy URL, kể cả crawler, đều có thể tạo tài khoản trên server của bạn. Họ không thể đọc vault của bạn, nhưng vẫn tiêu tốn tài nguyên và biến instance riêng của bạn thành một service mở. Dấu hiệu cho thấy bạn vẫn để mở: /admin liệt kê các tài khoản mà bạn chưa từng tạo.
Để thêm thành viên gia đình hoặc đồng đội sau này mà không mở lại đăng ký công khai, hãy dùng nút Invite User trong /admin; cách này yêu cầu đã cấu hình SMTP để người được mời nhận được link của họ.
Bước 5, truy cập /admin
Mở https://vault.example.com/admin và nhập admin token dạng plaintext (chuỗi ngẫu nhiên hoặc password mà bạn đã hash, không phải chính hash đó). Tại đây, bạn có thể liệt kê user, điều chỉnh setting, gửi email kiểm thử và tạo snapshot cho database.
Nếu trang trả về 404 Not Found, thì ADMIN_TOKEN đang rỗng hoặc chưa được set. Điều này vô hiệu hóa hoàn toàn panel và vẫn là lựa chọn hợp lệ nếu bạn không bao giờ cần dùng panel. Nếu panel tải được nhưng từ chối token, xem lỗi escaping của $$ trong danh sách lỗi bên dưới. Quên token? Không có prompt khôi phục. Hãy sửa .env hoặc file Compose, đặt token mới rồi docker compose up -d.
Bước 6, kết nối các client Bitwarden
Mọi client chính thức đều có thể kết nối đến server self-hosted. Vì vậy, hãy cài client Bitwarden cho desktop, mobile hoặc browser từ các store thông thường. Bạn không cần bản build Vaultwarden riêng.
Trước khi đăng nhập, mở biểu tượng bánh răng cài đặt trên màn hình đăng nhập (có nhãn Self-hosted hoặc Region → Self-hosted), đặt Server URL thành https://vault.example.com rồi lưu. Sau đó đăng nhập bằng email và master password đã đăng ký. Client sẽ kết nối ngay và đề nghị tự động điền, lưu credential.
Nếu client hiển thị This is not a recognized Bitwarden server. You may need to check with your provider or update your server., URL có thể sai, đang dùng http hoặc certificate không được tin cậy. Hãy kiểm tra lại để đảm bảo https://vault.example.com tải bình thường trong browser trước. Việc cập nhật chậm trên các thiết bị khác là do WebSocket push; phần dưới sẽ giải thích vấn đề này.
Bước 7, cấu hình jail Fail2ban cho endpoint đăng nhập
Vaultwarden ghi lại mọi lần đăng nhập thất bại vào file được đặt bằng LOG_FILE. Đây chính xác là dữ liệu cần cho cơ chế chống brute-force. Nếu bạn chưa chạy Fail2ban, phần cài đặt và kiến thức cơ bản có trong hướng dẫn hardening SSH bằng Fail2ban; ở đây chúng ta chỉ thêm một jail cho vault.
Trước tiên, tìm vị trí của named volume trên host để Fail2ban có thể đọc log:
docker volume inspect vaultwarden_vw-data --format '{{ .Mountpoint }}'Lệnh này sẽ in ra thông tin tương tự /var/lib/docker/volumes/vaultwarden_vw-data/_data; log nằm trong vaultwarden.log. Tạo filter:
# /etc/fail2ban/filter.d/vaultwarden.conf
[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =Sau đó tạo jail:
# /etc/fail2ban/jail.d/vaultwarden.local
[vaultwarden]
enabled = true
filter = vaultwarden
logpath = /var/lib/docker/volumes/vaultwarden_vw-data/_data/vaultwarden.log
banaction = iptables-allports
chain = DOCKER-USER
maxretry = 5
findtime = 600
bantime = 3600Reload bằng sudo systemctl restart fail2ban và xác nhận bằng sudo fail2ban-client status vaultwarden.
Có 3 chi tiết về Docker quyết định cấu hình này có thực sự bảo vệ hệ thống hay không. Thứ nhất, nếu log hiển thị IP: 127.0.0.1 hoặc địa chỉ của proxy trong mọi lần đăng nhập thất bại, Vaultwarden đang ban proxy. Hãy đặt IP_HEADER thành header mà proxy của bạn thực sự gửi, dùng X-Forwarded-For cho Traefik, X-Real-IP cho block nginx ở trên và CF-Connecting-IP khi chạy phía sau Cloudflare. Thứ hai, chain iptables phù hợp phụ thuộc vào proxy của bạn. Khi Traefik chạy dưới dạng container với các port được publish, traffic đi qua path FORWARD của Docker, nên lệnh ban phải đặt trong DOCKER-USER như trên. Nhưng nếu bạn chọn phương án host-nginx ở Step 1, các kết nối kết thúc tại nginx trên host, trong chain INPUT, và lệnh ban DOCKER-USER sẽ không nhìn thấy chúng. Khi đó, hãy xóa dòng chain = DOCKER-USER để Fail2ban dùng chain mặc định INPUT. Thứ ba, hãy dùng banaction = iptables-allports thay cho cấu hình mặc định dựa trên port. Jail này không định nghĩa port, còn lệnh ban áp dụng cho mọi port trong DOCKER-USER sẽ chặn offender khỏi tất cả service được publish trên máy.
Bước 8, sao lưu vault rồi thực sự khôi phục nó
Volume vw-data chính là password manager của bạn. Nó chứa db.sqlite3 (mọi entry), các thư mục attachments/ và sends/, các file rsa_key.* dùng để ký login session, và config.json từ admin panel. Bản sao lưu bỏ sót bất kỳ thành phần nào trong số này sẽ thất bại khi bạn cần khôi phục.
Sao chép db.sqlite3 trong lúc Vaultwarden đang ghi dữ liệu có thể tạo ra file bị ghi dở và hỏng. Vì vậy, hãy tạo cold snapshot. Thời gian gián đoạn chỉ vài giây:
#!/usr/bin/env bash
set -euo pipefail
STAMP=$(date +%F)
DEST=/root/vw-backups
VOL=$(docker volume inspect vaultwarden_vw-data --format '{{ .Mountpoint }}')
mkdir -p "$DEST"
docker compose -f /opt/vaultwarden/docker-compose.yml stop vaultwarden
tar czf "$DEST/vw-$STAMP.tgz" -C "$VOL" .
docker compose -f /opt/vaultwarden/docker-compose.yml start vaultwardenChạy lệnh này hằng đêm bằng cron và sao chép .tgz ra ngoài máy. Bản sao lưu chỉ tồn tại trên chính server mà bạn đang bảo vệ thì không phải là bản sao lưu. Cách phù hợp để chuyển nó là dùng restic sao lưu hằng đêm sang server khác hoặc object storage, công cụ này mã hóa archive và deduplicate các snapshot lặp lại cho bạn. Nút Backup Database trong admin panel rất tiện để tạo hot snapshot chỉ của file SQLite, nhưng nó bỏ qua attachments và keys.
Bây giờ là bước phân biệt bản sao lưu thực sự với việc chỉ hy vọng mọi thứ sẽ ổn: hãy khôi phục nó một lần và xác nhận nó hoạt động:
mkdir -p /tmp/vw-restore
tar xzf /root/vw-backups/vw-2026-07-15.tgz -C /tmp/vw-restore
docker run --rm -p 127.0.0.1:8888:80 -v /tmp/vw-restore:/data vaultwarden/serverTừ laptop, hãy tạo tunnel đến server bằng ssh -L 8888:127.0.0.1:8888 you@your-vps rồi mở http://localhost:8888. Vì localhost là secure context nên crypto.subtle khả dụng, và vault được giải mã qua plain http tại đây. Đây là nơi duy nhất được phép làm vậy. Đăng nhập bằng master password và xác nhận các entry của bạn vẫn còn. Nếu chúng còn, database, RSA keys và master password của bạn đều đã được khôi phục đầy đủ, và bạn có thể dựng lại trên một VPS mới trong vài phút. Dừng container bằng Ctrl-C rồi xóa /tmp/vw-restore. Hãy giữ thói quen dùng tunnel này cho mọi admin UI khác trên máy không nên public ra Internet. Bạn cũng sẽ dùng cách này để truy cập một security scanner open-kritt tự host trên port 5173.
Các dạng lỗi và chuỗi bạn sẽ thấy
Cannot read properties of undefined (reading 'importKey') trong console của trình duyệt. Vault được tải qua http nên crypto.subtle không được định nghĩa; chỉ truy cập vault qua https:// và thêm redirect HTTP sang HTTPS tại proxy.
This is not a recognized Bitwarden server... trong client. Server URL dùng http, bị nhập sai hoặc certificate không được tin cậy; xác nhận https://vault.example.com hiển thị biểu tượng ổ khóa hợp lệ, rồi nhập lại URL đó trong phần cài đặt self-hosted của client.
/admin từ chối password chính xác. Argon2 hash bị mất ký tự escape, mọi $ phải được ghi thành $$ trong Compose, hoặc bạn đã nhập hash thay vì plaintext tương ứng.
Đồng bộ giữa các thiết bị chậm; console hiển thị WebSocket connection to 'wss://vault.example.com/notifications/hub' failed. Proxy không forward các header Upgrade/Connection; Traefik tự xử lý việc này, còn nginx cần 2 dòng upgrade từ Step 1. Vault vẫn hoạt động, nhưng chỉ đồng bộ khi mở. Dedicated port 3012 cũ đã bị loại bỏ từ v1.31.0, nên không cần route WebSocket riêng.
Fail2ban báo đã ban nhưng attacker vẫn tiếp tục kết nối. Nó đang ban 127.0.0.1 vì IP_HEADER không đúng, hoặc rule ban nằm trong iptables chain sai; đặt chain = DOCKER-USER và banaction = iptables-allports.
Nâng cấp
Pull image mới và tạo lại container; named volume cùng toàn bộ dữ liệu vẫn được giữ nguyên:
docker compose pull
docker compose up -dVaultwarden phát hành bản mới thường xuyên. Hãy theo dõi ghi chú phát hành của project thay vì pin một patch version, vì một số bản phát hành có kèm hướng dẫn migration. Hãy tạo backup mới trước mỗi lần nâng cấp lớn; bạn có thể rollback bằng cách khôi phục tarball vào một volume mới.
FAQ
Vaultwarden có giống Bitwarden không?
Đây là một server độc lập tương thích, không phải server chính thức. Vaultwarden triển khai lại Bitwarden server API bằng Rust, nên các client chính thức trên desktop, mobile, trình duyệt và CLI đều hoạt động với nó, trong khi chỉ dùng một phần nhỏ tài nguyên so với stack chính thức. Định dạng vault giống nhau, vì vậy bạn có thể migrate theo cả hai chiều bằng cách export và import.
Tôi có thực sự cần HTTPS không, hay có thể chạy qua http trong LAN?
Bạn cần HTTPS cho mọi trường hợp ngoài một bài test localhost. Bitwarden web vault và các extension sử dụng Web Crypto API của trình duyệt. API này chỉ hoạt động trong secure context, nên client sẽ báo Cannot read properties of undefined và không bao giờ đăng nhập được khi dùng http thuần. Địa chỉ http duy nhất hoạt động là http://localhost. Vì vậy, bài restore test ở Bước 8 sử dụng SSH tunnel.
Làm thế nào để ngăn người lạ đăng ký trên server?
Đặt SIGNUPS_ALLOWED: "false" trong file Compose rồi chạy docker compose up -d ngay sau khi tạo tài khoản của bạn. Sau đó, thêm người dùng mới bằng nút Invite User trong /admin. Tính năng này cần SMTP đã được cấu hình để họ nhận link mời. Thỉnh thoảng kiểm tra danh sách admin user để xác nhận không có tài khoản bất thường nào xuất hiện.
Làm thế nào để backup Vaultwarden vault?
Tạm dừng container rồi archive toàn bộ volume vw-data, db.sqlite3, attachments/, sends/, config.json và các file rsa_key.*. Sau đó copy archive ra khỏi server, tốt nhất là chạy bằng cron hằng đêm. Copy file SQLite khi server đang chạy có thể tạo snapshot bị hỏng, vì vậy hãy backup khi server đã dừng. Quan trọng nhất, hãy restore một lần vào một container tạm thời rồi đăng nhập, để xác nhận backup dùng được trước khi phụ thuộc vào nó.
Tự host password có thực sự an toàn không?
Có, nếu bạn thực hiện 3 việc được đề cập trong guide này: HTTPS thực sự, tắt đăng ký cùng với admin token mạnh, và backup đã được kiểm tra restore. Vault được mã hóa phía client bằng master password, nên ngay cả server cũng không thấy password ở dạng rõ; một db.sqlite3 bị đánh cắp sẽ vô dụng nếu không có master password. Đổi lại, việc patch và backup trở thành trách nhiệm của bạn. Vì vậy, Fail2ban và quy trình restore không phải là các bước tùy chọn ở đây. Khi đã thiết lập những phần này, xem kỹ hơn những nơi mà một vault tự host thực sự có thể bị tấn công là bước tiếp theo hữu ích. Vì các entry đã được mã hóa ở client, phần còn lại cần bảo vệ là admin token và backup archive.