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...,确保每次拉取的镜像内容完全一致,避免标签被覆盖导致的不一致问题。
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。
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。