feat: Phase 0 FBA 部署包——docker-compose + nginx 反代 + env 模板(issue #159)

This commit is contained in:
2026-08-06 08:41:59 +08:00
parent 8b68d015c2
commit 70c680a612
5 changed files with 284 additions and 0 deletions
+90
View File
@@ -0,0 +1,90 @@
# iAOP · FBA 基础设施部署(Epic #159 · Phase 0)
将 [fastapi-best-architecture](https://github.com/fastapi-practices/fastapi-best-architecture)
(下称 FBA)作为 iAOP 的统一认证 / 用户角色权限基座,以 Docker 方式与现有 iAOP
服务并行部署,由宿主机现有 nginx 以 `/fba/` 前缀统一反代。
## 架构位置
```
浏览器
│ http://39.101.182.167:8090
▼
宿主机 nginx(现有 iAOP 站点)
├── / → iAOP 前端(web/ 静态)
├── /api/v1/ → iAOP 后端(现有 FastAPI,业务接口)
└── /fba/ → 127.0.0.1:8001 → fba_server(FBA 后端,认证/RBAC)
├── fba_postgres(PG16)
└── fba_redis
```
> iAOP 自身也使用 `/api/v1` 前缀,因此 FBA 必须通过 `/fba/` 前缀隔离,
> 两者不能共用路径。
## 前置条件
1. 服务器已安装 Docker 与 Docker Compose 插件(`docker compose version` 可查)。
2. 获取 FBA 源码,放到本仓库同级目录:
```bash
cd /opt/apps # 假设 iAOP 在 /opt/apps/iAOP
git clone https://github.com/fastapi-practices/fastapi-best-architecture fba-backend
```
若放在其他位置,修改 `compose.env` 中的 `FBA_SRC`。
## 部署步骤
```bash
cd /opt/apps/iAOP/deploy/fba
# 1. 修改密钥与密码(生产必做)
# - compose.env: FBA_PG_PASSWORD
# - fba.env: DATABASE_PASSWORD(与上一致)、TOKEN_SECRET_KEY
python3 -c "import secrets; print(secrets.token_urlsafe(32))" # 生成 TOKEN_SECRET_KEY
# 2. 构建并启动
docker compose --env-file compose.env up -d --build
# 3. 初始化数据库表结构 + 内置数据(菜单/角色/管理员)
docker exec -it fba_server fba init
# 若 fba 命令不可用,改用:docker exec -it fba_server python backend/cli.py init
# 4. 验证服务
curl -s http://127.0.0.1:8001/api/v1/auth/captcha | head -c 200
# 5. 合并 nginx 片段(见 nginx-fba.conf 头部说明),然后 reload
nginx -t && nginx -s reload
# 6. 通过外部入口验证
curl -s http://39.101.182.167:8090/fba/api/v1/auth/captcha | head -c 200
```
FBA 默认管理员账号:`admin / 123456`(登录后请立即修改)。
## 常用运维命令
```bash
docker compose --env-file compose.env logs -f fba_server # 看日志
docker compose --env-file compose.env restart fba_server # 重启
docker compose --env-file compose.env down # 停止(数据保留在卷中)
docker exec -it fba_postgres psql -U postgres -d fba # 进数据库
```
## 与 iAOP 代码侧的关系(后续 Phase)
- **Phase 1**:iAOP 前端 `web/shared/session.js` 改为调用
`/fba/api/v1/auth/login`(JSON 登录)与 `/fba/api/v1/auth/codes`
(授权码)做登录与鉴权,现有 `core/auth` 退役。
- **Phase 2**:Sider 菜单由 FBA `sys_menu` 接口驱动,替代前端硬编码菜单。
- **Phase 3**:FBA UI(Vue3 + AntDV)构建时设置
`VITE_GLOB_API_URL=http://<域名>/fba`,产物由 nginx 挂在 `/fba-admin/`,
作为用户/角色/菜单管理界面。
## 注意事项
- `fba_postgres` / `fba_redis` 不映射宿主端口,仅容器网络内可达;
`fba_server` 仅绑定 `127.0.0.1:8001`。
- iAOP 现有数据(SQLite 业务库)与 FBA 的 PG 库完全独立,Phase 0 不迁移任何数据。
- FBA 源码目录(`fba-backend`)不属于本仓库,升级 FBA 时在
`fba-backend` 目录内 `git pull` 后重新 `--build` 即可。
+16
View File
@@ -0,0 +1,16 @@
# =============================================================================
# docker compose --env-file 使用的变量文件
# 作用域:仅 deploy/fba/docker-compose.yml 的变量插值
# =============================================================================
# FBA 源码所在目录(需包含其官方 Dockerfile)。
# 默认期望克隆到 iAOP 仓库同级目录,例如:
# /opt/apps/iAOP ← 本仓库
# /opt/apps/fba-backend ← git clone https://github.com/fastapi-practices/fastapi-best-architecture
FBA_SRC=../../../fba-backend
# fba_server 对外(回环)端口,nginx 反代目标
DOCKER_MAP_SERVER_PORT=8001
# FBA PostgreSQL 超级用户密码,必须与 fba.env 中 DATABASE_PASSWORD 一致
FBA_PG_PASSWORD=123456
+102
View File
@@ -0,0 +1,102 @@
# =============================================================================
# iAOP · FBA(fastapi-best-architecture)最小化部署编排
# Epic issue #159 · Phase 0 基础设施
#
# 只包含 iAOP 需要的 3 个服务:fba_server / fba_postgres / fba_redis。
# 已移除 FBA 官方 compose 中的 celery / rabbitmq / nginx / 监控组件
# (iAOP 无定时任务需求,对外由宿主机现有 nginx 统一反代)。
#
# 前置条件:
# 1. 宿主机安装 Docker + Docker Compose 插件
# 2. 将 FBA 源码克隆到本仓库的同级目录:
# git clone https://github.com/fastapi-practices/fastapi-best-architecture ../fba-backend
# 或通过环境变量 FBA_SRC 指定其他路径(见下)
# 3. 按 fba.env 模板填写配置(务必更换 TOKEN_SECRET_KEY 与数据库密码)
#
# 启动:
# cd deploy/fba
# docker compose --env-file compose.env up -d --build
#
# 停止:
# docker compose --env-file compose.env down
# =============================================================================
networks:
fba_network:
name: fba_network
driver: bridge
volumes:
fba_postgres:
name: fba_postgres
fba_redis:
name: fba_redis
fba_static:
name: fba_static
fba_static_upload:
name: fba_static_upload
services:
# FBA 后端 API 服务(FastAPI + Casbin RBAC)
fba_server:
build:
# FBA 源码根目录(含其官方 Dockerfile)。默认取 iAOP 仓库同级目录 fba-backend,
# 可通过 compose.env 中的 FBA_SRC 覆盖。
context: ${FBA_SRC:-../../../fba-backend}
dockerfile: Dockerfile
image: fba_server:latest
container_name: fba_server
restart: always
environment:
- TZ=Asia/Shanghai
ports:
# 仅绑定回环地址:不直接对外,由宿主机 nginx 以 /fba/ 前缀反代
- "127.0.0.1:${DOCKER_MAP_SERVER_PORT:-8001}:8001"
depends_on:
- fba_postgres
- fba_redis
volumes:
# 用本目录下的 fba.env 作为 FBA 后端配置,避免改动 FBA 源码树
- ./fba.env:/fba/backend/.env:ro
- fba_static:/fba/backend/app/static
- fba_static_upload:/fba/backend/static/upload
- ./logs/fba:/var/log/fba
networks:
- fba_network
# 等待数据库与缓存就绪后再启动 supervisord(复用官方启动方式)
command:
- bash
- -c
- |
wait-for-it -s fba_postgres:5432 -s fba_redis:6379 -t 300
supervisord -c /etc/supervisor/supervisord.conf
supervisorctl restart
# PostgreSQL 16:FBA 的数据库(用户/角色/菜单/Casbin 规则等)
fba_postgres:
image: postgres:16
container_name: fba_postgres
restart: always
environment:
POSTGRES_DB: fba
# 必须与 fba.env 中 DATABASE_PASSWORD 一致
POSTGRES_PASSWORD: ${FBA_PG_PASSWORD:-123456}
TZ: Asia/Shanghai
# 不映射宿主端口,仅 fba_network 内可达
volumes:
- fba_postgres:/var/lib/postgresql/data
networks:
- fba_network
# Redis:Token 黑名单、验证码、限流
fba_redis:
image: redis:latest
container_name: fba_redis
restart: always
environment:
- TZ=Asia/Shanghai
# 不映射宿主端口,仅 fba_network 内可达
volumes:
- fba_redis:/data
networks:
- fba_network
+40
View File
@@ -0,0 +1,40 @@
# =============================================================================
# FBA 后端运行时配置(挂载为容器内 /fba/backend/.env)
# 模板基于 FBA 官方 deploy/backend/docker-compose/.env.server
#
# ⚠️ 部署前必须修改:
# 1. TOKEN_SECRET_KEY —— 重新生成(python -c "import secrets; print(secrets.token_urlsafe(32))")
# 2. DATABASE_PASSWORD —— 与 compose.env 中 FBA_PG_PASSWORD 保持一致
# =============================================================================
# Env
ENVIRONMENT='prod'
# Database
DATABASE_TYPE='postgresql'
DATABASE_HOST='fba_postgres'
DATABASE_PORT=5432
DATABASE_USER='postgres'
DATABASE_PASSWORD='123456'
# Redis
REDIS_HOST='fba_redis'
REDIS_PORT=6379
REDIS_PASSWORD=''
REDIS_DATABASE=0
# Token —— 生产环境务必替换
TOKEN_SECRET_KEY='REPLACE_ME_WITH_A_RANDOM_SECRET'
# [ App ] task
# Celery(iAOP 未启用 celery 容器,以下配置仅用于占位,避免启动报错)
CELERY_BROKER_REDIS_DATABASE=1
# Rabbitmq
CELERY_RABBITMQ_HOST='fba_redis'
CELERY_RABBITMQ_PORT=5672
CELERY_RABBITMQ_USERNAME='guest'
CELERY_RABBITMQ_PASSWORD='guest'
# [ Plugin ] oauth2(iAOP 不使用第三方登录,保留占位)
OAUTH2_GITHUB_CLIENT_ID='test'
OAUTH2_GITHUB_CLIENT_SECRET='test'
OAUTH2_GOOGLE_CLIENT_ID='test'
OAUTH2_GOOGLE_CLIENT_SECRET='test'
# [ Plugin ] email(未启用)
EMAIL_USERNAME=''
EMAIL_PASSWORD=''
+36
View File
@@ -0,0 +1,36 @@
# =============================================================================
# iAOP nginx 片段:将 /fba/ 前缀反代到 FBA 后端(127.0.0.1:8001)
#
# 用法:由运维将本文件 include 进现有 iAOP 站点的 server 块
# (与 8090 现有 location 并列),例如:
#
# server {
# listen 8090;
# ... 现有 iAOP 配置 ...
# include /opt/apps/iAOP/deploy/fba/nginx-fba.conf;
# }
#
# 路径映射:/fba/api/v1/auth/login → http://127.0.0.1:8001/api/v1/auth/login
# 说明:FBA 后端所有接口都在 /api/v1 之下,FBA UI 请求形如
# ${VITE_GLOB_API_URL}/api/v1/...,因此部署 FBA UI 时应将其
# VITE_GLOB_API_URL 配置为 https://<域名>/fba
# =============================================================================
location /fba/ {
# 去掉 /fba 前缀后转发
proxy_pass http://127.0.0.1:8001/;
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;
# FBA 登录/刷新 token 走 cookie + bearer,允许凭据
proxy_http_version 1.1;
proxy_set_header Connection "";
# 上传接口(sys/files)可能较大
client_max_body_size 50m;
proxy_read_timeout 60s;
}