第 11 课:整理真实项目依赖与目录
第四阶段 · 真实 student-management-api · 面向 Docker 初学者
本课完成标准
你能够:
- 整理 requirements.txt;
- 确认 main.py 的启动入口;
- 确认 static/ 和 migrations/ 必须进入镜像;
- 编写 .dockerignore;
- 识别不安全默认配置;
- 为真实项目构建 Docker 镜像做好准备。
1. 先认识真实项目结构
本地项目路径:
/Users/andy/Documents/code/student-management-api
服务器路径:
/www/wwwroot/student-management-api
| 目录或文件 | 用途 | Docker 是否需要 |
|---|---|---|
| main.py | FastAPI 应用入口 | 需要 |
| models/、routers/、schema/、utils/ | 模型、接口、数据结构和工具代码 | 需要 |
| static/ | HTML、CSS、JavaScript、图片和字体 | 需要 |
| migrations/、alembic.ini | Alembic 迁移 | 需要 |
| venv/、pycache/ | 本机环境和缓存 | 不需要 |
main.py 中使用相对路径挂载 static/,所以容器的工作目录必须是项目根目录。
2. 找出真实依赖
依赖不是“猜一份常见列表”。先查看项目的 import:
rg -n "^from |^import " --glob "*.py" --glob "!venv/**" --glob "!__pycache__/**"
根据当前项目代码,第一版可以从这些直接依赖开始:
fastapi[standard]
sqlmodel
pymysql
pydantic-settings
alembic
python-dotenv
python-multipart
openpyxl
python-jose[cryptography]
bcrypt
typer
保存后,在本地虚拟环境中验证导入:
macOS:
cd /Users/andy/Documents/code/student-management-api
source venv/bin/activate
python -c "import fastapi, sqlmodel, pymysql, alembic, openpyxl, jose, bcrypt; print('imports ok')"
python -m pip freeze
Windows PowerShell:
cd C:\path\to\student-management-api
.\venv\Scripts\Activate.ps1
python -c "import fastapi, sqlmodel, pymysql, alembic, openpyxl, jose, bcrypt; print('imports ok')"
先用明确的直接依赖;测试通过后再锁定关键版本。不要把整个本机 pip freeze 盲目复制成生产依赖。
3. 检查启动入口
当前项目的 FastAPI 对象名是 app,定义在 main.py。后续 Docker 启动命令可以使用:
fastapi run main.py --host 0.0.0.0 --port 8000
为什么是 0.0.0.0?容器需要监听所有容器网卡,Docker 才能把端口转发进来。127.0.0.1 只监听容器内部回环地址,外部无法访问。
4. static 和 migrations 必须进入版本库
main.py 会读取:
static/html/login.html
static/css/...
static/js/...
static/images/...
static/fonts/...
如果 Dockerfile 只复制 Python 文件,登录页面可能启动后返回 500 或 404。migrations/ 和 alembic.ini 也必须复制,否则后续无法执行迁移。
git status --short
git ls-files static migrations alembic.ini
如果这些路径没有被 Git 跟踪,先在本地添加并提交,再在 ECS 执行 git pull。
5. 编写 .dockerignore
在项目根目录创建 .dockerignore:
venv/
.venv/
__pycache__/
*.py[cod]
.env
.env.*
!.env.example
.git/
.gitignore
.DS_Store
.vscode/
.idea/
*.log
.pytest_cache/
.mypy_cache/
htmlcov/
.dockerignore 只影响 Docker 构建上下文,不会删除本机文件,也不会改变 Git。static/、migrations/、alembic.ini 不要写进忽略列表。
6. 处理真实项目中的不安全默认值
检查 config.py、database.py 和 migrations/env.py:
rg -n "password|secret|DATABASE_URL|echo=True|127.0.0.1|123456" --glob "*.py" --glob "!venv/**"
当前项目需要特别注意:
| 发现 | 生产处理 |
|---|---|
| config.py 中有数据库默认密码 | 删除真实默认值,要求从 .env 提供 |
| config.py 中有固定 JWT 密钥 | 改为随机生产密钥,通过 .env 注入 |
| database.py 中有 echo=True | 生产关闭 SQL 详细日志,避免泄露数据 |
| 注释或 demo 中出现真实数据库 URL | 删除或替换为无密码示例,并轮换已暴露密码 |
**只把密码从代码中删掉还不够。**如果真实密码曾经进入 Git 提交历史,应立即在宝塔 MySQL 中修改密码,再清理 Git 历史。
7. 本课操作顺序
cd /Users/andy/Documents/code/student-management-api
# 创建 requirements.txt 和 .dockerignore
# 处理 config.py / database.py 中的默认秘密
# 检查静态资源与迁移文件
git status
git add requirements.txt .dockerignore config.py database.py
git diff --cached
git commit -m "chore: prepare production dependencies"
提交前再次执行 git diff --cached,确认没有真实密码。然后推送到 GitHub,ECS 在第 10 课的目录中拉取新提交。
8. 一分钟自测
问题 1:为什么不能把 venv/ 复制进 Docker 镜像?
- A. 它是本机环境,可能与容器系统和架构不兼容
- B. Python 不允许使用虚拟环境
- C. Docker 不能复制文件
问题 2:为什么 static/ 必须进入构建上下文?
- A. main.py 会读取其中的页面、CSS、JS、图片和字体
- B. static/ 负责安装 MySQL
- C. static/ 是 Docker 的配置目录
答案:1A,2A。
本课通关证据
test -f requirements.txt
test -f .dockerignore
test -d static
test -d migrations
git status
git diff --cached
完成标准:requirements.txt 和 .dockerignore 已提交;static、migrations、alembic.ini 会进入构建上下文;venv 和 .env 被排除;默认密码、JWT 密钥和 SQL 调试日志已进入整改清单。
如果遇到错误,请贴完整命令和输出,但隐藏密码、Token 与私钥。
想系统学习这门课程?
你已阅读完本文。需要更完整的知识体系,可以继续了解「Vibe Coding 实战课程」。
查看课程详情