python环境搭建 (五) Dockerfile 和 docker-compose.yml 核心作用

一、Dockerfile 和 docker-compose.yml 核心作用

1. Dockerfile:构建「可运行的镜像」

Dockerfile 是镜像构建脚本,定义了「运行项目所需的基础环境、依赖、代码、配置」,最终打包成一个独立的 Docker 镜像(镜像 = 项目运行的"完整操作系统+依赖+代码")。简单说,Dockerfile 是"制作镜像的配方"。

2. docker-compose.yml:编排「容器的运行」

Docker Compose 是 Docker 官方的容器编排工具,docker-compose.yml 是它的配置文件,用来定义容器的运行规则 (比如端口映射、数据持久化、环境变量、启动命令、健康检查等),可以一键启动/停止/重启容器,避免手动敲复杂的 docker run 命令。简单说,docker-compose.yml 是"运行容器的说明书"。


二、逐行解析你的文件写法(为什么这么写)

(1)Dockerfile 解析(镜像构建逻辑)
dockerfile 复制代码
# 基础镜像:轻量版 Python 3.12(slim 减少镜像体积,适合生产环境)
FROM python:3.12-slim

# 环境变量配置(Python 运行最佳实践)
ENV PYTHONDONTWRITEBYTECODE=1 \    # 禁止生成 .pyc 字节码文件(减少冗余)
    PYTHONUNBUFFERED=1 \           # 关闭输出缓冲(日志实时打印,方便调试)
    PYTHONPATH=/app \              # 设定 Python 根目录(项目代码可直接导入)
    TZ=Asia/Shanghai               # 设定时区(避免日志/业务时间错乱)

# 设定容器内的工作目录(后续命令都在 /app 下执行)
WORKDIR /app

# 安装系统级依赖(按需安装,最小化原则)
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \  # 编译依赖(部分 Python 包带 C 扩展,需编译)
    curl \             # 用于 docker-compose 的健康检查(curl 检测接口)
    bash \             # 执行启动脚本(start.sh 需要 bash 环境)
    supervisor \       # 进程管理(可选,用于管理多进程应用)
    && rm -rf /var/lib/apt/lists/* \  # 清理缓存(减小镜像体积)
    && apt-get clean

# 安装 Python 依赖(先拷贝 requirements.txt 利用 Docker 缓存)
COPY requirements.txt .
RUN pip install --no-cache-dir --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple \
    && pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# --no-cache-dir:不缓存安装包(减小镜像体积);清华源:加速国内依赖安装

# 拷贝项目所有代码到容器 /app 目录
COPY . .

# 创建日志/数据目录 + 给启动脚本加执行权限
RUN mkdir -p /app/logs /app/data \
    && chmod +x /app/scripts/*.sh

# 声明容器暴露 8000 端口(仅声明,实际映射靠 docker-compose)
EXPOSE 8000
(2)docker-compose.yml 解析(容器运行逻辑)
yaml 复制代码
version: '3.8'  # Compose 文件格式版本(兼容 Docker 版本)

services:
  app:  # 定义一个名为 app 的服务(对应一个容器)
    image: xmh-docker.tencentcloudcr.com/prod-xmh-ecology-service/ai-expert-hub:latest
    # 构建配置:基于当前目录的 Dockerfile 构建镜像
    build:
      context: .       # 构建上下文(Dockerfile 所在目录)
      dockerfile: Dockerfile
    container_name: ai-expert-hub  # 容器名称(固定名称,方便管理)
    restart: unless-stopped  # 重启策略:除非手动停止,否则容器崩溃自动重启(高可用)
    ports:
      - "8000:8000"  # 端口映射:主机 8000 端口 → 容器 8000 端口(外部可访问)
    command: ["bash", "/app/scripts/start.sh"]  # 容器启动后执行的命令(运行启动脚本)
    environment:
      - ENV=${ENV:-prod}  # 环境变量:ENV 默认为 prod(项目可根据 ENV 加载不同配置)
    volumes:
      # 数据卷(持久化 + 热更新):
      - /data/log/ai-expert-hub:/app/logs  # 主机日志目录 → 容器日志目录(容器删除日志不丢)
      - .:/app  # 主机当前目录 → 容器 /app(开发时改本地代码,容器内实时同步,无需重构镜像)
    healthcheck:  # 健康检查(监控服务是否存活)
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]  # 检测 /health 接口
      interval: 30s  # 每 30 秒检查一次
      timeout: 10s   # 检查超时时间
      retries: 3     # 失败重试 3 次判定为不健康
      start_period: 10s  # 容器启动 10 秒后开始检查

三、两者的配合逻辑

  1. Dockerfile 做"构建":把项目的运行环境(Python 3.12)、系统依赖(curl/bash)、Python 依赖(requirements.txt)、项目代码打包成一个镜像,这个镜像可以在任何支持 Docker 的机器上运行。
  2. docker-compose.yml 做"运行" :基于 Dockerfile 构建的镜像,配置容器的运行参数(端口、数据卷、环境变量、启动命令等),然后通过 docker-compose 命令一键启动容器,无需手动执行 docker build + docker run 等复杂命令。

四、搭建完整环境的步骤(从 0 到 1)

前提:安装 Docker + Docker Compose
  • Windows/macOS:安装 Docker Desktop(内置 Compose)。

  • Linux:执行以下命令安装(以 Ubuntu 为例):

    bash 复制代码
    # 安装 Docker
    sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io
    # 安装 Docker Compose
    sudo apt-get install -y docker-compose-plugin
    # 给当前用户加 Docker 权限(避免每次输 sudo)
    sudo usermod -aG docker $USER && newgrp docker
步骤 1:检查项目文件完整性

确保项目根目录有以下文件/目录(缺一不可):

复制代码
你的项目/
├── Dockerfile          # 镜像构建脚本
├── docker-compose.yml  # 容器编排配置
├── requirements.txt    # Python 依赖列表(如 fastapi、uvicorn 等)
├── scripts/
│   └── start.sh        # 启动脚本(容器核心启动命令)
└── 你的项目代码(如 main.py、app/ 等)
步骤 2:编写启动脚本 start.sh

scripts/start.sh 是容器启动的核心,示例(以 FastAPI 为例,根据你的项目框架调整):

bash 复制代码
#!/bin/bash
# 可选:添加初始化操作(如数据库迁移、配置检查)
# python /app/manage.py migrate

# 启动 Python 应用(以 uvicorn 为例)
exec uvicorn main:app --host 0.0.0.0 --port 8000

注意:exec 必须加,保证应用进程是容器的 1 号进程(Docker 能正确监控进程状态)。

步骤 3:构建并启动容器

打开终端,进入项目根目录,执行:

bash 复制代码
# 构建镜像 + 启动容器(后台运行)
docker-compose up -d --build

# 查看容器状态(正常应为 Up)
docker-compose ps

# 查看应用日志(排查启动失败问题)
docker-compose logs -f app
步骤 4:验证服务是否正常
  • 访问健康检查接口:http://localhost:8000/health(需项目实现 /health 接口,返回 200 OK 即正常)。
  • 访问应用主接口:http://localhost:8000(根据你的项目路由调整)。
步骤 5:日常管理命令
bash 复制代码
# 停止容器(保留镜像/数据)
docker-compose down

# 重启容器
docker-compose restart app

# 进入容器内部调试(比如看代码、查日志)
docker-compose exec app bash

# 重新构建镜像(修改 Dockerfile/requirements.txt 后执行)
docker-compose build app

五、常见问题排查

  1. 容器启动失败 :执行 docker-compose logs app 看日志,常见原因:
    • start.sh 不存在/无执行权限(检查脚本路径 + chmod +x scripts/start.sh)。
    • 端口 8000 被占用(修改 docker-compose.ymlports8001:8000)。
    • Python 依赖安装失败(检查 requirements.txt 语法 + 网络是否能访问清华源)。
  2. 日志不持久化 :Linux 下给主机日志目录加权限:sudo chmod 777 /data/log/ai-expert-hub
  3. 代码修改后不生效 :确认 volumes 里的 .:/app 配置存在(本地代码映射到容器,改本地代码容器内实时同步)。
相关推荐
Byte Beat2 小时前
使用docker单机部署kafka,以KRaft模式运行,不使用zookeeper,
docker·kafka·kraft
独断万古他化2 小时前
【Spring 事务】核心概念与实战:从手动控制到注解自动事务
java·spring·事务
马猴烧酒.2 小时前
【团队空间|第十一天】基础功能实现,RBAC权限控制,ShardingSphere详解
java·开发语言·数据库
fengxin_rou2 小时前
从 String 到 Zset:Redis 核心数据结构全解析及排行榜应用
java·开发语言·redis·多线程
世界尽头与你2 小时前
CVE-2025-55752_ Apache Tomcat 安全漏洞
java·安全·网络安全·渗透测试·tomcat·apache
Re.不晚2 小时前
Java进阶之路--线程最最详细讲解
java·开发语言
礼拜天没时间.2 小时前
Docker基础操作——镜像与容器管理
linux·运维·服务器·docker·容器·centos
fen_fen2 小时前
Docker MongoDB 配置 0.0.0.0 监听(外部可访问)操作文档
mongodb·docker·eureka
遨游xyz2 小时前
数据结构-栈
java·数据结构·算法