为什么要容器化?¶
在开发和部署应用时,我们常常会遇到“在我电脑上能运行”但“在你电脑上不行”的问题,这就是环境不一致导致的。Docker容器化技术能解决这个问题——它把你的应用和所有依赖打包成一个独立的“盒子”,不管在什么机器上,打开这个盒子就能运行你的应用,就像打开一个罐头一样简单。
FastAPI是一个高性能、易上手的Python API框架,用它开发的服务,配合Docker容器化后部署会更方便、更一致。接下来,我们一步步来实现。
一、准备工作:先写一个最简单的FastAPI应用¶
1. 安装Python和依赖¶
首先确保你的电脑上安装了Python(推荐3.7+版本)。然后创建一个项目文件夹,比如叫fastapi-docker-demo,在里面新建一个main.py文件,这是FastAPI应用的入口文件。
2. 编写FastAPI代码¶
在main.py中输入以下代码:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"} # 访问根路径返回Hello World
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q} # 带参数的示例接口
这段代码创建了一个FastAPI应用,包含两个接口:
- 根路径/返回JSON数据{"Hello": "World"}
- 带参数的路径/items/{item_id},接收整数item_id和可选字符串q
3. 生成依赖文件¶
在项目根目录下,打开命令行,运行:
pip install fastapi uvicorn # 安装FastAPI和Uvicorn(Uvicorn是FastAPI推荐的运行服务器)
pip freeze > requirements.txt # 生成依赖文件,记录需要安装的包
此时项目目录结构应该是这样的:
fastapi-docker-demo/
├── main.py
└── requirements.txt
二、用Docker打包FastAPI应用¶
1. 什么是Dockerfile?¶
Dockerfile是一个文本文件,里面包含了构建Docker镜像的所有指令。我们需要用它告诉Docker“如何把FastAPI应用打包成一个镜像”。
2. 编写Dockerfile¶
在项目根目录下新建一个Dockerfile(没有后缀名),输入以下内容:
# 1. 基础镜像:使用Python 3.9的精简版镜像
FROM python:3.9-slim
# 2. 设置工作目录(容器内的工作路径)
WORKDIR /app
# 3. 复制依赖文件到容器内(先复制requirements.txt是为了利用Docker缓存,加快构建速度)
COPY requirements.txt .
# 4. 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 5. 复制当前目录的所有文件到容器内的/app目录
COPY . .
# 6. 容器启动时执行的命令:启动Uvicorn服务器
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
每一行的作用解释:
- FROM python:3.9-slim:从Docker仓库拉取Python 3.9的精简版镜像(体积小,适合生产环境)
- WORKDIR /app:在容器内创建并进入/app目录,后续操作都在这个目录下
- COPY requirements.txt .:把本地的requirements.txt复制到容器的/app目录
- RUN pip install ...:安装依赖文件里的包,--no-cache-dir是为了不缓存依赖,减少镜像体积
- COPY . .:把本地所有文件(除了.dockerignore里的)复制到容器的/app目录
- CMD ["uvicorn", ...]:当容器启动时,执行uvicorn命令启动FastAPI服务,--host 0.0.0.0表示允许外部访问,--port 8000指定端口
3. 忽略不需要的文件(可选)¶
如果项目里有__pycache__、.git等文件,Docker会一起打包,导致镜像变大。可以创建.dockerignore文件,内容如下:
__pycache__
*.pyc
*.pyo
*.pyd
.git
.gitignore
三、构建Docker镜像¶
1. 构建镜像命令¶
在项目根目录下(确保Docker已经安装),打开命令行,执行:
docker build -t my-fastapi-app .
-t my-fastapi-app:给镜像起个名字my-fastapi-app(可以自定义).:表示Dockerfile在当前目录下
执行后,Docker会自动按照Dockerfile的步骤构建镜像。如果一切顺利,最后会显示Successfully built [镜像ID]。
2. 检查镜像是否构建成功¶
运行以下命令,查看本地镜像列表:
docker images
你应该能看到刚才创建的my-fastapi-app镜像。
四、运行Docker容器¶
1. 启动容器¶
执行以下命令启动容器,同时把容器的8000端口映射到主机的8000端口(这样才能从浏览器访问):
docker run -p 8000:8000 my-fastapi-app
-p 8000:8000:端口映射,格式是主机端口:容器端口my-fastapi-app:要运行的镜像名称
启动后,你会看到类似以下日志:
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
这说明服务已经启动,并且监听在容器的8000端口(通过--host 0.0.0.0设置的)。
五、测试服务是否正常运行¶
1. 访问API接口¶
打开浏览器,访问http://localhost:8000,你应该能看到返回{"Hello": "World"}。
或者用命令行工具curl测试:
curl http://localhost:8000
输出:{"Hello":"World"}
2. 访问自动生成的API文档¶
FastAPI自带Swagger UI和ReDoc,方便调试接口。访问:
http://localhost:8000/docs
这里可以看到所有接口的详细说明,点击“Try it out”还能直接测试接口参数。
六、常见问题和解决方法¶
1. 端口被占用怎么办?¶
如果启动时报错Bind to address 0.0.0.0:8000 failed,说明8000端口被其他程序占用。解决方法:
- 换一个端口(比如8001):修改Dockerfile中的CMD为uvicorn main:app --host 0.0.0.0 --port 8001,然后重新构建镜像,启动时用-p 8001:8001
- 停止占用端口的程序:在Windows用netstat -ano | findstr 8000,找到PID后用taskkill /PID [PID] /F结束进程;在Linux/Mac用lsof -i :8000找到进程ID后kill
2. 如何修改代码后重新部署?¶
每次修改代码后,需要重新构建镜像并启动容器:
# 先停止之前的容器(如果没后台运行)
docker stop [容器ID]
# 重新构建镜像
docker build -t my-fastapi-app .
# 重新启动容器
docker run -p 8000:8000 my-fastapi-app
七、总结¶
通过Docker容器化部署FastAPI,你可以:
1. 确保开发、测试、生产环境一致,避免“在我电脑上能跑”的问题
2. 快速迁移服务,只需复制镜像文件
3. 隔离应用依赖,让部署更轻量
后续还可以进一步优化,比如:
- 使用Docker Compose管理多个服务(比如FastAPI+数据库)
- 配置Nginx反向代理,用HTTPS
- 部署到云平台(如阿里云、AWS、Google Cloud)的容器服务
现在你已经掌握了FastAPI+Docker的基础部署流程,可以开始把你的API服务封装成容器,实现一键部署啦!