FastAPI 新手入门第 17 篇:用 Docker 跑起来,让别人不用猜运行环境
前面的项目需要先准备 Python、虚拟环境和依赖,再启动 FastAPI。换一台机器时,Python 版本、依赖版本和启动命令都可能不同。本文把项目做成 Docker 镜像,读者只需构建一次镜像,再用 docker run 启动服务,打开 /docs 就能调用接口。
Docker 镜像保存运行 FastAPI 所需的代码、依赖和默认启动命令。容器是镜像启动后的运行实例。
Dockerfile 放什么
在项目根目录新建 Dockerfile。这段配置使用 Python 3.12 精简镜像,把 pyproject.toml 和 app/ 复制进容器,安装项目后通过 FastAPI CLI 启动服务。
FROM python:3.12-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
COPY pyproject.toml ./
COPY app ./app
RUN pip install --no-cache-dir .
EXPOSE 8000
CMD ["fastapi", "run", "app/main.py", "--host", "0.0.0.0", "--port", "8000"]
WORKDIR /app 让后续命令都在容器的 /app 目录执行。pip install . 按 pyproject.toml 安装当前项目和依赖;--no-cache-dir 不保留 pip 下载缓存,镜像会少一些无用文件。
CMD 使用 JSON 数组形式。容器停止时,Docker 能把停止信号直接交给 FastAPI 进程,应用有机会正常关闭。
--host 0.0.0.0 不能省略。容器中的 127.0.0.1 只指向容器自己,服务监听 0.0.0.0 后,Docker 的端口映射才能把请求转进应用。
用 .dockerignore 缩小构建上下文
Docker 构建时会把项目目录发送给守护进程。虚拟环境、Git 历史、测试缓存、本地数据库和 .env 都不应进入镜像。
在根目录新建 .dockerignore:
.git
.venv
__pycache__/
*.py[cod]
.pytest_cache/
.ruff_cache/
.mypy_cache/
.env
*.db
*.egg-info/
tests/
.env 被排除后,JWT 密钥和环境差异不会写进镜像。镜像可以在开发、测试和生产环境复用,配置在启动容器时再传入。
构建镜像
确认 Docker Desktop 已启动,在项目根目录执行:
docker build -t fastapi-beginner-lab .
末尾的 . 表示构建上下文是当前目录。-t fastapi-beginner-lab 给构建结果取一个本地镜像名,后面的 docker run 会使用这个名字。
首次构建会下载 Python 基础镜像和 Python 依赖,耗时通常比后续构建长。修改应用代码后再次执行同一条命令,Docker 会复用没有变化的层。
用容器启动接口
先准备运行时配置。没有 .env 时,项目会使用 Settings 中的开发默认值;已有 .env 时,把它作为容器环境变量传入。
Copy-Item .env.example .env
docker run --rm --name fastapi-beginner-lab -p 8000:8000 --env-file .env fastapi-beginner-lab
-p 8000:8000 左边是 Windows 主机端口,右边是容器内 FastAPI 的端口。--rm 会在容器停止后删除容器本身,适合本地试验;镜像仍然保留,可以再次启动。
打开下面地址验证:
http://127.0.0.1:8000/docs
也可以在另一个 PowerShell 窗口请求健康检查:
Invoke-RestMethod http://127.0.0.1:8000/health
返回内容里有 status、app_name 和 app_env,说明端口映射和应用启动命令都已生效。
容器里的 SQLite 数据不会自动保留
当前默认数据库地址是 sqlite:///./fastapi_beginner_lab.db。这会在容器的 /app 目录创建 SQLite 文件。使用 docker run --rm 停止容器后,该容器连同其中新建的数据库文件都会消失。
本地演示可以接受这个行为。需要保存商品、用户或上传记录时,至少要做两件事:把数据库地址改到挂载目录或外部数据库,并在启动容器时提供对应的卷或数据库连接配置。Docker 解决的是运行环境一致,不会替应用保存数据。
镜像构建和容器运行各查什么
遇到问题时,可以按下面顺序检查:
docker build失败:查看Dockerfile的COPY路径、pyproject.toml和依赖安装输出。- 容器启动后马上退出:运行
docker logs fastapi-beginner-lab,检查 FastAPI 的启动异常。 - 浏览器无法访问:确认容器命令使用了
--host 0.0.0.0,并确认-p 8000:8000没有被其他程序占用。 - 配置不符合预期:确认
.env没有被复制进镜像,并检查--env-file .env是否指向当前项目的配置文件。
动手改一下
把应用名称改为容器环境的名字:
$env:APP_NAME = "FastAPI Container Lab"
docker run --rm -p 8000:8000 -e APP_NAME=$env:APP_NAME fastapi-beginner-lab
刷新 /docs。页面标题显示 FastAPI Container Lab,说明配置来自启动容器时的环境变量,而不是写进镜像的代码。
到这里,这篇的目标已经完成:
- 我们写出了可构建 FastAPI 项目的
Dockerfile。 - 我们用端口映射启动容器,并访问了
/docs和/health。 - 我们知道了
.env与 SQLite 数据都不该直接固化进镜像。
本文代码:https://github.com/tanghaojin/fastapi-beginner-lab/tree/article-17-docker
参考资料
- FastAPI in Containers - Docker: https://fastapi.tiangolo.com/deployment/docker/
- Dockerfile reference: https://docs.docker.com/reference/dockerfile/
更多推荐



所有评论(0)