Python 后端基础(十七):Docker 和 Docker Compose 怎么用,把项目一键跑起来
很多项目在自己电脑能跑,换一台电脑就跑不起来。
原因可能是 Python 版本不同、依赖没装、环境变量缺失、MySQL 和 Redis 没启动。Docker 解决的就是“环境一致性”问题。
【一、Docker 是什么】
Docker 可以把应用和运行环境打包成镜像,然后在不同机器上用容器运行。
简单理解:
镜像 image:应用的打包模板
容器 container:镜像运行起来后的实例
Dockerfile:描述怎么构建镜像
它不是虚拟机,但可以提供相对隔离的运行环境。
【二、为什么后端项目要用 Docker】
主要价值:
- 环境一致。
- 部署简单。
- 依赖清晰。
- 方便本地启动 MySQL、Redis。
- 适合 CI/CD。
- 简历项目看起来更工程化。
对秋招项目来说,有 Docker Compose 比只写“运行 python main.py”更有说服力。
【三、Dockerfile 示例】
FastAPI 项目 Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
含义:
- 基于 Python 3.11 镜像。
- 设置工作目录 `/app`。
- 安装依赖。
- 复制项目代码。
- 暴露 8000 端口。
- 启动 FastAPI 服务。
【四、构建和运行】
构建镜像:
docker build -t my-fastapi-app .
运行容器:
docker run -p 8000:8000 my-fastapi-app
`-p 8000:8000` 表示把宿主机 8000 端口映射到容器 8000 端口。
【五、Docker Compose 是什么】
一个后端项目通常不只有一个服务,还可能有:
- API 服务
- MySQL
- Redis
- Celery Worker
- Nginx
Docker Compose 可以用一个文件把多个服务一起启动。
services:
api:
build: .
ports:
- "8000:8000"
depends_on:
- redis
redis:
image: redis:7
ports:
- "6379:6379"
启动:
docker compose up --build
停止:
docker compose down
【六、环境变量】
Compose 里可以传环境变量:
services:
api:
build: .
env_file:
- .env
`.env` 保存真实配置,不上传 GitHub。
`.env.example` 写示例:
DATABASE_URL=mysql://user:pass@mysql:3306/app
REDIS_URL=redis://redis:6379/0
JWT_SECRET=change_me
【七、数据卷】
数据库容器如果不挂载数据卷,容器删除后数据可能没了。
volumes:
mysql_data:
services:
mysql:
image: mysql:8
volumes:
- mysql_data:/var/lib/mysql
数据卷用于持久化数据。
【八、常见坑】
- 容器内访问 localhost,以为能访问宿主机服务。
- MySQL 容器没完全启动,API 就开始连接。
- 没有 `.dockerignore`,把 `.venv`、日志、输出文件都打进镜像。
- 数据库没挂 volume,重建容器后数据丢失。
- 生产环境把密钥写进 Dockerfile。
【九、面试常问】
1. Docker 镜像和容器有什么区别?
镜像是静态模板,包含应用和依赖;容器是镜像运行起来后的实例。一个镜像可以启动多个容器。
2. Docker Compose 有什么用?
Compose 用来编排多个容器服务,比如 API、MySQL、Redis、Worker,用一个 yaml 文件统一启动和管理。
3. Dockerfile 里为什么先复制 requirements.txt 再复制代码?
这样可以利用 Docker 构建缓存。依赖没变时,不用每次重新安装依赖,构建更快。