Python 后端基础(十七):Docker 和 Docker Compose 怎么用,把项目一键跑起来

📅 2026/7/6 6:10:52 👁️ 阅读次数 📝 编程学习
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 构建缓存。依赖没变时,不用每次重新安装依赖,构建更快。