2FAuth 8.0.3 Docker Compose 部署指南
2FAuth 8.0.3 Docker Compose 部署指南:以官方 compose 基准为骨架的实测部署流程,覆盖目录规划、APP_KEY 生成、MySQL 健康检查编排、启动初始化、API 链路验证、备份与升级运维及排障实录。
2FAuth 8.0.3 Docker Compose 部署指南
本文是 2FAuth 专栏的部署篇。以下流程于 2026-10-24 在一台真实 Linux 服务器上按官方 Docker-Compose 基准实测走通:从零建目录、起服务、注册管理员、创建 2FA 账户到 API 验证全链路可用。文中所有命令回显均为实测原文(凭据类字段已脱敏标注),环境为 Docker Compose v2。
选型背景与组件画像见《2FAuth 8.0.3 介绍与选型指南》,本文只解决「怎么把 8.0.3 跑起来」。部署完成后,参数逐项调优见《2FAuth 8.0.3 配置参数详解》,上线前加固清单见《2FAuth 8.0.3 安全加固指南》。
一、部署前决策
镜像与版本锁定:使用官方镜像 2fauth/2fauth:8.0.3(不可变版本标签),不要用 latest——官方文档明确 latest 跟随 master 分支,可能包含未正式发布的修复。数据库选择 MySQL 8.0(官方镜像默认零配置跑 SQLite,单文件在 ./2fauth 卷内;多人使用或需要独立备份周期时建议外挂数据库,本文实测采用 MySQL)。
官方 compose 基准(docs.2fauth.app 原文要点):单服务 2fauth,env_file 指向环境变量文件,卷挂载 ./2fauth:/2fauth,端口 8000:8000,必设环境变量为 APP_KEY(官方强调必须是个人唯一值)。本文在此基准上补齐 MySQL 服务、健康检查与自定义网络。
目录与端口规划(实测布局):
/opt/2fauth/ # 部署根目录
├── docker-compose.yml
├── settings.env # 2FAuth 环境变量(env_file 指向它)
├── 2fauth/ # 应用数据卷(日志、SQLite 场景下的数据库)
└── mysql-data/ # MySQL 数据卷
端口实测采用宿主机 8130 映射容器 8000(8130 为实测时避开宿主机占用的选择,可按需修改)。容器以非 root 的 1000:1000 身份运行(官方镜像约定),数据目录属主需与之匹配。
二、编写 docker-compose.yml
实测全量文件(服务名 app/mysql,项目名 2fauth-8.0.3-stack):
name: 2fauth-8.0.3-stack
services:
app:
image: 2fauth/2fauth:8.0.3
container_name: 2fauth-803-app
restart: unless-stopped
depends_on:
mysql:
condition: service_healthy
env_file: settings.env
ports:
- "8130:8000/tcp"
volumes:
- ./2fauth:/2fauth
mysql:
image: mysql:8.0
container_name: 2fauth-803-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "********" # 脱敏:实测使用独立强口令
MYSQL_DATABASE: 2fauth
MYSQL_USER: 2fauth
MYSQL_PASSWORD: "********" # 脱敏:需与 settings.env 的 DB_PASSWORD 一致
volumes:
- ./mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-p********"]
interval: 5s
timeout: 5s
retries: 30
networks:
default:
name: 2fauth-803-net
三个编排要点(均为实测验证过的行为):
depends_on+condition: service_healthy:2FAuth 首次启动要跑数据库迁移,必须等 MySQL 真正可接受连接。健康检查用mysqladmin ping,实测从启动到 Healthy 约 10 秒内完成;没有这一条,app 会因连不上库而反复重启。env_file: settings.env:应用配置全部走环境变量文件,与官方基准一致;数据库四要素(DB_CONNECTION/DB_DATABASE/DB_HOST/DB_PORT/DB_USERNAME/DB_PASSWORD)在 env 文件中配置,DB_HOST填 compose 服务名mysql。- 数据双卷:
./2fauth:/2fauth存放应用侧数据(日志在2fauth/storage/logs/),./mysql-data存放数据库文件,两者都可独立备份。
宿主机目录权限(官方 Docker 文档要求,容器内进程身份为 1000:1000):
mkdir -p /opt/2fauth/2fauth
chown -R 1000:1000 /opt/2fauth/2fauth
chmod 700 /opt/2fauth/2fauth
三、编写 settings.env
实测文件(敏感值脱敏,完整参数逐项解释见《2FAuth 8.0.3 配置参数详解》):
APP_NAME=2FAuth
APP_ENV=production
APP_TIMEZONE=UTC
APP_DEBUG=false
SITE_OWNER=admin@example.com
APP_KEY=base64:18M+5Xktw…(脱敏:32 字节 base64 键,实测值)
APP_URL=http://127.0.0.1:8130
APP_SUBDIRECTORY=
IS_DEMO_APP=false
LOG_CHANNEL=daily
LOG_LEVEL=notice
CACHE_DRIVER=file
SESSION_DRIVER=file
DB_CONNECTION=mysql
DB_DATABASE=2fauth
DB_HOST=mysql
DB_PORT=3306
DB_USERNAME=2fauth
DB_PASSWORD=********(脱敏:与 compose 中 MYSQL_PASSWORD 一致)
THROTTLE_API=60
THROTTLE_API_DURING_IMPORT=1000
LOGIN_THROTTLE=5
AUTHENTICATION_GUARD=web-guard
WEBAUTHN_NAME=2FAuth
WEBAUTHN_ID=null
WEBAUTHN_USER_VERIFICATION=preferred
TRUSTED_PROXIES=null
PROXY_FOR_OUTGOING_REQUESTS=null
CONTENT_SECURITY_POLICY=true
BLOCK_OPTAUTH_IMAGELINK_FETCHING=true
PHP_MEMORY_LIMIT_TEMP_OVERRIDE=512
MAIL_MAILER=log
APP_KEY 的两种官方生成方式:
# 方式一:借用官方镜像现场生成(推荐, Official Docker 文档原文命令)
docker run -it --rm --entrypoint /usr/bin/php 2fauth/2fauth:8.0.3 artisan key:generate --show
# 方式二:用任意 Laravel Encryption Key Generator 生成 32 字节 base64 键
注意两条官方红线:APP_KEY 必须是个人唯一值,不能照抄任何文档示例;后续如需换钥,把旧钥移入 APP_PREVIOUS_KEYS 以保证存量密文与访问令牌仍可解。
四、启动与初始化(实测实录)
1) 拉起服务:
cd /opt/2fauth && docker compose up -d
实测回显(原文,可看到 healthcheck 门控生效的完整时序):
Container 2fauth-803-mysql Creating
Container 2fauth-803-mysql Created
Container 2fauth-803-app Creating
Container 2fauth-803-app Created
Container 2fauth-803-mysql Starting
Container 2fauth-803-mysql Started
Container 2fauth-803-mysql Waiting
Container 2fauth-803-mysql Healthy
Container 2fauth-803-app Starting
Container 2fauth-803-app Started
Waiting → Healthy → app Starting 三行就是第 2 节健康检查门控的真实效果:app 在 MySQL 通过健康检查后才被拉起。
2) 存活探测:
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8130/
# 200
curl -s http://127.0.0.1:8130/up
# 2FAuth up
/up 返回 2FAuth up 且首页 HTTP 200,说明 PHP-FPM、Nginx、数据库迁移链路全部就绪。
3) 注册首个管理员:浏览器访问 http://<服务器IP>:8130,首次进入即注册流程,注册的第一个用户即为管理员(实测按此完成注册并登录,取得会话 Cookie:2fauth_session、XSRF-TOKEN、laravel_token)。生产环境请立刻按《2FAuth 8.0.3 安全加固指南》关闭开放注册。
4) 建一个 2FA 账户做端到端验证(实测使用标准测试向量 Secret,无生产凭据):
curl -s -X POST http://127.0.0.1:8130/api/v1/twofaccounts \
-H "Authorization: Bearer <你的API令牌>" \
-H "Content-Type: application/json" \
-d '{"otp_type":"totp","service":"GitHub","account":"test@example.com","secret":"JBSWY3DPEHPK3PXP"}'
实测回显(原文):
{"id":1,"group_id":null,"otp_type":"totp","account":"root@quzuo.net","service":"GitHub","icon":"Ohh5RSnRYjbvN9bzT52j3HiUcTknA4kZ3J1qBslH.svg","secret":"JBSWY3DPEHPK3PXP","digits":6,"algorithm":"sha1","period":30,"counter":null}
HTTP 状态 201,账户入库并返回完整对象(totp、6 位、sha1、30 秒周期即默认 OTP 参数)。API 令牌在网页设置中生成(Passport 令牌)。至此部署闭环完成。
五、日常运维
升级:改 compose 中的镜像 tag(如 8.0.4 发布后)→ docker compose pull → docker compose up -d。2FAuth 首次启动向导会自动执行迁移(容器内向导命令为 php artisan 2fauth:install),实测的 artisan 专用命令清单:2fauth:install(安装/更新向导)、2fauth:check-db-connection(数据库连通性检查)、2fauth:purge-auth-log 与 2fauth:purge-otp-log(清理过期认证/OTP 日志)、2fauth:fix-passport-key-permissions。容器内执行示例:docker exec 2fauth-803-app php artisan 2fauth:check-db-connection。
备份(两个有状态卷 + 一个配置文件):
# 数据库:在 mysql 容器内执行 mysqldump
docker exec 2fauth-803-mysql mysqldump -u2fauth -p"********" 2fauth > backup-$(date +%F).sql
# 应用数据与配置:直接打包宿主机目录
tar czf 2fauth-data-$(date +%F).tgz ./2fauth settings.env
settings.env 里的 APP_KEY 必须随备份一起保管——落库加密开启后,丢钥等于丢数据。
日志:docker logs 2fauth-803-app(Nginx/PHP-FPM 输出);应用日志在宿主机 ./2fauth/storage/logs/(LOG_CHANNEL=daily 时按日轮转 7 份)。
六、排障实录
- app 反复重启、日志报数据库连接拒绝:MySQL 未通过 Healthy 即手动放行了 app,或
DB_HOST误填127.0.0.1(容器内 127.0.0.1 是自己,应填服务名mysql);用2fauth:check-db-connection快速定位。 - 页面 500 或样式丢失:宿主机
./2fauth目录属主不是1000:1000;chown -R 1000:1000后重启容器。 - WebAuthn 安全密钥注册失败:
APP_URL与浏览器实际访问地址(含端口)不一致所致,WebAuthn 强依赖站点来源一致性;改为真实地址后重启。 - 反向代理后取到的都是代理 IP:设置
TRUSTED_PROXIES为代理地址,详见《2FAuth 8.0.3 配置参数详解》。 - 二维码识别偶发内存报错:官方内置运行期限流
PHP_MEMORY_LIMIT_TEMP_OVERRIDE(默认 512MB),调大即可。
七、下一步
- 参数逐项调优:《2FAuth 8.0.3 配置参数详解》
- 上线前加固(注册管控、加密、WebAuthn、反代 TLS):《2FAuth 8.0.3 安全加固指南》
- 组件画像与同类对比:《2FAuth 8.0.3 介绍与选型指南》