跳转至

Dockerfile 实战演示

准备一个环境

创建工作目录

Bash
cd /opt/app/

准备 requirements.txt 文件

Bash
1
2
3
cat requirements.txt
fastapi
uvicorn

准备 main.py 文件

Python
from fastapi import FastAPI
import uvicorn

app = FastAPI()

@app.get("/")
def read_root():
    return {"hello": "World"}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

编写 Dockerfile

Docker
FROM python:3.13-slim

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

EXPOSE 8000

CMD ["python3", "main.py"]

Dockerfile 逐行解析

  1. FROM python:3.13-slim

    • 指定基础镜像为 Python 3.13 的轻量级版本
    • slim 版本体积更小,适合生产环境
  2. WORKDIR /app

    • 设置工作目录为 /app
    • 后续指令都将在该目录下执行
  3. COPY . .

    • 将构建上下文的所有文件复制到容器内的 /app 目录
    • 包括 requirements.txtmain.py
  4. RUN pip install -r requirements.txt

    • 安装 Python 依赖包
    • 这是构建时执行的命令
  5. EXPOSE 8000

    • 声明容器监听 8000 端口
    • FastAPI 应用默认运行在 8000 端口
  6. CMD ["python3", "main.py"]

    • 设置容器启动时的默认命令
    • 使用 Exec 形式,运行 main.py

构建镜像

Bash
docker build -t docker_test .

参数说明

  • -t:给镜像起名字,名字后边加 :01 版本
  • .:当前目录构建(表示构建上下文为当前目录)

构建过程

  1. Docker 引擎读取 Dockerfile
  2. 按照指令顺序执行
  3. 每个指令创建一个新的镜像层
  4. 最终生成可用的镜像

推送镜像

登录镜像仓库

Bash
# 登录镜像仓库,最好自建,官方登录不上
docker login

推送镜像到仓库

Bash
1
2
3
4
5
# 推送镜像需要带上自己的名字
docker build -t chaic/docker_test .

# 推送
docker push chaic/docker_test

注意事项

  1. 镜像命名规范

    • 格式:[用户名]/[镜像名]:[标签]
    • 示例:chaic/docker_test:1.0
  2. 仓库选择

    • Docker Hub(官方公共仓库)
    • 私有仓库(推荐企业使用)
    • 阿里云镜像仓库、腾讯云镜像仓库等国内服务商
  3. 标签管理

    • :latest - 最新版本(默认)
    • :1.0 - 具体版本号
    • 建议使用语义化版本号

运行容器

Bash
docker run -d -p 8000:8000 --name my-fastapi docker_test

参数说明

  • -d:后台运行(detached mode)
  • -p 8000:8000:端口映射(主机端口:容器端口)
  • --name my-fastapi:指定容器名称

访问应用

Bash
curl http://localhost:8000/

返回结果:

JSON
{"hello": "World"}

常见问题排查

1. 构建失败

问题RUN pip install 失败

解决

  • 检查网络连接
  • 使用国内镜像源
  • 确认 requirements.txt 格式正确
Docker
RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt

2. 端口冲突

问题docker run 时提示端口已被占用

解决

  • 修改主机端口映射
  • 使用 -p 8001:8000 映射到其他端口

3. 文件权限问题

问题:容器内无权限读写文件

解决

Docker
USER 1000:1000

最佳实践

1. 优化镜像大小

Docker
1
2
3
4
5
6
# 使用 alpine 版本
FROM python:3.13-alpine

# 清理缓存
RUN pip install -r requirements.txt && \
    rm -rf /root/.cache/pip

2. 利用层缓存

Docker
1
2
3
4
5
6
# 先复制依赖文件,利用缓存
COPY requirements.txt .
RUN pip install -r requirements.txt

# 再复制应用代码
COPY . .

3. 多阶段构建

Docker
# 构建阶段
FROM python:3.13 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --target=/install -r requirements.txt

# 运行阶段
FROM python:3.13-slim
COPY --from=builder /install /usr/local/lib/python3.13/site-packages
COPY . .
CMD ["python3", "main.py"]

4. 安全性

Docker
1
2
3
# 使用非 root 用户运行
RUN adduser -D -u 1000 appuser
USER appuser

5. 健康检查

Docker
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8000/ || exit 1

总结

本实战演示展示了从零开始构建一个 FastAPI 应用的 Docker 镜像的完整流程:

  1. 准备应用代码和依赖文件
  2. 编写 Dockerfile
  3. 构建镜像
  4. 推送到镜像仓库
  5. 运行容器

通过实际操作,可以更好地理解 Dockerfile 各指令的作用和 Docker 镜像构建的过程。