Skip to content

Docker 与 Docker Compose ​

Phase 07 — Engineering · 知识点 08–09:Docker · Docker Compose


1. 学习目标 ​

完成本知识点后,你应该能够:

  • 理解 Docker 镜像、容器、Volume、Network 核心概念
  • 编写多阶段 Dockerfile 构建 Go 服务静态二进制镜像
  • 使用 Docker Compose 编排 Go、PostgreSQL、Redis
  • 通过环境变量向容器注入 Configuration
  • 配置健康检查(healthcheck)与依赖启动顺序
  • 实现 docker compose up 一键启动数字孪生后端完整依赖

2. 为什么需要 ​

「在我机器上能跑」是协作和部署的大敌。Docker 把 Go 二进制、运行时依赖、PostgreSQL、Redis 打包成可复现环境,新成员无需手动安装数据库即可联调 Three.js 前端。

本路线不包含 Kubernetes——Docker Compose 足够支撑 Project 03 本地开发与中小型生产前验证。


3. 核心概念 ​

3.1 Docker 核心 ​

概念说明
Image只读模板,类似「类」
ContainerImage 的运行实例,类似「对象」
Dockerfile构建 Image 的脚本
Volume持久化数据(PostgreSQL 数据目录)
Network容器间通信(Compose 默认 bridge 网络)

3.2 Go 多阶段构建 ​

Stage 1 (builder): golang:1.22-alpine → 编译静态二进制
Stage 2 (runtime):  alpine/scratch   → 仅复制二进制,镜像 ~20MB

3.3 Docker Compose ​

  • 单文件 docker-compose.yml 定义多服务
  • docker compose up -d 后台启动
  • 服务名即 DNS 主机名:postgres:5432、redis:6379

4. 基础语法 ​

4.1 Dockerfile(Go 服务) ​

dockerfile
# syntax=docker/dockerfile:1

FROM golang:1.22-alpine AS builder
WORKDIR /app
RUN apk add --no-cache git ca-certificates
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server ./cmd/server

FROM alpine:3.19
RUN apk add --no-cache ca-certificates tzdata
WORKDIR /app
COPY --from=builder /server .
EXPOSE 8080
USER nobody
ENTRYPOINT ["./server"]

4.2 docker-compose.yml ​

yaml
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      APP_ENV: development
      HTTP_ADDR: ":8080"
      DATABASE_URL: postgres://twin:twin@postgres:5432/twin?sslmode=disable
      REDIS_ADDR: redis:6379
      LOG_LEVEL: debug
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
      interval: 10s
      timeout: 3s
      retries: 3

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: twin
      POSTGRES_PASSWORD: twin
      POSTGRES_DB: twin
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U twin -d twin"]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    image: redis:7-alpine
    volumes:
      - redisdata:/data

volumes:
  pgdata:
  redisdata:

4.3 .dockerignore ​

.git
workspace/
exercises/
docs/
*.md
.env

减小 build context,加快构建。

4.4 常用命令 ​

bash
docker compose build          # 构建镜像
docker compose up -d          # 后台启动
docker compose logs -f app    # 查看日志
docker compose ps             # 状态
docker compose down           # 停止并移除容器
docker compose down -v        # 同时删除 volume(慎用)

5. 代码解析 ​

CGO_ENABLED=0:纯 Go 静态链接,runtime 镜像无需 glibc 依赖。

depends_on + condition: service_healthy:避免 app 在 PostgreSQL 未就绪时连接失败。

USER nobody:非 root 运行,降低容器逃逸风险。

环境变量 DATABASE_URL:主机名用服务名 postgres,不是 localhost(容器内 localhost 指向自身)。

Volume:docker compose down 不删 volume,数据保留;-v 才清空。


6. JavaScript / TypeScript 对比 ​

概念前端Docker
环境隔离nvm / volta容器 OS 级隔离
依赖安装npm cigo mod download in build
多服务手动开多个终端Compose 一键
环境变量Vite .envCompose environment
部署产物静态文件 dist/Docker Image

前端 npm run dev 类比 docker compose up,但 Docker 包含后端依赖服务。


7. 常见错误 ​

错误 1:DATABASE_URL 使用 localhost ​

Compose 网络内应使用服务名 postgres。

错误 2:镜像过大 ​

未使用多阶段构建,把源码和 Go toolchain 打进 runtime 镜像。

错误 3:未配置 healthcheck ​

app 启动时 DB 未就绪,连接失败后崩溃且不重启。

错误 4:把 .env secrets 写进 compose 并提交 ​

生产用 secrets 或 CI 注入,compose 文件用 ${DATABASE_URL} 占位。

错误 5:开发时每次改代码都 rebuild ​

本地开发可只容器化 DB/Redis,Go 服务 go run 在宿主机;或使用 air 热重载 + 挂载 volume。


8. 实际应用 ​

Project 03 Docker 交付 ​

docker compose up -d
# → PostgreSQL 就绪
# → Redis 就绪
# → Go 服务 :8080
# → Three.js 前端连接 ws://localhost:8080/ws

验收:

  • curl http://localhost:8080/health → {"status":"ok"}
  • WebSocket 连接正常
  • 重启 docker compose restart app 数据不丢(PostgreSQL volume)

生产注意(Phase 08):

  • Compose 可用于单机生产,多机需其他方案(本路线不展开 K8s)
  • 镜像推送到 Registry(GHCR、Docker Hub)
  • 不在镜像内包含 .env

9. 深入理解 ​

9.1 BuildKit 缓存 ​

bash
DOCKER_BUILDKIT=1 docker compose build

go mod download 层缓存加速重复构建。

9.2 网络模式 ​

  • ports: "8080:8080":宿主机访问
  • 容器间:服务名 DNS,无需暴露端口

9.3 WebSocket 与 Docker ​

无特殊配置;Nginx 反向代理时注意 Upgrade header(Phase 08)。


10. 练习 ​

详细练习见 exercises/phase-07-engineering/03-docker-compose.md。

Level 1 — 基础 ​

练习 1.1:编写 Dockerfile,docker build -t twin-server . 成功。

练习 1.2:添加 .dockerignore,对比 build context 大小。

Level 2 — 应用 ​

练习 2.1:Compose 添加 postgres + redis,app 连接成功。

练习 2.2:为 postgres 和 app 配置 healthcheck。

Level 3 — 综合 ​

练习 3.1:环境变量切换 LOG_LEVEL=debug 与 info,验证日志差异。

练习 3.2:docker compose down -v 后重新 up,验证 DB 初始化迁移。

Level 4 — 项目实践 ​

练习 4.1:Project 03 Phase 07 里程碑 — 完整 Compose + README 一键启动说明。


11. 学习检查 ​

  1. 多阶段构建的优势是什么?
  2. Compose 内容器如何访问 PostgreSQL?
  3. Volume 与 bind mount 区别?
  4. 为什么 runtime 镜像用 CGO_ENABLED=0?
  5. healthcheck 解决什么问题?

12. 下一步 ​

已完成下一知识点关系
Docker · Docker ComposePhase 08 — Linux · SSH · Process · Port容器本地就绪 → 服务器部署

Phase 07 完成后,Project 03 具备测试与容器化能力。Phase 08 将学习在 Linux 服务器上部署 Go 二进制并通过 Nginx 对外提供 HTTPS/WSS。


学习导航 ​

上一篇:测试与性能基准 · 对应练习 · 下一篇:Linux 运维基础