Skip to content

Docker容器化实战指南

Docker容器化技术彻底改变了软件开发和部署方式,实现了"一次构建,随处运行"的理想。本文将从实战角度介绍Docker的核心概念和最佳实践。

Docker基础概念

容器 vs 虚拟机

容器和虚拟机的关键区别在于架构和资源隔离方式:

容器与虚拟机对比

特性容器虚拟机
启动时间秒级分钟级
资源消耗轻量级重量级
隔离级别进程级隔离完全隔离
操作系统共享宿主内核独立客户端操作系统
可移植性极高较低

Docker架构

Docker采用客户端-服务器架构,主要组件包括:

  1. Docker引擎:运行在宿主机上的守护进程
  2. Docker客户端:用户通过命令行与Docker交互
  3. Docker镜像:应用及其依赖的只读模板
  4. Docker容器:镜像的运行实例
  5. Docker注册表:存储和分发镜像的仓库(如Docker Hub)

Docker安装与配置

在不同平台安装Docker

不同操作系统的Docker安装方式:

Linux (Ubuntu):

bash
# 更新包索引
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镜像拉取:

json
// /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

配置后重启Docker服务:

bash
sudo systemctl daemon-reload
sudo systemctl restart docker

Docker镜像管理

基本镜像操作

bash
# 查找镜像
docker search nginx

# 拉取镜像
docker pull nginx:latest

# 列出本地镜像
docker images

# 查看镜像详情
docker inspect nginx:latest

# 删除镜像
docker rmi nginx:latest

构建自定义镜像

使用Dockerfile创建自定义镜像是Docker的核心功能:

示例:Node.js应用Dockerfile

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"]

构建镜像:

bash
docker build -t my-node-app:1.0 .

镜像优化技巧

减小Docker镜像大小的关键技术:

  1. 使用轻量级基础镜像

    dockerfile
    FROM alpine:3.14
  2. 多阶段构建

    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
  3. 合并RUN命令

    dockerfile
    RUN apt-get update && \
        apt-get install -y --no-install-recommends python3 && \
        rm -rf /var/lib/apt/lists/*
  4. 添加.dockerignore文件

    node_modules
    npm-debug.log
    Dockerfile
    .git
    .gitignore

容器操作实战

容器生命周期管理

bash
# 创建并启动容器
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和内存使用:

bash
# 限制内存为512MB,CPU使用率为50%
docker run -d --name limited-nginx \
  --memory="512m" \
  --cpus="0.5" \
  -p 8080:80 \
  nginx

容器网络配置

Docker提供了多种网络模式:

bash
# 创建自定义网络
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容器中的数据默认是临时性的,可以使用卷或绑定挂载实现持久化:

bash
# 创建卷
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示例

yaml
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常用命令

bash
# 启动所有服务
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):

dockerfile
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):

dockerfile
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 5000
CMD ["node", "server.js"]

docker-compose.yml:

yaml
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:

部署流程

bash
# 克隆项目
git clone https://github.com/example/mern-docker.git
cd mern-docker

# 构建并启动容器
docker-compose up -d

# 查看运行状态
docker-compose ps

生产环境注意事项

  1. 使用生产环境变量:

    yaml
    environment:
      - NODE_ENV=production
      - API_KEY=${API_KEY}
  2. 配置健康检查:

    yaml
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
  3. 配置日志驱动:

    yaml
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Docker安全最佳实践

容器安全基本原则

  1. 最小权限原则:

    dockerfile
    # 创建非root用户
    RUN addgroup -S appgroup && adduser -S appuser -G appgroup
    USER appuser
  2. 只安装必要组件:

    dockerfile
    RUN apt-get update && \
        apt-get install -y --no-install-recommends curl && \
        rm -rf /var/lib/apt/lists/*
  3. 定期更新基础镜像:

    bash
    docker pull nginx:latest
  4. 使用内容信任:

    bash
    # 启用Docker内容信任
    export DOCKER_CONTENT_TRUST=1
    docker pull nginx:latest

镜像安全扫描

使用工具扫描镜像中的漏洞:

bash
# 使用Trivy扫描镜像
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image nginx:latest

Docker监控与调试

容器监控工具

  1. Docker原生命令:

    bash
    # 查看容器资源使用情况
    docker stats
    
    # 查看容器进程
    docker top my-container
  2. 使用Portainer进行可视化管理:

    bash
    docker run -d -p 9000:9000 \
      --name portainer \
      --restart always \
      -v /var/run/docker.sock:/var/run/docker.sock \
      portainer/portainer-ce

容器日志管理

bash
# 查看容器日志
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:

yaml
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

自动化部署流程

  1. 开发环境:本地Docker Compose开发
  2. 测试环境:CI工具构建镜像并推送到注册表
  3. 生产环境:使用Docker Swarm或Kubernetes部署

总结与最佳实践

Docker使用核心原则

  1. 保持镜像精简:使用多阶段构建,移除不必要的包
  2. 优化缓存使用:合理排列Dockerfile指令顺序
  3. 合理管理数据:使用卷进行数据持久化
  4. 网络安全配置:仅暴露必要端口,使用内部网络
  5. 版本控制:始终标记镜像版本,避免使用latest标签
  6. 资源限制:设置容器内存和CPU限制
  7. 健康检查:配置容器健康检查确保服务可用
  8. 日志管理:配置适当的日志驱动和轮转策略

Docker容器化技术不仅简化了开发流程,还大大提高了部署效率和系统可靠性。通过本文的实战指南,你已经掌握了Docker的核心概念和最佳实践,可以将其应用到自己的项目中去,实现真正的"一次构建,随处运行"。