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
常用参数速记:
-d:后台运行(detached)-it:分配交互式终端(常用于进 shell)--rm:容器停止后自动删除-p 8080:80:端口映射(主机端口:容器端口)-v /host:/container:挂载卷(持久化数据)-e KEY=VALUE:注入环境变量--name myname:给容器起个名字(不写会随机)
④ 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 数组形式)
常用指令速查:
FROM:基础镜像,必须第一条WORKDIR:工作目录(每次执行都生效)COPY:本地复制文件(优于 ADD,除非要远程 URL/解压 tar)RUN:构建时执行的命令(会写入新的一层)ENV:设置环境变量EXPOSE:文档性声明端口CMD:容器启动命令(可被docker run覆盖)ENTRYPOINT:固定入口(CMD 变成它的参数)
⚠️ 重要: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 build、docker push 到 registry,部署机 docker pull 重启,发布链路就成型了。
③ 微服务
每个服务一个容器 + 一个 Dockerfile,docker compose 把 order、user、inventory、payment 串起来,本地一键起完整链路。
④ 云原生(Kubernetes)
当容器数量上百、需要滚动升级、自动扩缩容时,Kubernetes(K8s) 登场。Docker 负责"打包",K8s 负责"调度"。
3 个常见陷阱
① 不要在 Dockerfile 里写 secrets
密码、API key 一旦写进 ENV 或 RUN,就会永久留在镜像层里,docker history 能看到。正解是用 docker secret、CI 变量、或运行时 -e 注入。
② 用更小的基础镜像
同样是 Node 20,node:20 ≈ 1GB,node:20-alpine ≈ 50MB,distroless ≈ 30MB。生产环境优先 alpine / distroless。
③ 别忘了 .dockerignorenode_modules、.git、dist 不应该被打进镜像,否则不仅体积大,还可能泄露源码:
# .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"](前台运行)即可。
如何减小镜像体积?
三板斧:① 多阶段构建分离编译/运行环境;② 基础镜像换 alpine 或 distroless;③ 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 输出时高频使用)