Docker 入门:把环境装进一个集装箱

「在我电脑上明明能跑!」——每个开发者都听过这句话。Docker 的出现,就是为了让这句话从此失效:把应用连同它的运行环境,一起装进一个标准化集装箱(容器),到哪都能原样跑。

镜像 vs 容器

这是新手最容易混的一对概念:

  • 镜像(Image):一个只读的模板,相当于「安装盘」。里面是操作系统、依赖、代码。
  • 容器(Container):镜像运行起来的实例,相当于「装好系统的电脑」。

类比:镜像是类(class),容器是对象(instance)。

第一个容器

# 拉取并运行一个 hello-world 镜像
docker run hello-world

# 跑一个 nginx 并把 80 端口映射到本机 8080
docker run -d -p 8080:80 --name my-nginx nginx

-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"]        # 容器启动命令

然后构建并运行:

docker build -t my-app .
docker run -p 5000:5000 my-app

三个常见坑

  1. 容器一停数据就没——用 volume-v 主机目录:容器目录)把数据挂到宿主机。
  2. 镜像越积越大——选用 slim/alpine 基础镜像,多阶段构建(multi-stage)只留运行所需。
  3. 权限问题——容器里默认以 root 跑,生产环境记得用非 root 用户。

它解决了什么

痛点Docker 的解法
环境不一致一次构建,处处运行
依赖冲突每个应用隔离在各自容器
部署繁琐镜像即交付物,CI/CD 直接拉取

Docker 不是银弹,但它把「环境」这件事,从玄学变成了可版本化、可复制的工程问题。