Docker入门指南2026:彻底搞懂容器技术
Docker入门指南2026:彻底搞懂容器技术
从零学Docker。用实战示例理解容器、镜像、Dockerfile和Docker Compose。
为什么开发者必须学Docker?
"在我的电脑上是好的"——这句话几乎是每个开发者说过的经典台词。环境差异、依赖冲突、配置不一致,这些问题困扰着无数开发团队。Docker的出现彻底解决了这个问题。
2026年,Docker不再只是DevOps工程师的专属工具,它已经成为每个现代开发者必须掌握的基础技能。无论你是后端开发者、全栈工程师还是数据科学家,Docker都能让你的工作更高效、更可靠。
核心概念:容器 vs 虚拟机
虚拟机(VM)
虚拟机模拟完整的硬件环境,运行完整的操作系统。每个VM包含:
- 客户操作系统(几GB)
- 应用程序及其依赖
- 通过Hypervisor与宿主机隔离
问题:启动慢(分钟级)、资源消耗大、体积庞大。
容器(Container)
容器共享宿主机的操作系统内核,只打包应用程序和必要的依赖:
| 对比项 | 虚拟机 | 容器 |
|---|---|---|
| 启动时间 | 1-2分钟 | 秒级 |
| 磁盘占用 | GB级 | MB级 |
| 内存开销 | 大 | 小 |
| 隔离程度 | 完全隔离 | 进程级隔离 |
| 可移植性 | 中等 | 极高 |
Docker核心组件
镜像(Image)
Docker镜像是容器的蓝图,是一个只读的分层文件系统。你可以把镜像理解为应用程序的"快照",包含了运行应用所需的一切:代码、运行时、库、环境变量和配置文件。
容器(Container)
容器是镜像的运行实例。一个镜像可以启动多个容器。容器可以启动、停止、移动和删除。
Dockerfile
Dockerfile是构建镜像的脚本,包含一系列指令,告诉Docker如何构建镜像。
Docker Registry
Registry是存储和分发镜像的地方。Docker Hub是最大的公共Registry,你也可以搭建私有Registry。
安装Docker
访问https://www.docker.com/products/docker-desktop下载适合你系统的Docker Desktop,包括Mac、Windows和Linux版本。
安装完成后验证:
docker --version
# Docker version 25.0.3, build 4debf41
docker run hello-world
# 运行第一个容器,验证安装是否成功
常用Docker命令速查
# 镜像操作
docker pull nginx # 拉取镜像
docker images # 列出本地镜像
docker rmi nginx # 删除镜像
docker build -t myapp . # 从Dockerfile构建镜像
# 容器操作
docker run nginx # 运行容器
docker run -d nginx # 后台运行
docker run -p 8080:80 nginx # 端口映射(宿主机:容器)
docker run -v /host:/container nginx # 挂载卷
docker ps # 列出运行中的容器
docker ps -a # 列出所有容器(含已停止)
docker stop <container_id> # 停止容器
docker rm <container_id> # 删除容器
docker logs <container_id> # 查看容器日志
docker exec -it <id> bash # 进入容器终端
# 网络操作
docker network ls # 列出网络
docker network create mynet # 创建网络
编写你的第一个Dockerfile
以一个Node.js应用为例:
// app.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.json({
message: 'Hello from Docker!',
timestamp: new Date().toISOString()
});
});
app.get('/health', (req, res) => {
res.json({ status: 'healthy' });
});
app.listen(PORT, () => {
console.log(`服务器运行在端口 ${PORT}`);
});
// package.json
{
"name": "docker-demo",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.18.2"
}
}
# Dockerfile
# 第一步:选择基础镜像
FROM node:20-alpine
# 第二步:设置工作目录
WORKDIR /app
# 第三步:复制依赖文件(利用Docker缓存层优化构建速度)
COPY package*.json ./
# 第四步:安装依赖
RUN npm ci --only=production
# 第五步:复制应用代码
COPY . .
# 第六步:暴露端口
EXPOSE 3000
# 第七步:定义非root用户(安全最佳实践)
USER node
# 第八步:启动命令
CMD ["node", "app.js"]
构建和运行:
# 构建镜像
docker build -t my-node-app .
# 运行容器
docker run -d -p 3000:3000 --name my-app my-node-app
# 测试
curl http://localhost:3000
# {"message":"Hello from Docker!","timestamp":"2026-03-17T..."}
.dockerignore文件
类似.gitignore,避免将不必要的文件复制到镜像中:
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.env.*
Dockerfile
.dockerignore
Docker Compose:多容器应用管理
实际应用通常需要多个服务协同工作(如Web服务器 + 数据库 + 缓存)。Docker Compose让管理多容器应用变得简单。
# docker-compose.yml
version: '3.8'
services:
# Web应用服务
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:password@db:5432/mydb
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
restart: unless-stopped
networks:
- app-network
# PostgreSQL数据库
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
# Redis缓存
cache:
image: redis:7-alpine
volumes:
- redis_data:/data
networks:
- app-network
# Nginx反向代理
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./ssl:/etc/ssl/certs
depends_on:
- app
networks:
- app-network
volumes:
postgres_data:
redis_data:
networks:
app-network:
driver: bridge
Docker Compose常用命令:
docker-compose up -d # 启动所有服务(后台)
docker-compose down # 停止并删除容器
docker-compose down -v # 同时删除数据卷
docker-compose logs -f app # 追踪查看app服务日志
docker-compose ps # 查看服务状态
docker-compose exec app bash # 进入app容器
docker-compose build # 重新构建镜像
docker-compose restart # 重启所有服务
Docker多阶段构建
多阶段构建可以显著减小最终镜像的体积:
# 多阶段构建示例(Go应用)
# 阶段1:构建
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# 阶段2:最终镜像(极小体积)
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
构建后镜像体积可以从几百MB缩减到几十MB。
实用技巧和最佳实践
1. 层缓存优化
将不常变化的内容放在Dockerfile前面,充分利用缓存层:
# 好的做法:先复制依赖文件,再复制代码
COPY package*.json ./
RUN npm install
COPY . . # 代码改变不会使npm install缓存失效
# 不好的做法:先复制全部内容
COPY . . # 任何文件变化都会重新安装依赖
RUN npm install
2. 使用具体的镜像版本
# 好
FROM node:20.11.1-alpine3.19
# 不好(不可预测)
FROM node:latest
3. 健康检查
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
总结
Docker的学习曲线并不陡峭,但它带来的收益是巨大的。从"在我机器上是好的"到"在任何地方都好用",Docker帮助开发团队消除环境差异,简化部署流程,提高协作效率。
掌握本文介绍的核心概念——镜像、容器、Dockerfile和Docker Compose——你就已经具备了在实际项目中使用Docker的基础能力。下一步,可以学习Kubernetes,了解如何在生产环境中编排和管理大规模容器集群。