dockerfile必须先copy requirements.txt再run pip install,再copy源码并设workdir /app;docker-compose.yml中depends_on需配condition: service_healthy和healthcheck;expose与ports须双配置;环境变量须通过environment或env_file注入容器。

Python Web应用的Dockerfile必须显式指定WORKDIR和COPY顺序
不设 WORKDIR 或把 COPY . /app 放在 RUN pip install 之后,会导致依赖安装后被覆盖、python app.py 找不到模块。常见错误是直接 COPY 整个目录再装包,结果 requirements.txt 还没读就执行了 pip install。
-
FROM python:3.11-slim足够轻量,避免用python:3.11(带完整 deb 包管理器,镜像大且有安全风险) - 先
COPY requirements.txt .,再RUN pip install --no-cache-dir -r requirements.txt,利用 Docker 层缓存加速构建 - 再
COPY . .,确保源码更新不触发重装依赖 - 必须
WORKDIR /app,否则gunicorn app:app中的相对路径会失败
docker-compose.yml里depends_on不能替代健康检查
depends_on 只控制容器启动顺序,不等数据库 ready 就跑 Python 应用,必然报 ConnectionRefusedError: [Errno 111] Connection refused。PostgreSQL 容器可能已启动,但 pg_isready 还没返回 true。
- 用
healthcheck配合restart: on-failure更可靠:healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d mydb"] interval: 30s timeout: 10s retries: 5
-
depends_on必须搭配condition: service_healthy才真正生效,否则形同虚设 - Web 服务本身也建议加 healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"],方便负载均衡探活
Python项目暴露端口时别漏掉EXPOSE和ports双配置
Dockerfile 里的 EXPOSE 8000 只是文档性质,不自动映射;docker-compose.yml 里 ports 没写或写错格式(比如写成 "8000" 而非 "8000:8000"),会导致宿主机 curl 通不了。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
-
EXPOSE写在 Dockerfile 末尾,对应应用实际监听端口(如gunicorn --bind :8000) -
ports在 compose 中必须显式声明映射关系:- "8000:8000"(本机 8000 → 容器 8000),若省略左边,Docker 会随机分配,无法稳定访问 - 生产环境建议用反向代理(如 nginx 容器),此时 Python 容器只
EXPOSE 8000,不暴露到宿主机,由 nginx 的proxy_pass http://web:8000转发
环境变量和配置文件分离:.env 文件不能替代 compose 的environment
本地 .env 文件会被 docker-compose up 自动加载,但只用于替换 YAML 中的 ${VAR} 占位符;它不会注入到容器内部。如果 Python 代码靠 os.getenv("DB_URL") 读取,却只在 .env 里写了,运行时就是 None。
- 敏感配置(密码、密钥)必须通过
environment或env_file注入容器:environment: - DATABASE_URL=postgresql://postgres:pass@db:5432/mydb env_file: - ./prod.env
-
.env(顶层)仅用于 compose 解析 YAML,比如image: myweb:${TAG};env_file(容器内)才影响 Python 进程 - 避免在 Dockerfile 中用
ENV硬编码配置,会导致镜像不可复用;所有可变参数走运行时注入
网络连通性问题最常卡在服务名拼写和默认 bridge 网络——Docker Compose 自动创建的默认网络里,容器间必须用服务名(如 db)作为 hostname 访问,写 localhost 或 127.0.0.1 一定失败。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










