Teampass 3.2.3.2 Docker Compose 部署指南
Teampass 3.2.3.2 Docker Compose 部署指南:应用与 MySQL 8.0 双服务编排、安装向导 6 步全程实测(含 CSRF 驱动与 84 表建表回执)、数据持久化与备份恢复、环境变量表、等价 docker run 与运维命令,附安装器缺表、维护模式、口令策略等 8 个实测 FAQ。
Teampass 3.2.3.2 Docker Compose 部署指南
目标:从零完成 Teampass 3.2.3.2 团队密码保管库的双服务编排部署(应用 + MySQL 8.0),走完安装向导全部 6 步并完成管理员账号初始化、普通用户创建与权限矩阵配置,最终得到一个可登录、可建条目、可按角色授权的生产可用实例。已在 Ubuntu 宿主机(内核 6.8.0-138-generic、Docker 29.8.1、Docker Compose v5.5.1)实测通过,全流程命令与回显均为真实执行记录。
一、环境信息
本次实测部署的环境基线如下(均为宿主机实查回显):
| 项目 | 值 | 来源 |
|---|---|---|
| 宿主机内核 | 6.8.0-138-generic | uname -r 实查 |
| Docker | 29.8.1, build 4a63305 | docker --version 实查 |
| Docker Compose | v5.5.1 | docker compose version 实查 |
| Teampass 版本 | 3.2.3.2(TP_VERSION 3.2.3 + TP_VERSION_MINOR 2) | 镜像常量实查 |
| 应用镜像 | teampass/teampass:3.2.3.2(737MB) | docker images 实查 |
| 数据库镜像 | mysql:8.0(1.1GB,服务端版本 8.0.46) | docker images 实查 |
| 应用内 PHP | 8.3.35(NTS) | 容器内 php -v 实查 |
| 应用端口 | 宿主机 8144 → 应用 80 | compose 映射实查 |
| 自定义网络 | teampass-3232-net(bridge,子网 10.89.70.0/24) | compose 定义实查 |
| 数据卷 | teampass-db(MySQL 数据)、teampass-html(应用全量目录) | compose 定义实查 |
Teampass 3.2.3.2 是官方明确推荐用于全新安装的版本(GitHub Release Notes 原文「3.2.3.2 is the version to use for any new installation」,发布于 2026-10-20)。版本背景与选型对比见《Teampass 3.2.3.2 介绍与选型指南》。
二、镜像选型说明
2.1 应用镜像
Teampass 官方在 Docker Hub 发布 teampass/teampass 镜像,本次实测选择固定版本 tag teampass/teampass:3.2.3.2,理由如下:
- 版本可追溯:该 tag 对应 GitHub 仓库
nilsteampassnet/TeamPass的 3.2.3.2 发布版,镜像内 PHP 常量TP_VERSION='3.2.3'、TP_VERSION_MINOR='2'实查一致; - 不要用 latest 部署生产:实测比对发现
latesttag 与 3.2.3.2 tag 的 manifest digest 不同——latest指向 master 分支的滚动构建,包含未发布改动,部署后出现的问题无法对应到任何官方发布版本,排障无从溯源; - 镜像内自带 PHP 8.3.35 运行时、nginx(php-fpm 由 nginx 用户运行)与
docker-entrypoint.sh引导脚本,无需自建 Dockerfile。
镜像 tag 清单可通过 Docker Hub API 实查(实测共 401 个 tag,包含 3.2.3.2 与 latest 等),拉取前建议先核对目标 tag 存在。
2.2 数据库镜像
选择 mysql:8.0 官方镜像(服务端 8.0.46 实查)。Teampass 3.2 线要求数据表全部为 InnoDB 且字符集 utf8mb4,compose 中通过启动参数显式指定 --character-set-server=utf8mb4 与 --collation-server=utf8mb4_unicode_ci 保证新库默认值正确。MariaDB 10.7+ 亦可作为数据库(官方要求),但 MySQL 8.0 与安装向导的兼容验证最直接。
2.3 镜像拉取
国内网络环境建议先配置可用的镜像加速地址再拉取;拉取后核对本地镜像:
docker pull mysql:8.0
docker pull teampass/teampass:3.2.3.2
docker images | grep -E 'teampass|mysql:8.0'
实测回显:
teampass/teampass:3.2.3.2 737MB
mysql:8.0 1.1GB
三、前置条件
- 服务器已安装 Docker 29.x 与 Compose 插件(
docker compose version可正常返回); - 端口规划:应用对外端口需未被占用(本次用 8144),确认方式
ss -tlnp | grep 8144无输出; - 子网规划:自定义 bridge 网络显式指定子网,避免与既有网段冲突(本次用 10.89.70.0/24,创建前用
docker network ls与docker network inspect确认未占用); - 数据落盘目录:编排文件与过程资料统一放在
/opt/data/quzuo/tmp/teampass/stack/(生产环境按自身目录规范放置即可); - 数据库口令:预先确定 MySQL root 与业务账号口令。Teampass 安装向导第 4 步对管理员口令有强度要求(实测规则:≥10 位、必须同时包含大小写字母与数字/特殊字符,
q1w2e3r4这类弱口令会被拒绝,详见 FAQ); - 浏览器或 curl:安装向导既可用浏览器逐步完成,也可全程 curl 驱动(本文以 curl 驱动实录)。
四、部署步骤
4.1 编排文件
创建 /opt/data/quzuo/tmp/teampass/stack/docker-compose.yml:
name: teampass-3.2.3.2-stack
services:
db:
image: mysql:8.0
container_name: teampass-3.2.3.2-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: q1w2e3r4
MYSQL_DATABASE: teampass
MYSQL_USER: teampass
MYSQL_PASSWORD: q1w2e3r4
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
volumes:
- teampass-db:/var/lib/mysql
networks:
- tpnet
teampass:
image: teampass/teampass:3.2.3.2
container_name: teampass-3.2.3.2-web
restart: unless-stopped
depends_on:
- db
ports:
- "8144:80"
volumes:
- teampass-html:/var/www/html
networks:
- tpnet
volumes:
teampass-db:
teampass-html:
networks:
tpnet:
driver: bridge
name: teampass-3232-net
ipam:
config:
- subnet: 10.89.70.0/24
要点说明:
- 应用侧数据卷
teampass-html挂载整个/var/www/html。不要只挂载空目录到/var/www/html——bind mount 一个空宿主目录会把镜像内全部应用文件盖住,导致启动即白屏;命名卷首次挂载时会先拷入镜像内容,行为正确; depends_on: - db保证启动顺序,镜像 entrypoint 自带 30 次 × 2 秒的数据库就绪等待循环,双保险;- compose 项目名
teampass-3.2.3.2-stack中的点号会被规范化剥掉,数据卷实际前缀为teampass-3232-stack_(实测卷名teampass-3232-stack_teampass-html),属正常现象。
4.2 启动与就绪确认
cd /opt/data/quzuo/tmp/teampass/stack
docker compose up -d
docker compose ps
实测回显(应用健康检查通过后):
teampass-3.2.3.2-db Up 39 minutes 3306/tcp, 33060/tcp
teampass-3.2.3.2-web Up 34 minutes (healthy) 9000/tcp, 0.0.0.0:8144->80/tcp
HTTP 层验证:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8144/index.php
实测返回 200。
4.3 安装向导总览
首次访问 http://<服务器IP>:8144/ 会 302 到 install/install.php 安装向导,共 6 步:路径确认 → 环境检查 → 数据库连接 → 管理员账号 → 建表 → 收尾动作。向导接口全部要求 CSRF 令牌(响应头/页面内 csrf-token meta,请求头 X-CSRF-Token),实测令牌为 64 位十六进制串。以下全部步骤在宿主机用 curl 驱动,cookie 与令牌贯穿全程。
4.4 第 1 步:路径确认
BASE=http://127.0.0.1:8144
CK=/opt/data/quzuo/tmp/teampass/ck.txt
CSRF=$(curl -s -c $CK $BASE/install/install.php | grep -oP 'csrf-token" content="\K[a-f0-9]+')
echo ${#CSRF} # 实测 64
curl -s -b $CK -H "X-CSRF-Token: $CSRF" $BASE/install/install-steps/run.step1.php \
-d "absolutePath=/var/www/html/public" \
-d "urlPath=http://192.168.146.128:8144/"
实测回显:
{"success":true,"message":"<i class=\"fa-solid fa-check\"><\/i> Done"}
urlPath 要写成用户实际访问的应用 URL(含协议、IP/域名与端口),它会被写入站点设置 cpassman_url,后续邮件通知、附件链接等都基于它。
4.5 第 2 步:环境检查
逐项调用 run.step2.php,检查目录可写、PHP 扩展与运行参数:
step2() { curl -s -b $CK -H "X-CSRF-Token: $CSRF" $BASE/install/install-steps/run.step2.php "$@"; echo; }
step2 -d type=directory -d path=/var/www/html/app/config/
step2 -d type=directory -d path=/var/www/html/app/includes/libraries/csrfp/libs/
step2 -d type=directory -d path=/var/www/html/storage/files/
step2 -d type=extension -d name=mbstring
step2 -d type=extension -d name=openssl
step2 -d type=php_version -d version=
step2 -d type=execution_time -d limit=30
实测回显(核心项全部 {"success":true};可选项 posix/opcache/php_fpm 通过,pcntl/apcu/redis 为 false,均为可选能力不影响安装)。官方镜像的目录权限与扩展已预置到位,全部目录检查与必需扩展(mbstring/openssl/bcmath/xml/curl)一次通过。
4.6 第 3 步:数据库连接
curl -s -b $CK -H "X-CSRF-Token: $CSRF" $BASE/install/install-steps/run.step3.php \
-d "dbHost=db" -d "dbName=teampass" -d "dbLogin=teampass" -d "dbPw=q1w2e3r4" \
-d "dbPort=3306" -d "tablePrefix=teampass_" \
-d "teampassAbsolutePath=/var/www/html/public" \
-d "teampassUrl=http://192.168.146.128:8144/"
实测回显:
{"success":true,"message":"<i class=\"fa-solid fa-check\"><\/i> Done"}
dbHost 填 compose 服务名 db(同网络内 DNS 解析),数据库与账号由 compose 环境变量 MYSQL_DATABASE/MYSQL_USER/MYSQL_PASSWORD 预建。
4.7 第 4 步:管理员账号
curl -s -b $CK -H "X-CSRF-Token: $CSRF" $BASE/install/install-steps/run.step4.php \
-d "adminPassword=q1w2E3R4T5" -d "adminEmail=admin@example.com" \
-d "adminName=admin" -d "adminLastname=User" \
-d "dbHost=db" -d "dbName=teampass" -d "dbLogin=teampass" -d "dbPw=q1w2e3r4" \
-d "dbPort=3306" -d "tablePrefix=teampass_"
实测回显:
{"success":true,"message":"<i class=\"fa-solid fa-check\"><\/i> Done"}
注意:首次实测用 q1w2e3r4 被向导拒绝(口令策略要求 ≥10 位且含大小写与数字/特殊字符),改用 10 位混合口令后通过。
4.8 第 5 步:建表
run.step5.php 按动作逐个建表/执行迁移,实测全部 84 个动作一次通过(OK=84 FAIL=0),包括 utf8 迁移、InnoDB 引擎设定,以及 items/users/roles/rights/sharekeys/log_items/log_system/auth_failures/background_tasks/webauthn 等全部业务表:
for a in utf8 migrateToUtf8mb4 checkAndSetInnoDBEngine api automatic_del cache cache_tree \
categories categories_folders categories_items defuse_passwords emails export files \
items items_change items_edition items_otp kb kb_categories kb_items kb_comments \
kb_edition ldap_groups_roles languages log_items log_system misc nested_tree \
notification otv background_tasks background_subtasks background_tasks_logs \
restriction_to_roles rights roles_title roles_values sharekeys_fields sharekeys_files \
sharekeys_items sharekeys_logs sharekeys_suggestions suggestion tags templates tokens \
users auth_failures items_importations user_private_keys users_groups \
users_groups_forbidden users_roles users_favorites users_latest_items \
users_options_favorites encryption_migration_stats websocket_events \
websocket_connections websocket_tokens network_acl items_corruption api_tokens \
api_sessions api_rate_limit import_tracking item_health user_nudges rotation_flags \
access_reviews access_review_items data_classification user_notifications \
emails_templates lapr_endpoints lapr_accounts lapr_policies lapr_audit_log \
lapr_rate_limit items_revisions api_idempotency webauthn_credentials sharekeys_webauthn; do
curl -s -b $CK -H "X-CSRF-Token: $CSRF" $BASE/install/install-steps/run.step5.php \
-d "action=$a" -d "dbHost=db" -d "dbName=teampass" -d "dbLogin=teampass" \
-d "dbPw=q1w2e3r4" -d "dbPort=3306" -d "tablePrefix=teampass_" | grep -o '"success":true' \
|| echo "FAILED: $a"
done
实测 84 个动作无任何 FAILED 输出。建表后登录数据库核验:
docker exec teampass-3.2.3.2-db mysql -uteampass -pq1w2e3r4 teampass \
-e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='teampass';"
实测返回 85(84 张业务表 + 系统自动生成的 1 张)。
4.9 第 6 步:收尾动作
依次执行 6 个收尾动作,全部返回 {"success":true,"message":"<i class=\"fa-solid fa-check\"><\/i> Done"}:
| 动作 | 作用(实测效果) |
|---|---|
| secureFile | 在 secrets/ 下生成随机文件名(SECUREFILE)的 Defuse 主密钥文件 |
| chmod | 收紧 storage/ 与 secrets/ 目录权限 |
| settingsFile | 生成 settings.php(数据库连接信息,DB 口令为密文) |
| csrf | 生成 CSRF 防护配置 csrfp.config.php |
| cronJob | 写入定时任务配置 |
| cleanInstall | 标记安装完成 |
for a in secureFile chmod settingsFile csrf cronJob cleanInstall; do
curl -s -b $CK -H "X-CSRF-Token: $CSRF" $BASE/install/install-steps/run.step6.php \
-d "action=$a" -d "dbHost=db" -d "dbName=teampass" -d "dbLogin=teampass" \
-d "dbPw=q1w2e3r4" -d "dbPort=3306" -d "tablePrefix=teampass_"; echo
done
4.10 安装后验证
安装完成后访问 http://<服务器IP>:8144/ 进入登录页,用第 4.7 节创建的管理员账号登录。登录成功即代表安装闭环。首次进入系统后有两个必做动作(均为实测结论):
- 关闭维护模式:全新安装默认
maintenance_mode=1,非管理员用户登录会被拒绝(错误提示maintenance_mode_enabled)。管理员进入后台设置把维护模式关闭后普通用户方可登录; - 确认站点 URL:后台设置中的站点 URL 应与实际访问地址一致(第 4.4 步写入的
cpassman_url)。
完成一个最小权限模型验证(实测全过程):
- 创建角色「运维组」,把角色对目标文件夹授写权限(授权接口回执
{"error":false,"message":""}); - 创建普通用户挂到该角色(创建成功后接口回执返回自动生成口令);
- 该用户登录后可在授权文件夹内新建条目(回执
{"error":false,"item_id":1,"encryption_task_created":true}),尝试在根目录建文件夹被拒(回执{"error":true,"message":"Folder is not allowed for this user"}),尝试在授权文件夹下建子文件夹亦被拒(回执{"error":true,"message":"You are not allowed to do that!"})——证明写权限只覆盖条目增删改,不含文件夹结构变更。
五、数据持久化说明
5.1 数据落点全景
Teampass 的持久化数据分布在三个层面,实测清单如下:
| 数据 | 落点 | 持久化载体 |
|---|---|---|
| 全部密码条目密文、用户、角色、审计日志 | MySQL 库 teampass(85 张表) | 命名卷 teampass-db → /var/lib/mysql |
| 应用代码 + 配置 + 上传附件 + 附件密钥 | /var/www/html 整目录 | 命名卷 teampass-html |
| Defuse 主密钥文件 | /var/www/html/secrets/<随机名>(0600,目录 0700) | 随 teampass-html 卷持久化(镜像另对其声明独立卷) |
| settings.php 与 csrfp.config.php | /var/www/html/storage/config/(应用路径经符号链接指向) | 随 teampass-html 卷持久化 |
5.2 安装产物的符号链接持久化机制
官方镜像 entrypoint 对安装向导产物做了显式的持久化处理(脚本内注释与实测文件属性一致):app/config/settings.php 与 app/includes/libraries/csrfp/libs/csrfp.config.php 在应用路径上是符号链接,实体文件位于 storage/config/。这样安装向导无论写到哪个路径,最终都落在数据卷上,容器重建(docker compose down && up)后不会触发重新安装。实测验证:storage/config/ 下确有 settings.php(1048 字节)与 csrfp.config.php(1192 字节),属主 nginx:nginx、权限 0640。
5.3 备份方法
# 数据库备份
docker exec teampass-3.2.3.2-db sh -c \
'exec mysqldump -uteampass -p"q1w2e3r4" teampass' > /opt/data/quzuo/tmp/teampass/tp_db_$(date +%F).sql
# 应用目录(含配置与 secrets)备份
docker run --rm -v teampass-3232-stack_teampass-html:/src:ro -v /opt/data/quzuo/tmp/teampass:/dst \
alpine tar czf /dst/tp_html_$(date +%F).tgz -C /src .
恢复 = 先恢复数据库再恢复应用目录卷;两者必须成对恢复,因为数据库中的 Defuse 密文依赖 secrets/ 主密钥文件解密,配置文件中的数据库口令密文依赖同一密钥,错配将导致无法解密。
5.4 升级时的卷保留
docker compose pull && docker compose up -d 会重建应用服务但保留两个命名卷;镜像 entrypoint 内置数据库版本比对逻辑(读取 teampass_misc 表中的 teampass_version 与 upgrade_timestamp,低于镜像携带的 schema 底线则自动执行升级迁移),升级路径无需手工介入。
六、环境变量表
官方镜像 docker-entrypoint.sh 实查支持的运行时环境变量如下:
| 变量 | 默认值 | 说明 |
|---|---|---|
DB_HOST | db | 数据库主机(compose 服务名) |
DB_PORT | 3306 | 数据库端口 |
DB_NAME | teampass | 数据库名 |
DB_USER | teampass | 业务数据库账号 |
DB_PASSWORD | 空 | 业务数据库口令(entrypoint 用于就绪等待与升级辅助连接) |
DB_PREFIX | teampass_ | 数据表前缀 |
TEAMPASS_URL | http://localhost | 站点对外 URL(entrypoint 启动横幅显示用) |
PHP_MEMORY_LIMIT | 512M | PHP 内存上限(entrypoint 写入 conf.d 覆盖文件) |
PHP_UPLOAD_MAX_FILESIZE | 100M | 上传文件上限 |
PHP_POST_MAX_SIZE | 同上传上限 | POST 请求体上限 |
PHP_MAX_EXECUTION_TIME | 120 | 脚本最大执行时间(秒) |
注意两点(脚本实查):一是这些变量不直接预写 settings.php——安装向导才是数据库连接信息的写入方,环境变量主要用于就绪检测、PHP 运行参数与升级辅助;二是 PHP_* 四项通过生成 /usr/local/etc/php/conf.d/teampass-env.ini 生效,改完需重建容器。
MySQL 侧环境变量(MYSQL_ROOT_PASSWORD/MYSQL_DATABASE/MYSQL_USER/MYSQL_PASSWORD)为 mysql 官方镜像标准变量,仅在数据卷首次初始化时生效;卷已存在时改这些变量不会改动已建库与口令。
七、配置参数说明
部署阶段涉及的参数分三层,逐层说明:
- 编排层参数(4.1 节 compose 文件):端口映射、数据卷、子网、字符集启动参数。子网必须显式指定(实测宿主机已有多个 10.89.x.0/24 段的网络,随机分配易冲突);
- 安装向导参数(4.4~4.9 节):站点绝对路径与 URL、数据库五项连接参数、表前缀、管理员四项信息。这些参数在安装完成后分别落在
settings.php(数据库连接、cpassman_url等)与数据库teampass_misc表(站点设置全集 294 项); - 运行层参数(第六节环境变量表 + PHP conf.d):内存、上传、执行时间。
安装后如需调整站点行为(密码复杂度、会话时长、双因素策略、附件加密开关等),在管理员后台设置界面修改即可,全部变更实时写库生效(实测:修改 clipboard_life_duration 30→60 后,数据库 teampass_misc 表 valeur 字段立即变为 60)。参数全集逐项详解见《Teampass 3.2.3.2 配置参数详解》同专栏续篇;安全相关参数的加固用法见《Teampass 3.2.3.2 安全加固指南》(同专栏)。
八、配置文件挂载
8.1 需要关注的配置文件清单(容器内实查)
| 文件 | 权限/属主 | 作用 |
|---|---|---|
/var/www/html/storage/config/settings.php | 0640 nginx:nginx | 数据库连接(DB_HOST/DB_USER/DB_PASSWD/DB_NAME/DB_PREFIX/DB_PORT/DB_ENCODING 等),数据库口令为 Defuse 密文(def50200... 前缀),非明文 |
/var/www/html/storage/config/csrfp.config.php | 0640 nginx:nginx | CSRF 防护配置 |
/var/www/html/secrets/<随机名> | 0600 nginx:nginx,目录 0700 | Defuse 加密主密钥,文件名即 settings.php 中 SECUREFILE 常量值 |
/usr/local/etc/php/conf.d/teampass-env.ini | 镜像生成 | entrypoint 按 PHP_* 环境变量生成的 PHP 覆盖配置 |
8.2 挂载建议
- 本文 compose 直接用命名卷
teampass-html挂整个/var/www/html,上述配置文件全部随卷持久化,无需单独挂载条目; - 若希望配置与应用代码分离管理,可追加挂载:
- ./config:/var/www/html/storage/config(覆盖命名卷内同路径),但注意宿主目录属主需与容器内 nginx 用户 uid 匹配,否则安装向导写入 settings.php 时会失败(镜像 issue #5238 即此类属主问题); secrets/目录安全等级最高(0700/0600),生产环境建议独立卷并纳入备份(5.3 节)。
九、等价 docker run
不用 Compose 时,以下三条命令与 4.1 节编排等价(按序执行):
# 1. 自定义网络(显式子网)
docker network create --driver bridge --subnet 10.89.70.0/24 teampass-3232-net
# 2. 数据库
docker run -d --name teampass-3.2.3.2-db --restart unless-stopped \
--network teampass-3232-net \
-e MYSQL_ROOT_PASSWORD=q1w2e3r4 \
-e MYSQL_DATABASE=teampass \
-e MYSQL_USER=teampass \
-e MYSQL_PASSWORD=q1w2e3r4 \
-v teampass-db:/var/lib/mysql \
mysql:8.0 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# 3. 应用
docker run -d --name teampass-3.2.3.2-web --restart unless-stopped \
--network teampass-3232-net \
-p 8144:80 \
-v teampass-html:/var/www/html \
teampass/teampass:3.2.3.2
后续安装向导步骤与 4.3~4.10 节完全一致。日常管理推荐 Compose(docker compose ps/logs/stop/up -d 一组命令覆盖全部服务)。
十、常用运维命令
cd /opt/data/quzuo/tmp/teampass/stack
# 状态与健康检查
docker compose ps
docker inspect --format '{{.State.Health.Status}}' teampass-3.2.3.2-web
# 日志跟踪(应用引导横幅含版本号与数据库等待过程)
docker compose logs -f teampass
docker compose logs --tail 100 db
# 重启单个服务 / 全部服务
docker compose restart teampass
docker compose down # 停止并移除容器,数据卷保留
docker compose up -d # 重新拉起,数据完整保留
# 版本核对
docker exec teampass-3.2.3.2-web grep -E "TP_VERSION" /var/www/html/app/config/include.php
# 直连数据库排查
docker exec -it teampass-3.2.3.2-db mysql -uteampass -pq1w2e3r4 teampass
# 应用目录内执行 PHP(如命令行维护脚本)
docker exec teampass-3.2.3.2-web php /var/www/html/app/scripts/read-db-version.php
实测补充:服务器重启后 restart: unless-stopped 的服务会自动拉起;若以 Exited 状态存在,docker start teampass-3.2.3.2-db teampass-3.2.3.2-web 即可,数据无损。
十一、常见问题
Q1:拉取的 latest 镜像装出来的版本号和官方 3.2.3.2 对不上?
实测 latest 与 3.2.3.2 两个 tag 的 manifest digest 不同——latest 是 master 分支滚动构建。生产部署一律用固定版本 tag,核对方法:启动后 docker exec teampass-3.2.3.2-web grep -E "TP_VERSION" /var/www/html/app/config/include.php,应看到 3.2.3 与 2 两个常量。
Q2:安装向导第 5 步某动作返回 500,提示缺表 teampass_user_webauthn_credentials?
3.2.3.2 安装器存在遗漏:建表清单不含该表,而后续创建用户等功能的代码会查询它(实测 add_new_user 接口 500,错误栈指向该表不存在)。修复方法为手工补建,实测建表语句如下(列集从代码中该表的 INSERT/UPDATE/SELECT 语句反推):
CREATE TABLE IF NOT EXISTS teampass_user_webauthn_credentials (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT NOT NULL,
credential_id VARBINARY(1024) NOT NULL,
rp_id VARCHAR(255) NOT NULL,
public_key_cose MEDIUMBLOB NOT NULL,
sign_count BIGINT NOT NULL DEFAULT 0,
aaguid VARCHAR(64) DEFAULT NULL,
transports VARCHAR(255) DEFAULT NULL,
label VARCHAR(255) DEFAULT NULL,
key_wrap_mode VARCHAR(32) NOT NULL DEFAULT 'wrapped',
wrapped_private_key MEDIUMBLOB DEFAULT NULL,
wrap_salt VARBINARY(64) DEFAULT NULL,
backup_eligible TINYINT(1) NOT NULL DEFAULT 0,
backup_state TINYINT(1) NOT NULL DEFAULT 0,
created_at VARCHAR(50) DEFAULT NULL,
last_used_at VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (id),
KEY user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
补建后重新执行失败的动作即可继续。
Q3:管理员口令 q1w2e3r4 在安装第 4 步被拒?
实测口令策略:长度 ≥10、必须同时包含大写字母、小写字母与数字/特殊字符。换 q1w2E3R4T5 这类 10 位混合口令可通过。该策略同样作用于后台自建用户的口令修改。
Q4:安装完成、管理员能登录,普通用户登录却报 maintenance_mode_enabled?
全新安装默认开启维护模式(teampass_misc 表 maintenance_mode=1),仅管理员可登录。管理员在后台设置中关闭维护模式后普通用户即可登录(实测关闭接口回执 {"error":false,"misc":"1 ; 0"},即 1 改 0)。
Q5:删除过的用户名无法重新创建,提示 "User already exists"?
Teampass 的用户删除是软删除(login 改名 <原用户名>_deleted_<时间戳>、置 disabled),且创建用户时的重名校验会同时匹配软删除记录,因此同名用户不能直接重建,官方设计是走「恢复用户」。若确需重建(如测试环境),需清理数据库残留:删除 teampass_users 中该用户行,并同步清理 teampass_user_private_keys、teampass_users_roles、teampass_api 等表中 user_id 指向该用户的行(实测仅清 users 表仍会因残留密钥行报错)。
Q6:文件夹/条目的密码复杂度设置哪些值合法?
复杂度档位是固定枚举(对应枚举值 0/20/38/48/60 五档),传其他值(实测传 64)后端报 Undefined array key 64。后台文件夹编辑界面里只有这五档可选;数据库 teampass_misc 表 type=complex 的行记录了档位定义。
Q7:普通用户对文件夹有写权限,为什么还是不能建子文件夹?
实测权限模型:角色-文件夹的写授权(W)覆盖条目的增删改查,不含文件夹结构变更(建子文件夹被拒,回执 "You are not allowed to do that!"),根目录建文件夹另需 can_create_root_folder 能力(实测无此能力的用户建根目录文件夹回执 "Folder is not allowed for this user")。
Q8:把宿主机空目录 bind mount 到 /var/www/html 后应用白屏/404? bind mount 空目录会盖住镜像内的全部应用文件。应用目录必须用命名卷(首次挂载自动拷入镜像内容,见 4.1 节要点),或在宿主目录先备好完整应用文件。
十二、参考链接
- 《Teampass 3.2.3.2 介绍与选型指南》(同专栏,版本背景与选型对比)
- Teampass 官方文档站(Install & requirements / Installing TeamPass):https://documentation.teampass.net
- Teampass 官方代码仓库:https://github.com/nilsteampassnet/TeamPass
- Teampass 官方镜像(Docker Hub):https://hub.docker.com/r/teampass/teampass
- 3.2.3.2 发布说明:https://github.com/nilsteampassnet/TeamPass/releases
- MySQL 8.0 官方镜像文档:https://hub.docker.com/_/mysql
- 同类自托管密码库部署参考:《PassIt 1.25.0 介绍与选型指南》、《Psono v7.5.3 介绍与选型指南》、《AliasVault 0.31.1 介绍与选型指南》