Links
Comment on page

1.使用 MariaDB (MySQL) 后端

对应的官方页面地址
我们的构建基于 MariaDB 客户端库,因为这是 Debian 提供的。
对最新 Oracle MySQLv8 版本的支持需要额外注意。
如果您坚持使用 MySQLv8 而不是 MariaDB,请使用旧的密码散列方法而不是默认方法创建用户!
要使用 MySQL 后端,你可以使用官方 Docker 镜像,也可以构建您自己的启用了 MySQL 的二进制。
要运行二进制或容器,请确保已设置 DATABASE_URL 环境变量(即 DATABASE_URL='mysql://<user>:<password>@mysql/vaultwarden[?ssl_mode=(disabled|required|preferred)&ssl_ca=/path/to/cart.(crt|pem)]')。
连接字符串语法:
DATABASE_URL=mysql://[[user]:[password]@]host[:port][/database]
如果密码包含特殊字符,则需要使用百分号编码。
!
#
$
%
&
'
(
)
*
+
,
/
:
;
=
?
@
[
]
%21
%23
%24
%25
%26
%27
%28
%29
%2A
%2B
%2C
%2F
%3A
%3B
%3D
%3F
%40
%5B
%5D
完整的代码列表可以在 Wikipedia 的百分号编码页面上找到。

使用 Docker 的示例

# 启动 mysql 容器
docker run --name mysql --net <some-docker-network>\
-e MYSQL_ROOT_PASSWORD=<my-secret-pw>\
-e MYSQL_DATABASE=vaultwarden\
-e MYSQL_USER=<vaultwarden_user>\
-e MYSQL_PASSWORD=<vaultwarden_pw> -d mysql:5.7
# 使用 MySQL 环境变量值启动 vaultwarden
docker run -d --name vaultwarden --net <some-docker-network>\
-v $(pwd)/vw-data/:/data/ -v <Path to ssl certs>:/ssl/\
-p 443:80 -e ROCKET_TLS='{certs="/ssl/<your ssl cert>",key="/ssl/<your ssl key>"}'\
-e RUST_BACKTRACE=1 -e DATABASE_URL='mysql://<vaultwarden_user>:<vaultwarden_pw>@mysql/vaultwarden'\
-e ADMIN_TOKEN=<some_random_token_as_per_above_explanation>\
-e ENABLE_DB_WAL='false' <you vaultwarden image name>

使用非 Docker MySQL 服务器的示例

Server IP/Port 192.168.1.10:3306 UN: dbuser / PW: yourpassword / DB: vaultwarden
mysql://dbuser:[email protected]:3306/vaultwarden

使用 docker-compose 的示例

version: "3.7"
services:
mariadb:
image: "mariadb"
container_name: "mariadb"
hostname: "mariadb"
restart: always
env_file:
- ".env"
volumes:
- "mariadb_vol:/var/lib/mysql"
- "/etc/localtime:/etc/localtime:ro"
environment:
- "MYSQL_ROOT_PASSWORD=<my-secret-pw>"
- "MYSQL_PASSWORD=<vaultwarden_pw>"
- "MYSQL_DATABASE=vaultwarden_db"
- "MYSQL_USER=<vaultwarden_user>"
vaultwarden:
image: "vaultwarden/server-mysql:latest"
container_name: "vaultwarden"
hostname: "vaultwarden"
restart: always
env_file:
- ".env"
volumes:
- "vaultwarden_vol:/data/"
environment:
## 当在 mysql URL 周围使用单括号时会出现问题,就像在普通的 docker 例子中的一样
- "DATABASE_URL=mysql://<vaultwarden_user>:<vaultwarden_pw>@mariadb/vaultwarden_db"
- "ADMIN_TOKEN=<some_random_token_as_per_above_explanation>"
- "RUST_BACKTRACE=1"
ports:
- "80:80"
volumes:
vaultwarden_vol:
mariadb_vol:

手动创建数据库(例如,使用现有的数据库服务器)

要执行这些查询,您需要有一个可以创建新数据库和用户的用户。大多数情况下,这将是 root 用户,但根据您的数据库可能会有所不同。
使用上面的 docker-compose 示例使这些步骤变得不必要。数据库、排序规则和字符集在启动时将被自动创建。

创建数据库和用户

1、为 Vaultwarden 创建一个新的(空)数据库(确保字符集和排序规则正确!):
CREATE DATABASE vaultwarden CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2a、创建一个新的数据库用户并授予数据库权限(对于 MariaDB,版本低于 v8 的 MySQL):
CREATE USER 'vaultwarden'@'localhost' IDENTIFIED BY 'yourpassword';
GRANT ALL ON `vaultwarden`.* TO 'vaultwarden'@'localhost';
FLUSH PRIVILEGES;
2b、如果使用 MySQL v8.x,则需要这样创建用户:
-- 在 MySQLv8 安装上这样使用
CREATE USER 'vaultwarden'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword';
GRANT ALL ON `vaultwarden`.* TO 'vaultwarden'@'localhost';
FLUSH PRIVILEGES;
如果您已经创建了用户,想要更改密码类型:
-- 密码类型由 caching_sha2_password 更改未原生
ALTER USER 'vaultwarden'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword';
您可能想尝试一组受限的授权:
GRANT ALTER, CREATE, DELETE, DROP, INDEX, INSERT, SELECT, UPDATE ON `vaultwarden`.* TO 'vaultwarden'@'localhost';
FLUSH PRIVILEGES;

从 SQLite 迁移到 MySQL

话题评论中描述了一种从 SQLite 迁移到 MySQL 的简单方法。下面重复这些步骤。请注意,使用此方法风险自负,强烈建议备份您的安装和数据!
1、首先遵循上面的步骤 1 和步骤 2。
2、配置 Vaultwarden 并启动它,以便 diesel 可以运行迁移并正确设置模式。除此之外不要做别的。
3、停止 Vaultwarden。
4、使用下面的命令转储您现有的 SQLite 数据库。再次检查您的 sqlite 数据库的名称,默认应该是 db.sqlite
注意:在您的 Linux 系统上需要已经安装了 sqlite3 命令。
我们需要从 sqlite 转储的输出中移除一些查询,如创建表等,我们将在这里进行。
您可以使用以下单行命令:
sqlite3 db.sqlite3 .dump | grep "^INSERT INTO" | grep -v "__diesel_schema_migrations" > sqlitedump.sql ; echo -ne "SET FOREIGN_KEY_CHECKS=0;\n$(cat sqlitedump.sql)" > mysqldump.sql
或者逐行运行下列命令:
sqlite3 db.sqlite3 .dump | grep "^INSERT INTO" | grep -v "__diesel_schema_migrations" > sqlitedump.sql
echo "SET FOREIGN_KEY_CHECKS=0;" > mysqldump.sql
cat sqlitedump.sql >> mysqldump.sql
5、加载 MySQL 转储:
mysql --force --password --user=vaultwarden --database=vaultwarden < mysqldump.sql
6、重新启动 Vaultwarden。
注意:使用 --show-warnings 加载 MySQL 转储时,会突出显示 datetime 字段在导入期间被截断了,这似乎也不会有问题。
Note (Code 1265): Data truncated for column 'created_at' at row 1
Note (Code 1265): Data truncated for column 'updated_at' at row 1
注意 1:加载 mysqldump.sql 数据过程中出现加载错误
error (1064): Syntax error near '"users" VALUES('9b5c2d13-8c4f-47e9-bd94-f0d7036ff581'*********)
修复:
sed -i s#\"#\#g mysqldump.sql
mysql --password --user=vaultwarden
use vaultwarden
source /vw-data/mysqldump.sql
exit
注意 2:如果 SQLite 数据库是从以前的某个旧版本迁移而来 ,MariaDB 可能会提示不匹配的值计数,例如:
ERROR 1136 (21S01) at line ###: Column count doesn't match value count at row 1
由于版本跳转,可能添加了新的数据库列。首先使用 SQLite 后端升级 Vaultwarden 以在 SQLite 数据库上运行迁移,切换到 MariaDB 后端,然后重复上述迁移步骤。或者,查找自您安装的版本以来添加迁移的提交并使用 sqlite3 手动运行迁移。

外键错误、排列规则和字符集

由于密码库中存储的某些数据是二进制或纯文本(如邮件地址、用户名或组织名称),其中可能包含 Unicode 字符,因此您需要确保正确设置数据库和表的排序规则和字符集。如果不是这种情况,则可能会在更新期间导致问题,然后生成诸如 Cannot add or update a child row: a foreign key constraint fails ...(无法添加或更新子行:外键约束失败...)或 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126.(行大小太大。所用表类型的最大行大小(不包括 BLOB)为 8126。)之类的消息。
要解决此问题,您需要更新/更改整个数据库及其包含的表的排序规则和字符集。您可以通过您喜欢的 SQL 工具或使用 CLI 跟踪和执行以下设置来完成此操作。
在下面的示例中,我将使用数据库名称 vaultwarden,如果您使用不同的名称,请更改它。
在开始之前,通过运行以下两个查询来验证是否存在任何问题。它应该返回 utf8mb4utf8mb4_unicode_ci
同样要在下面的查询末尾运行这些查询以验证它是否有效!
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = "vaultwarden";
SELECT CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = "vaultwarden" AND CHARACTER_SET_NAME IS NOT NULL;
首先更改数据库本身的排序规则和字符集:
ALTER DATABASE `vaultwarden` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
然后转换所有表(包括文本字段)。执行以下命令,并复制输出:
SELECT CONCAT('ALTER TABLE `', TABLE_NAME,'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;') AS CharSetConvert
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="vaultwarden"
AND TABLE_TYPE="BASE TABLE";
这将生成几个查询,您需要执行这些查询来转换这些表的排序规则和字符集。为了使这些更改生效,我们需要暂时禁用外键检查。将上面查询生成的输出复制/粘贴到以下行的中间:
SET foreign_key_checks = 0;
-- 复制/粘贴上面的输出内容到这里
SET foreign_key_checks = 1;
最后,它看起来应该类似于以下内容(但根据数据库结构的更新或更改,可能会有所不同):
SET foreign_key_checks = 0;
ALTER TABLE `__diesel_schema_migrations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `attachments` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `ciphers_collections` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `ciphers` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `collections` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `devices` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `emergency_access` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `favorites` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `folders_ciphers` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `folders` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `invitations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `org_policies` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `organizations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `sends` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `twofactor_incomplete` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `twofactor` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `users_collections` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `users_organizations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `users` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SET foreign_key_checks = 1;
您需要运行这些查询以将它们转换为正确的排序规则和字符集。您可以通过对至少一张表运行以下查询来验证它是否有效:
SHOW CREATE TABLE `users`;
它应该输出如下,注意最后的 CHARSET=utf8mb4
CREATE TABLE `users` (
`uuid` char(36) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`email` varchar(255) NOT NULL,
`name` text NOT NULL,
--- CUT ---
`enabled` tinyint(1) NOT NULL DEFAULT 1,
`stamp_exception` text DEFAULT NULL,
PRIMARY KEY (`uuid`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
您可以对数据库执行相同的操作:
SHOW CREATE DATABASE `vaultwarden`;
它应该看起来像这样,注意 DEFAULT CHARACTER SET utf8mb4
CREATE DATABASE `vaultwarden` /*!40100 DEFAULT CHARACTER SET utf8mb4 */