Docker 入门:把环境装进一个集装箱
「在我电脑上明明能跑!」——每个开发者都听过这句话。Docker 的出现,就是为了让这句话从此失效:把应用连同它的运行环境,一起装进一个标准化集装箱(容器),到哪都能原样跑。
镜像 vs 容器
这是新手最容易混的一对概念:
- 镜像(Image):一个只读的模板,相当于「安装盘」。里面是操作系统、依赖、代码。
- 容器(Container):镜像运行起来的实例,相当于「装好系统的电脑」。
类比:镜像是类(class),容器是对象(instance)。
第一个容器
# 拉取并运行一个 hello-world 镜像
# 跑一个 nginx 并把 80 端口映射到本机 8080
-d 后台运行,-p 主机端口:容器端口 做端口转发,--name 给容器起名。
用 Dockerfile 定义镜像
项目根目录写一份 Dockerfile:
FROM python:3.12-slim # 基础镜像
WORKDIR /app # 工作目录
COPY requirements.txt . # 复制依赖清单
RUN pip install -r requirements.txt
COPY . . # 复制源码
CMD ["python", "app.py"] # 容器启动命令
然后构建并运行:
三个常见坑
- 容器一停数据就没——用
volume(-v 主机目录:容器目录)把数据挂到宿主机。 - 镜像越积越大——选用
slim/alpine基础镜像,多阶段构建(multi-stage)只留运行所需。 - 权限问题——容器里默认以 root 跑,生产环境记得用非 root 用户。
它解决了什么
| 痛点 | Docker 的解法 |
|---|---|
| 环境不一致 | 一次构建,处处运行 |
| 依赖冲突 | 每个应用隔离在各自容器 |
| 部署繁琐 | 镜像即交付物,CI/CD 直接拉取 |
Docker 不是银弹,但它把「环境」这件事,从玄学变成了可版本化、可复制的工程问题。