Docker 入门:从零理解容器化(2026 完整指南)

「在我电脑上是好的」——这句开发者的口头禅,道出了环境不一致的痛点。Docker 是一个开源的容器化平台,它把应用连同运行时、依赖、配置打包成一个标准化的"集装箱",让它在任何 Linux/Windows/macOS 上都能跑出一致的行为。这份 Docker 入门教程 适合 docker for beginners,从概念、命令、Dockerfile 到 Compose 一条路走通。

四个核心概念

在动手敲命令前,先把四个名词搞清楚——这是后续所有内容的根基:

镜像(Image)

只读模板,类似面向对象里的"类"。一个镜像可以包含完整的 Ubuntu 系统 + Node.js + 你的应用代码。镜像采用分层存储(Union File System),每一层对应 Dockerfile 的一条指令,便于复用与缓存。

容器(Container)

镜像的运行实例,类似"对象"。同一个镜像可以启动多个容器,彼此隔离。从 Docker 镜像 vs 容器 的角度看:镜像是静态的"图纸",容器是动态的"建筑"。

镜像层(Layer)

每条 Dockerfile 指令都会生成一层。多个镜像共享相同基础层时只占用一份磁盘空间,这也是 alpine 镜像能小到 5MB 的原因。

仓库(Registry)

镜像的"GitHub"。公网用 Docker Hub,企业常用私有仓库 Harbor、云厂商的 AWS ECR / GCP Artifact Registry

Docker 容器 vs 虚拟机

很多人第一次接触容器都会问"和虚拟机啥区别",下面这张表讲清楚:

维度 · 容器 · 虚拟机

启动速度 · 秒级 · 分钟级

磁盘占用 · MB 级 · GB 级

性能损失 · 接近原生 · 有 hypervisor 开销(≈5–15%)

操作系统 · 共享宿主机内核 · 独立运行完整 OS

隔离级别 · 进程级(namespaces + cgroups)· 硬件级(CPU/内存/IO 划分)

密度 · 单机可跑数百容器 · 单机通常跑十几台 VM

简单记:容器是"进程",虚拟机是"电脑"。容器轻、密、快,VM 重、隔、强。

5 大核心命令

日常 90% 的操作都离不开这几条 Docker 命令,建议收藏:

① docker pull — 拉镜像

docker pull nginx:latest
docker pull node:20-alpine
docker pull postgres:16

tag(冒号后)指定版本;不写默认是 latest,生产环境严禁用 latest。

② docker images — 列本地镜像

docker images
docker images -a          # 含中间层
docker image prune -a     # 清理悬空镜像

③ docker run — 启动容器(最常用)

docker run -d -p 8080:80 --name mynginx nginx

常用参数速记:

④ docker ps — 列容器

docker ps          # 仅运行中
docker ps -a       # 含已停止的
docker stop mynginx
docker rm mynginx

⑤ docker logs / exec — 调试必备

docker logs -f mynginx       # -f 持续跟随(类似 tail -f)
docker logs --tail 100 mynginx
docker exec -it mynginx sh   # 进容器(Alpine 用 sh,Ubuntu 用 bash)

Dockerfile 教程

Dockerfile 是镜像的"源代码"。下面是一条生产可用的 Node.js 示例,每行注释清楚:

FROM node:20-alpine          # 基础镜像,alpine 体积小
WORKDIR /app                # 设置工作目录(推荐用,别再 RUN cd)
COPY package*.json ./        # 先复制 package.json 利用缓存
RUN npm ci --only=production # ci 比 install 更快、更严格
COPY . .                    # 复制剩余源码
EXPOSE 3000                 # 声明端口(仅文档作用,不真发布)
CMD ["node", "server.js"]   # 启动命令(推荐 JSON 数组形式)

常用指令速查:

⚠️ 重要:CMD 和 ENTRYPOINT 推荐用 JSON 数组形式 ["node", "server.js"],避免 shell 形式把 PID 1 变成 sh 接收不到 SIGTERM,导致 docker stop 要等 10 秒。

多阶段构建(Multi-stage)

Go、Java、Rust 这类编译型语言,传统做法是把整个 SDK 塞进镜像,结果一个 hello world 都要 800MB。多阶段构建 思路是:第一个阶段编译,第二个阶段只拿产物:

# Stage 1: 编译
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# Stage 2: 运行时(仅几 MB 的 alpine)
FROM alpine:3.19
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD ["myapp"]

最终镜像通常 10–20MB,比单阶段缩小 30–50 倍,安全面也更小。

Docker Compose 教程

真实项目不会只有一个容器——Web、DB、Redis、消息队列需要一起编排。Docker Compose 用一个 YAML 文件描述多容器应用:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data:

关键命令:

docker compose up -d       # 后台启动全部服务
docker compose down        # 停止并删除容器、网络
docker compose ps          # 看服务状态
docker compose logs -f web # 看 web 服务日志

📌 注意:Docker 20.10+ 已把 docker-compose(带连字符)合并为 docker compose(空格)子命令,老教程里两种写法都会出现。

4 个实战场景

① 本地开发环境

一行命令拉起 MySQL/Redis/Elasticsearch,比装本地服务干净得多,删掉 -v 卷就重置。

docker run -d --rm -p 6379:6379 --name redis redis:7-alpine
docker run -d --rm -p 9200:9200 -e discovery.type=single-node \
  --name es elasticsearch:8.13.0

② CI/CD(GitHub Actions)

在 CI 里 docker builddocker push 到 registry,部署机 docker pull 重启,发布链路就成型了。

③ 微服务

每个服务一个容器 + 一个 Dockerfile,docker compose 把 order、user、inventory、payment 串起来,本地一键起完整链路。

④ 云原生(Kubernetes)

当容器数量上百、需要滚动升级、自动扩缩容时,Kubernetes(K8s) 登场。Docker 负责"打包",K8s 负责"调度"。

3 个常见陷阱

① 不要在 Dockerfile 里写 secrets
密码、API key 一旦写进 ENVRUN,就会永久留在镜像层里,docker history 能看到。正解是用 docker secret、CI 变量、或运行时 -e 注入。

② 用更小的基础镜像
同样是 Node 20,node:20 ≈ 1GB,node:20-alpine ≈ 50MB,distroless ≈ 30MB。生产环境优先 alpine / distroless。

③ 别忘了 .dockerignore
node_modules.gitdist 不应该被打进镜像,否则不仅体积大,还可能泄露源码:

# .dockerignore
node_modules
.git
.env
*.log
dist

推荐使用专业编辑器(VS Code + Docker 插件)来编写 Dockerfile,需要预览效果时可以用 DevToolbox 的 Markdown 预览工具 把说明文档贴进去检查渲染。

常见问题(FAQ)

Docker 和 Kubernetes 什么关系?

Docker 是容器引擎,负责"打包和运行单个容器";Kubernetes(K8s) 是容器编排系统,负责"管理成百上千个容器的部署、扩缩容、滚动升级、自愈"。类比:Docker 是发动机,K8s 是整车调度系统。

为什么容器一启动就退出?

容器生命周期 = 里面 PID 1 进程的生命周期。最常见两种情况:① CMD 写的是后台命令(比如 nginx &),前台立刻空,容器退出;② 没分配 tty 又没前台进程。改成 CMD ["nginx", "-g", "daemon off;"]["node", "server.js"](前台运行)即可。

如何减小镜像体积?

三板斧:① 多阶段构建分离编译/运行环境;② 基础镜像换 alpinedistroless;③ RUN apt-get update && apt-get install -y ... && rm -rf /var/lib/apt/lists/* 清理 apt 缓存。

容器里的数据怎么持久化?

volumes(推荐,由 Docker 管理,存 /var/lib/docker/volumes/)或 bind mount(直接挂主机目录)。例如 -v pgdata:/var/lib/postgresql/data

生产环境用 Docker 安全吗?

本身安全,但要做到:① 扫描漏洞(trivy / docker scout);② 不用 root 运行USER node);③ 固定 tag,避免 latest;④ 定期重建镜像,引入基础镜像的安全补丁。

结论

Docker 已经是后端开发的事实标准。Docker 入门 的关键不是背命令,而是建立"镜像 = 类、容器 = 对象、分层 = 复用、Compose = 多服务编排"的模型思维。把这篇 Docker 教程 收藏起来,动手跑一遍 docker run nginx、写一个 Dockerfile、用 Compose 起一个 web+db,30 分钟就能上手。

打开 DevToolbox → https://devstoolbox.net,配合 JSON / YAML / 正则工具一起使用,效率翻倍。

相关文章

JSON 格式化完全指南(docker-compose.yml 调试时常需 JSON 工具对比结构)

正则表达式速查表(解析 docker logs 输出时高频使用)