跳到主要内容

第 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.pyFastAPI 应用入口需要
models/、routers/、schema/、utils/模型、接口、数据结构和工具代码需要
static/HTML、CSS、JavaScript、图片和字体需要
migrations/、alembic.iniAlembic 迁移需要
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 与私钥。


← 第 10 课:ECS 项目准备 · 第 12 课:真实项目 Dockerfile 与 Compose →

课程推荐

想系统学习这门课程?

你已阅读完本文。需要更完整的知识体系,可以继续了解「Vibe Coding 实战课程」。

查看课程详情