mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-14 13:06:51 +00:00
chore(deploy): 成品部署链路、依赖分组与运维基建
部署方式:服务器不再接收源码、不执行构建,改为本地构建成品后交付
- deploy-artifacts.sh:构建→备份→校验→原子替换,支持回滚、镜像/备份轮转、
mysql 与 postgres 双变体镜像;后端以 docker save|ssh|docker load 交付
- 依赖分组:requirements/{base,storage}.txt + db/{mysql,postgres,sqlite}.txt,
镜像按所选数据库只装对应驱动(MySQL 变体 565MB → 521MB)
编排与运行时加固
- compose:MySQL/Redis/backend 端口仅绑 127.0.0.1;密钥(SECRET_KEY、
DATA_ENCRYPTION_KEY、DATA_ENCRYPTION_OLD_KEYS)、PROD_CORS_ORIGINS、
FORWARDED_ALLOW_IPS、DEMO_ENABLE 一律由 docker/.env 注入
- Dockerfile:对齐依赖分组、以非 root(uid=1000) 运行;.dockerignore 排除全部真实 .env.*
- nginx:静态资源长缓存、隐藏文件拒绝、接口文档仅内网可访问、放行 ACME http-01 校验路径
工程基建
- 新增 CI:backend(uv sync + ruff + pytest)与 frontend(web type-check+vitest、app type-check)
- 新增 DEPLOYMENT.md 运维手册(部署/回滚/密钥轮换/每日巡检/证书/排查)
This commit is contained in:
+22
-8
@@ -32,11 +32,7 @@ dependencies = [
|
||||
"ua-parser==1.0.2", # 解析 User-Agent 获取 OS/浏览器
|
||||
"uvicorn==0.49.0", # uvicorn web 框架
|
||||
"websockets>=16.0,<17.0", # websocket 通信
|
||||
"aiosqlite==0.22.1",
|
||||
"aiomysql>=0.2.0",
|
||||
"asyncpg==0.31.0",
|
||||
"psycopg[binary]==3.3.2",
|
||||
"pymysql==1.2.0",
|
||||
"aiosqlite==0.22.1", # 内嵌知识库(app/modules/ai/chat)固定使用 sqlite,故列入核心
|
||||
"openai==2.46.0",
|
||||
"pydantic[email]>=2.12.5",
|
||||
"cryptography==50.0.0", # Fernet 对称加密(存储源密码加密)
|
||||
@@ -47,10 +43,28 @@ dependencies = [
|
||||
"cos-python-sdk-v5==1.9.44",
|
||||
]
|
||||
|
||||
# 数据库驱动按需安装:uv sync --extra mysql / --extra postgres / --extra sqlite
|
||||
# 默认(不指定 extra)只装核心依赖,启动时会提示缺少对应驱动
|
||||
[project.optional-dependencies]
|
||||
mysql = ["aiomysql>=0.2.0"]
|
||||
postgres = ["asyncpg==0.31.0"]
|
||||
sqlite = ["aiosqlite==0.22.1"]
|
||||
mysql = [
|
||||
"aiomysql>=0.2.0", # 异步驱动(ASYNC_DB_URI)
|
||||
"pymysql==1.2.0", # 同步驱动(DB_URI)
|
||||
]
|
||||
postgres = [
|
||||
"asyncpg==0.31.0", # 异步驱动(ASYNC_DB_URI)
|
||||
"psycopg[binary]==3.3.2", # 同步驱动(DB_URI,自带 libpq)
|
||||
]
|
||||
sqlite = [
|
||||
"aiosqlite==0.22.1",
|
||||
]
|
||||
# 一个进程同时支持三种库(体积最大,适合本地开发)
|
||||
all-db = [
|
||||
"aiomysql>=0.2.0",
|
||||
"pymysql==1.2.0",
|
||||
"asyncpg==0.31.0",
|
||||
"psycopg[binary]==3.3.2",
|
||||
"aiosqlite==0.22.1",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
|
||||
+14
-41
@@ -1,41 +1,14 @@
|
||||
# 与 pyproject.toml [project] dependencies 一致(生产 pip;不含 dev 组:pytest / ruff / fakeredis)
|
||||
agno==2.5.8 # AI agent框架
|
||||
aiofiles==24.1.0 # 文件操作
|
||||
aiosqlite==0.22.1 # sqlite 异步操作数据库
|
||||
alembic==1.18.4 # 数据库迁移
|
||||
apscheduler==3.11.0 # 定时任务
|
||||
croniter==6.2.4 # cron 表达式校验
|
||||
aiomysql>=0.2.0 # 异步mysql操作数据库
|
||||
asyncpg==0.31.0 # 异步postgresql操作数据库
|
||||
bleach==6.4.0 # 过滤 HTML 标签
|
||||
tinycss2==1.5.1 # bleach CSS 清洗依赖
|
||||
click==8.1.7 # 命令行参数解析
|
||||
fastapi==0.138.2 # fastapi 框架
|
||||
greenlet==3.5.2 # 协程核心依赖(SQLAlchemy 异步)
|
||||
httpx==0.28.1 # HTTP 客户端
|
||||
jinja2==3.1.6 # 模板引擎
|
||||
loguru==0.7.3 # 日志
|
||||
openai==2.46.0 # OpenAI API
|
||||
openpyxl==3.1.5 # Excel
|
||||
psutil==7.2.2 # 系统信息
|
||||
py-ip2region==3.0.4 # IP归属地离线查询(ip2region官方binding,内置xdb本地解析)
|
||||
psycopg[binary]==3.3.2 # postgresql 同步驱动(含预编译 libpq,开箱即用)
|
||||
pydantic[email]>=2.12.5 # 邮箱校验
|
||||
pydantic-settings>=2.6.1,<3 # 配置设置
|
||||
pyjwt==2.13.0 # OAuth2
|
||||
pymysql==1.2.0 # MySQL 异步操作数据库
|
||||
python-multipart==0.0.32 # request.form() 对表单进行「解析」时安装
|
||||
redis==7.1.0 # Redis 异步操作数据库
|
||||
rich==15.0.0 # 终端打印美化
|
||||
sqlalchemy==2.0.51 # 数据库ORM
|
||||
sqlglot[rs]==27.8.0 # sql 解析
|
||||
typer==0.26.7 # 命令行工具
|
||||
ua-parser==1.0.2 # 获取用户UA
|
||||
uvicorn==0.49.0 # ASGI 框架
|
||||
websockets>=16.0,<17.0 # websocket 通信
|
||||
cryptography==50.0.0 # Fernet 对称加密(存储源密码加密)
|
||||
paramiko==5.0.0 # SFTP 协议
|
||||
boto3==1.43.72 # S3 协议
|
||||
esdk-obs-python==3.26.6 # 华为云 OBS 协议
|
||||
alibabacloud-oss-v2==1.3.2 # 阿里云 OSS 协议
|
||||
cos-python-sdk-v5==1.9.44 # 腾讯云 COS 协议
|
||||
# ============================================================================
|
||||
# 完整依赖入口(核心 + 全部数据库驱动 + 对象存储)
|
||||
# 适用于:源码部署、本机开发、以及需要「一个镜像同时支持 mysql/postgres/sqlite」的场景。
|
||||
#
|
||||
# 想要更小的生产镜像,请按需组合,例如:
|
||||
# MySQL : -r requirements/base.txt -r requirements/db/mysql.txt -r requirements/storage.txt
|
||||
# Postgres : -r requirements/base.txt -r requirements/db/postgres.txt -r requirements/storage.txt
|
||||
# SQLite : -r requirements/base.txt -r requirements/db/sqlite.txt
|
||||
# ============================================================================
|
||||
-r requirements/base.txt
|
||||
-r requirements/db/mysql.txt
|
||||
-r requirements/db/postgres.txt
|
||||
-r requirements/db/sqlite.txt
|
||||
-r requirements/storage.txt
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# ============================================================================
|
||||
# 核心依赖(与数据库、对象存储无关,任何部署方式都需要)
|
||||
# 用法:pip install -r requirements/base.txt -r requirements/db/<你的数据库>.txt
|
||||
# ============================================================================
|
||||
agno==2.5.8 # AI agent 框架
|
||||
aiosqlite==0.22.1 # AI 模块内嵌知识库固定用 sqlite(与主库类型无关),故列入核心
|
||||
aiofiles==24.1.0 # 异步文件操作
|
||||
alembic==1.18.4 # 数据库迁移
|
||||
apscheduler==3.11.0 # 定时任务
|
||||
bleach==6.4.0 # HTML 过滤
|
||||
click==8.1.7 # 命令行参数解析(typer 依赖)
|
||||
croniter==6.2.4 # cron 表达式校验
|
||||
fastapi==0.138.2 # Web 框架
|
||||
greenlet==3.5.2 # SQLAlchemy 异步必需
|
||||
httpx==0.28.1 # HTTP 客户端
|
||||
jinja2==3.1.6 # 模板引擎(代码生成)
|
||||
loguru==0.7.3 # 日志
|
||||
openai==2.46.0 # OpenAI 兼容接口
|
||||
openpyxl==3.1.5 # Excel 导入导出
|
||||
psutil==7.2.2 # 系统信息采集
|
||||
py-ip2region==3.0.4 # IP 归属地离线查询
|
||||
pydantic[email]>=2.12.5 # 数据校验 + 邮箱
|
||||
pydantic-settings>=2.6.1,<3 # 配置管理
|
||||
pyjwt==2.13.0 # 令牌签发校验
|
||||
python-multipart==0.0.32 # 表单解析
|
||||
redis==7.1.0 # 缓存 / 会话
|
||||
rich==15.0.0 # 终端输出美化
|
||||
sqlalchemy==2.0.51 # ORM
|
||||
sqlglot[rs]==27.8.0 # SQL 解析
|
||||
tinycss2==1.5.1 # bleach 依赖
|
||||
typer==0.26.7 # CLI 入口(main.py)
|
||||
ua-parser==1.0.2 # UA 解析
|
||||
uvicorn==0.49.0 # ASGI 服务器
|
||||
websockets>=16.0,<17.0 # WebSocket
|
||||
@@ -0,0 +1,7 @@
|
||||
# ============================================================================
|
||||
# MySQL 驱动(DATABASE_TYPE=mysql 时必需)
|
||||
# aiomysql / pymysql:异步与同步连接,分别对应 ASYNC_DB_URI 与 DB_URI
|
||||
# 用法:pip install -r requirements/base.txt -r requirements/db/mysql.txt
|
||||
# ============================================================================
|
||||
aiomysql>=0.2.0 # 异步驱动(ASYNC_DB_URI: mysql+aiomysql://)
|
||||
pymysql==1.2.0 # 同步驱动(DB_URI: mysql+pymysql://,迁移与后台任务用)
|
||||
@@ -0,0 +1,9 @@
|
||||
# ============================================================================
|
||||
# PostgreSQL 驱动(DATABASE_TYPE=postgres 时必需)
|
||||
# asyncpg:异步驱动,对应 ASYNC_DB_URI(postgresql+asyncpg://)
|
||||
# psycopg[binary]:同步驱动(含预编译 libpq),对应 DB_URI(postgresql+psycopg://)
|
||||
# 注意:psycopg[binary] 自带 libpq,无需在系统里额外安装 postgresql 客户端库
|
||||
# 用法:pip install -r requirements/base.txt -r requirements/db/postgres.txt
|
||||
# ============================================================================
|
||||
asyncpg==0.31.0 # 异步驱动
|
||||
psycopg[binary]==3.3.2 # 同步驱动
|
||||
@@ -0,0 +1,6 @@
|
||||
# ============================================================================
|
||||
# SQLite 驱动(DATABASE_TYPE=sqlite 时必需)
|
||||
# 适用于本地开发与单机小规模部署;AINI 的 AI 模块内嵌知识库也复用该驱动
|
||||
# 用法:pip install -r requirements/base.txt -r requirements/db/sqlite.txt
|
||||
# ============================================================================
|
||||
aiosqlite==0.22.1 # 异步驱动(sqlite+aiosqlite:///)
|
||||
@@ -0,0 +1,11 @@
|
||||
# ============================================================================
|
||||
# 对象存储与文件传输(本地存储源之外的能力;存储源配置里选用 S3 / OSS / COS / OBS / SFTP 时必需)
|
||||
# 仅使用「本地存储源」的部署可以不装这一组,镜像可再小约 45MB
|
||||
# 用法:pip install -r requirements/base.txt -r requirements/db/mysql.txt -r requirements/storage.txt
|
||||
# ============================================================================
|
||||
boto3==1.43.72 # S3 及兼容协议
|
||||
alibabacloud-oss-v2==1.3.2 # 阿里云 OSS
|
||||
cos-python-sdk-v5==1.9.44 # 腾讯云 COS
|
||||
esdk-obs-python==3.26.6 # 华为云 OBS
|
||||
paramiko==5.0.0 # SFTP
|
||||
cryptography==50.0.0 # 存储源密码的 Fernet 加密
|
||||
Generated
+17
-9
@@ -184,12 +184,10 @@ source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "agno" },
|
||||
{ name = "aiofiles" },
|
||||
{ name = "aiomysql" },
|
||||
{ name = "aiosqlite" },
|
||||
{ name = "alembic" },
|
||||
{ name = "alibabacloud-oss-v2" },
|
||||
{ name = "apscheduler" },
|
||||
{ name = "asyncpg" },
|
||||
{ name = "bleach" },
|
||||
{ name = "boto3" },
|
||||
{ name = "click" },
|
||||
@@ -206,12 +204,10 @@ dependencies = [
|
||||
{ name = "openpyxl" },
|
||||
{ name = "paramiko" },
|
||||
{ name = "psutil" },
|
||||
{ name = "psycopg", extra = ["binary"] },
|
||||
{ name = "py-ip2region" },
|
||||
{ name = "pydantic", extra = ["email"] },
|
||||
{ name = "pydantic-settings" },
|
||||
{ name = "pyjwt" },
|
||||
{ name = "pymysql" },
|
||||
{ name = "python-multipart" },
|
||||
{ name = "redis" },
|
||||
{ name = "rich" },
|
||||
@@ -225,11 +221,20 @@ dependencies = [
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
all-db = [
|
||||
{ name = "aiomysql" },
|
||||
{ name = "aiosqlite" },
|
||||
{ name = "asyncpg" },
|
||||
{ name = "psycopg", extra = ["binary"] },
|
||||
{ name = "pymysql" },
|
||||
]
|
||||
mysql = [
|
||||
{ name = "aiomysql" },
|
||||
{ name = "pymysql" },
|
||||
]
|
||||
postgres = [
|
||||
{ name = "asyncpg" },
|
||||
{ name = "psycopg", extra = ["binary"] },
|
||||
]
|
||||
sqlite = [
|
||||
{ name = "aiosqlite" },
|
||||
@@ -247,14 +252,15 @@ dev = [
|
||||
requires-dist = [
|
||||
{ name = "agno", specifier = "==2.5.8" },
|
||||
{ name = "aiofiles", specifier = "==24.1.0" },
|
||||
{ name = "aiomysql", specifier = ">=0.2.0" },
|
||||
{ name = "aiomysql", marker = "extra == 'all-db'", specifier = ">=0.2.0" },
|
||||
{ name = "aiomysql", marker = "extra == 'mysql'", specifier = ">=0.2.0" },
|
||||
{ name = "aiosqlite", specifier = "==0.22.1" },
|
||||
{ name = "aiosqlite", marker = "extra == 'all-db'", specifier = "==0.22.1" },
|
||||
{ name = "aiosqlite", marker = "extra == 'sqlite'", specifier = "==0.22.1" },
|
||||
{ name = "alembic", specifier = "==1.18.4" },
|
||||
{ name = "alibabacloud-oss-v2", specifier = "==1.3.2" },
|
||||
{ name = "apscheduler", specifier = "==3.11.0" },
|
||||
{ name = "asyncpg", specifier = "==0.31.0" },
|
||||
{ name = "asyncpg", marker = "extra == 'all-db'", specifier = "==0.31.0" },
|
||||
{ name = "asyncpg", marker = "extra == 'postgres'", specifier = "==0.31.0" },
|
||||
{ name = "bleach", specifier = "==6.4.0" },
|
||||
{ name = "boto3", specifier = "==1.43.72" },
|
||||
@@ -272,12 +278,14 @@ requires-dist = [
|
||||
{ name = "openpyxl", specifier = "==3.1.5" },
|
||||
{ name = "paramiko", specifier = "==5.0.0" },
|
||||
{ name = "psutil", specifier = "==7.2.2" },
|
||||
{ name = "psycopg", extras = ["binary"], specifier = "==3.3.2" },
|
||||
{ name = "psycopg", extras = ["binary"], marker = "extra == 'all-db'", specifier = "==3.3.2" },
|
||||
{ name = "psycopg", extras = ["binary"], marker = "extra == 'postgres'", specifier = "==3.3.2" },
|
||||
{ name = "py-ip2region", specifier = "==3.0.4" },
|
||||
{ name = "pydantic", extras = ["email"], specifier = ">=2.12.5" },
|
||||
{ name = "pydantic-settings", specifier = ">=2.6.1,<3" },
|
||||
{ name = "pyjwt", specifier = "==2.13.0" },
|
||||
{ name = "pymysql", specifier = "==1.2.0" },
|
||||
{ name = "pymysql", marker = "extra == 'all-db'", specifier = "==1.2.0" },
|
||||
{ name = "pymysql", marker = "extra == 'mysql'", specifier = "==1.2.0" },
|
||||
{ name = "python-multipart", specifier = "==0.0.32" },
|
||||
{ name = "redis", specifier = "==7.1.0" },
|
||||
{ name = "rich", specifier = "==15.0.0" },
|
||||
@@ -289,7 +297,7 @@ requires-dist = [
|
||||
{ name = "uvicorn", specifier = "==0.49.0" },
|
||||
{ name = "websockets", specifier = ">=16.0,<17.0" },
|
||||
]
|
||||
provides-extras = ["mysql", "postgres", "sqlite"]
|
||||
provides-extras = ["mysql", "postgres", "sqlite", "all-db"]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
|
||||
Reference in New Issue
Block a user