Docker容器化缓存一致性治理部署与调试指南 - 第2节

2.1 Docker 核心概念:镜像、容器、仓库

Docker 的三大核心概念构成了容器化技术的基石。理解镜像、容器与仓库之间的关系,是掌握 Docker 操作的第一步。镜像是一个只读的、轻量级的可执行软件包,包含运行应用程序所需的一切(代码、运行时、系统工具、库和设置)。容器是镜像的运行实例,具有独立的文件系统、网络和进程空间。仓库则用于存储和分发镜像。

核心关系速记: 镜像(类)→ 容器(对象)→ 仓库(Git 远程仓库)。镜像通过 docker run 实例化为容器,通过 docker push/pull 与仓库交互。

2.1.1 镜像与容器的生命周期对比

维度 镜像 (Image) 容器 (Container)
本质 只读模板,分层文件系统 镜像的读写实例,包含运行态
创建 docker build 或 docker pull docker create 或 docker run
状态 静态,不可变 运行中、已停止、暂停、已删除
存储 镜像层缓存,可复用 容器层(可写层),容器删除后数据丢失(除非挂载卷)
标识 repository:tag 或 image_id container_name 或 container_id

2.1.2 仓库类型与镜像命名规范

  • 官方仓库(Docker Hub): 默认公共仓库,镜像名如 nginx:latest、python:3.11-slim。
  • 私有仓库(Registry): 企业自建或云厂商提供(如 Harbor、AWS ECR、阿里云 ACR),镜像名需包含仓库地址,如 registry.example.com/myapp:v1.0。
  • 镜像标签(Tag)规范: 建议使用语义化版本号 + 环境标识,例如 app-backend:1.2.3-prod。避免使用 latest 作为生产部署标签。
最佳实践: 生产环境中始终使用精确的镜像摘要(Digest)进行部署,例如 nginx@sha256:abc123...,确保每次拉取的镜像内容完全一致,避免标签被覆盖导致的不一致问题。
Docker 三大核心概念关系图 仓库 (Registry) 存储与分发镜像 镜像 (Image) 只读模板,分层构建 容器 (Container) 运行实例,可写层 docker pull docker run docker push 核心工作流 从仓库拉取镜像 → 基于镜像创建容器 → 修改后提交为新镜像 → 推送回仓库

2.2 Dockerfile 编写规范

Dockerfile 是构建镜像的自动化脚本,其编写质量直接影响镜像的安全性、构建速度和运行时性能。以下规范基于生产环境最佳实践总结。

2.2.1 基础指令与执行顺序

指令 用途 关键规范
FROM 指定基础镜像 优先使用官方 slim 或 alpine 版本;必须指定精确 tag
WORKDIR 设置工作目录 始终使用绝对路径,避免 RUN cd 导致的路径混乱
COPY / ADD 添加文件到镜像 优先使用 COPY;ADD 仅用于自动解压 tar 或远程 URL 场景
RUN 执行构建命令 合并同类命令减少层数;使用 && 连接,末尾清理缓存
CMD / ENTRYPOINT 定义容器启动命令 推荐组合使用:ENTRYPOINT 固定执行程序,CMD 提供默认参数
EXPOSE 声明容器监听端口 仅作文档用途,不实际映射端口;需配合 -p 或 docker-compose 使用

2.2.2 多阶段构建与缓存优化

多阶段构建(Multi-stage Build)是减少镜像体积的核心手段。通过在一个 Dockerfile 中使用多个 FROM 语句,将编译环境与运行环境分离。

# 第一阶段:编译环境
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp .

# 第二阶段:运行环境
FROM alpine:3.19
RUN apk add --no-cache ca-certificates tzdata
WORKDIR /app
COPY --from=builder /app/myapp .
EXPOSE 8080
ENTRYPOINT ["./myapp"]
常见陷阱: 不要在 RUN 指令中直接使用 apt-get upgrade 或 yum update,这会导致基础镜像版本漂移,破坏构建可重复性。应始终锁定基础镜像的精确版本。

2.2.3 .dockerignore 文件

在构建上下文中排除不必要的文件,可显著提升构建速度并避免敏感信息泄露。典型 .dockerignore 内容:

node_modules/
.git/
.env
*.md
Dockerfile
.dockerignore
dist/
__pycache__/
*.log

2.3 docker-compose 编排入门

docker-compose 通过 YAML 文件定义和运行多容器应用,是本地开发环境和 CI 测试中最常用的编排工具。它解决了手动管理多个 docker run 命令的痛点。

2.3.1 docker-compose.yml 核心结构

一个标准的 Compose 文件包含三个顶级字段:services(定义容器)、networks(定义网络)、volumes(定义持久化存储)。

version: '3.8'

services:
  web:
    build: ./web
    ports:
      - "8080:80"
    depends_on:
      - redis
    environment:
      - REDIS_HOST=redis
    networks:
      - app-net

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    networks:
      - app-net

volumes:
  redis-data:

networks:
  app-net:
    driver: bridge

2.3.2 常用命令速查

命令 用途 说明
docker-compose up -d 启动所有服务(后台) 自动构建不存在的镜像
docker-compose down 停止并移除所有容器、网络 默认不删除卷,加 -v 删除卷
docker-compose logs -f 实时查看所有服务日志 可指定服务名如 logs web
docker-compose exec web sh 进入运行中的容器 类似 docker exec,但自动识别服务
docker-compose build 重新构建所有服务镜像 加 --no-cache 强制全量构建
开发效率技巧: 在 docker-compose.yml 中使用 volumes 挂载本地代码目录到容器内,实现代码修改后容器内即时生效,无需每次重新构建镜像。例如:./web:/app。
docker-compose 多服务编排架构 外部客户端 Web 服务 (Nginx + PHP) 端口映射 8080:80 depends_on Redis 缓存 持久化卷挂载 内部网络:app-net (bridge 驱动) 服务间通过服务名(web、redis)直接通信,无需 IP 硬编码

2.3.3 环境变量与配置管理

避免在 docker-compose.yml 中硬编码敏感信息。推荐使用 .env 文件或 Docker Secrets 管理配置。

# .env 文件(与 docker-compose.yml 同级)
DB_HOST=postgres
DB_PORT=5432
DB_USER=app_user
DB_PASSWORD=${DB_PASSWORD:-default_dev_pass}

# docker-compose.yml 中引用
services:
  app:
    image: myapp:latest
    environment:
      - DB_HOST=${DB_HOST}
      - DB_PORT=${DB_PORT}
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
生产环境提示: 在 CI/CD 流水线中,通过 --env-file 参数指定不同环境的配置文件,实现开发、测试、生产环境的配置分离。例如:docker-compose --env-file .env.prod up -d。