外观
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 | 只读模板,类似「类」 |
| Container | Image 的运行实例,类似「对象」 |
| Dockerfile | 构建 Image 的脚本 |
| Volume | 持久化数据(PostgreSQL 数据目录) |
| Network | 容器间通信(Compose 默认 bridge 网络) |
3.2 Go 多阶段构建
Stage 1 (builder): golang:1.22-alpine → 编译静态二进制
Stage 2 (runtime): alpine/scratch → 仅复制二进制,镜像 ~20MB3.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 ci | go mod download in build |
| 多服务 | 手动开多个终端 | Compose 一键 |
| 环境变量 | Vite .env | Compose 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 buildgo 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. 学习检查
- 多阶段构建的优势是什么?
- Compose 内容器如何访问 PostgreSQL?
- Volume 与 bind mount 区别?
- 为什么 runtime 镜像用
CGO_ENABLED=0? - healthcheck 解决什么问题?
12. 下一步
| 已完成 | 下一知识点 | 关系 |
|---|---|---|
| Docker · Docker Compose | Phase 08 — Linux · SSH · Process · Port | 容器本地就绪 → 服务器部署 |
Phase 07 完成后,Project 03 具备测试与容器化能力。Phase 08 将学习在 Linux 服务器上部署 Go 二进制并通过 Nginx 对外提供 HTTPS/WSS。