Docker容器化实战指南
Docker容器化技术彻底改变了软件开发和部署方式,实现了"一次构建,随处运行"的理想。本文将从实战角度介绍Docker的核心概念和最佳实践。
Docker基础概念
容器 vs 虚拟机
容器和虚拟机的关键区别在于架构和资源隔离方式:
特性 | 容器 | 虚拟机 |
---|---|---|
启动时间 | 秒级 | 分钟级 |
资源消耗 | 轻量级 | 重量级 |
隔离级别 | 进程级隔离 | 完全隔离 |
操作系统 | 共享宿主内核 | 独立客户端操作系统 |
可移植性 | 极高 | 较低 |
Docker架构
Docker采用客户端-服务器架构,主要组件包括:
- Docker引擎:运行在宿主机上的守护进程
- Docker客户端:用户通过命令行与Docker交互
- Docker镜像:应用及其依赖的只读模板
- Docker容器:镜像的运行实例
- Docker注册表:存储和分发镜像的仓库(如Docker Hub)
Docker安装与配置
在不同平台安装Docker
不同操作系统的Docker安装方式:
Linux (Ubuntu):
# 更新包索引
sudo apt-get update
# 安装必要的依赖
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
# 添加Docker的官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 设置Docker稳定版仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 安装Docker CE
sudo apt-get update
sudo apt-get install docker-ce
# 验证安装
sudo docker run hello-world
MacOS: 使用Docker Desktop for Mac,从Docker官网下载安装包。
Windows: 使用Docker Desktop for Windows,需要启用Hyper-V或WSL 2,从Docker官网下载安装包。
配置Docker镜像加速
对于中国用户,可以配置国内镜像源加速Docker镜像拉取:
// /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
配置后重启Docker服务:
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker镜像管理
基本镜像操作
# 查找镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
# 列出本地镜像
docker images
# 查看镜像详情
docker inspect nginx:latest
# 删除镜像
docker rmi nginx:latest
构建自定义镜像
使用Dockerfile创建自定义镜像是Docker的核心功能:
示例:Node.js应用Dockerfile
# 基础镜像
FROM node:16-alpine
# 设置工作目录
WORKDIR /app
# 复制package.json和package-lock.json
COPY package*.json ./
# 安装依赖
RUN npm install
# 复制源代码
COPY . .
# 构建应用
RUN npm run build
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["npm", "start"]
构建镜像:
docker build -t my-node-app:1.0 .
镜像优化技巧
减小Docker镜像大小的关键技术:
使用轻量级基础镜像:
dockerfileFROM alpine:3.14
多阶段构建:
dockerfile# 构建阶段 FROM node:16 AS builder WORKDIR /app COPY . . RUN npm ci && npm run build # 运行阶段 FROM nginx:alpine COPY --from=builder /app/build /usr/share/nginx/html
合并RUN命令:
dockerfileRUN apt-get update && \ apt-get install -y --no-install-recommends python3 && \ rm -rf /var/lib/apt/lists/*
添加.dockerignore文件:
node_modules npm-debug.log Dockerfile .git .gitignore
容器操作实战
容器生命周期管理
# 创建并启动容器
docker run -d --name my-nginx -p 8080:80 nginx
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 停止容器
docker stop my-nginx
# 启动已停止的容器
docker start my-nginx
# 重启容器
docker restart my-nginx
# 删除容器
docker rm my-nginx
容器资源限制
限制容器的CPU和内存使用:
# 限制内存为512MB,CPU使用率为50%
docker run -d --name limited-nginx \
--memory="512m" \
--cpus="0.5" \
-p 8080:80 \
nginx
容器网络配置
Docker提供了多种网络模式:
# 创建自定义网络
docker network create my-network
# 使用自定义网络启动容器
docker run -d --name db --network my-network mongo
docker run -d --name app --network my-network \
-p 8080:3000 \
my-app
持久化数据与卷管理
Docker容器中的数据默认是临时性的,可以使用卷或绑定挂载实现持久化:
# 创建卷
docker volume create my-data
# 使用卷启动容器
docker run -d --name postgres \
-v my-data:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=secret \
postgres
# 使用绑定挂载
docker run -d --name nginx \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
-p 8080:80 \
nginx
Docker Compose多容器应用
Docker Compose用于定义和运行多容器Docker应用程序:
docker-compose.yml示例
version: '3'
services:
web:
build: ./web
ports:
- "8080:80"
depends_on:
- api
environment:
- API_URL=http://api:3000
api:
build: ./api
ports:
- "3000:3000"
depends_on:
- db
environment:
- DB_HOST=db
- DB_USER=postgres
- DB_PASS=secret
volumes:
- ./api/logs:/app/logs
db:
image: postgres:13
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=myapp
volumes:
db-data:
Compose常用命令
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs -f
# 停止所有服务
docker-compose down
# 停止并删除卷
docker-compose down -v
实战案例:构建全栈应用
案例:MERN栈应用容器化
项目结构:
mern-docker/
├── docker-compose.yml
├── frontend/
│ ├── Dockerfile
│ └── ...
├── backend/
│ ├── Dockerfile
│ └── ...
└── nginx/
├── Dockerfile
└── nginx.conf
前端Dockerfile (React):
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
后端Dockerfile (Node.js/Express):
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 5000
CMD ["node", "server.js"]
docker-compose.yml:
version: '3'
services:
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
backend:
build: ./backend
ports:
- "5000:5000"
depends_on:
- mongo
environment:
- MONGO_URI=mongodb://mongo:27017/mern-app
- PORT=5000
- NODE_ENV=production
mongo:
image: mongo:latest
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
volumes:
mongo-data:
部署流程
# 克隆项目
git clone https://github.com/example/mern-docker.git
cd mern-docker
# 构建并启动容器
docker-compose up -d
# 查看运行状态
docker-compose ps
生产环境注意事项
使用生产环境变量:
yamlenvironment: - NODE_ENV=production - API_KEY=${API_KEY}
配置健康检查:
yamlhealthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3
配置日志驱动:
yamllogging: driver: "json-file" options: max-size: "10m" max-file: "3"
Docker安全最佳实践
容器安全基本原则
最小权限原则:
dockerfile# 创建非root用户 RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser
只安装必要组件:
dockerfileRUN apt-get update && \ apt-get install -y --no-install-recommends curl && \ rm -rf /var/lib/apt/lists/*
定期更新基础镜像:
bashdocker pull nginx:latest
使用内容信任:
bash# 启用Docker内容信任 export DOCKER_CONTENT_TRUST=1 docker pull nginx:latest
镜像安全扫描
使用工具扫描镜像中的漏洞:
# 使用Trivy扫描镜像
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image nginx:latest
Docker监控与调试
容器监控工具
Docker原生命令:
bash# 查看容器资源使用情况 docker stats # 查看容器进程 docker top my-container
使用Portainer进行可视化管理:
bashdocker run -d -p 9000:9000 \ --name portainer \ --restart always \ -v /var/run/docker.sock:/var/run/docker.sock \ portainer/portainer-ce
容器日志管理
# 查看容器日志
docker logs -f --tail=100 my-container
# 限制日志大小
docker run -d --log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx
CI/CD与Docker
GitHub Actions自动构建与推送Docker镜像
.github/workflows/docker-build.yml:
name: Build and Push Docker Image
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: myusername/myapp:latest
自动化部署流程
- 开发环境:本地Docker Compose开发
- 测试环境:CI工具构建镜像并推送到注册表
- 生产环境:使用Docker Swarm或Kubernetes部署
总结与最佳实践
Docker使用核心原则
- 保持镜像精简:使用多阶段构建,移除不必要的包
- 优化缓存使用:合理排列Dockerfile指令顺序
- 合理管理数据:使用卷进行数据持久化
- 网络安全配置:仅暴露必要端口,使用内部网络
- 版本控制:始终标记镜像版本,避免使用latest标签
- 资源限制:设置容器内存和CPU限制
- 健康检查:配置容器健康检查确保服务可用
- 日志管理:配置适当的日志驱动和轮转策略
Docker容器化技术不仅简化了开发流程,还大大提高了部署效率和系统可靠性。通过本文的实战指南,你已经掌握了Docker的核心概念和最佳实践,可以将其应用到自己的项目中去,实现真正的"一次构建,随处运行"。