5.0 KiB
5.0 KiB
Docker 构建指南
前提条件
- Docker 20.10+
- Cargo.lock 已存在(
cargo generate-lockfile) - 网络能够访问 crates.io
快速开始
# 构建全部镜像(默认 registry=myapp, tag=latest)
./docker/build.sh
# 构建指定镜像
./docker/build.sh app
./docker/build.sh gitserver email-worker
# 指定 registry 和 tag
REGISTRY=myregistry TAG=v1.0.0 ./docker/build.sh
镜像列表
| 镜像 | Dockerfile | 二进制 | 实例类型 | 说明 |
|---|---|---|---|---|
myapp/app:latest |
app.Dockerfile |
app |
多实例 | 主 Web 服务(API + WS) |
myapp/gitserver:latest |
gitserver.Dockerfile |
gitserver |
单实例 | Git HTTP + SSH 服务 |
myapp/email-worker:latest |
email-worker.Dockerfile |
email-worker |
单实例 | 邮件发送 Worker |
myapp/git-hook:latest |
git-hook.Dockerfile |
git-hook |
单实例 | Git Hook 事件处理 |
myapp/migrate:latest |
migrate.Dockerfile |
migrate |
Job/InitContainer | 数据库迁移 CLI |
部署架构
┌─ NATS ─┐
│ │
┌─────────┐ ┌──────────────┐ ┌─────────────────┐
│ LB/ │───▶│ app (×N) │ │ git-hook │
│ nginx │ │ (stateless) │ │ (单实例) │
└─────────┘ └──────────────┘ └─────────────────┘
┌──────────────┐
│ gitserver │
│ (单实例) │ ┌─────────────────┐
│ HTTP :8022 │───▶│ email-worker │
│ SSH :2222 │ │ (单实例) │
└──────────────┘ └─────────────────┘
环境变量
所有配置通过环境变量注入,无需修改镜像:
| 变量 | 示例 | 说明 |
|---|---|---|
APP_DATABASE_URL |
postgres://user:pass@host:5432/db |
数据库连接 |
APP_REDIS_URLS |
redis://host:6379 |
Redis(多实例用逗号分隔) |
APP_SMTP_HOST |
smtp.example.com |
SMTP 服务器 |
APP_SMTP_USERNAME |
noreply@example.com |
SMTP 用户名 |
APP_SMTP_PASSWORD |
xxx |
SMTP 密码 |
APP_SMTP_FROM |
noreply@example.com |
发件人地址 |
APP_AI_BASIC_URL |
https://api.openai.com/v1 |
AI API 地址 |
APP_AI_API_KEY |
sk-xxx |
AI API Key |
APP_DOMAIN_URL |
https://example.com |
主域名 |
APP_LOG_LEVEL |
info |
日志级别: trace/debug/info/warn/error |
APP_SSH_DOMAIN |
git.example.com |
Git SSH 域名 |
APP_REPOS_ROOT |
/data/repos |
Git 仓库存储路径 |
NATS_URL |
nats://localhost:4222 |
NATS 服务器地址 |
数据库迁移
镜像启动前先运行迁移:
# 方式一:直接运行
docker run --rm \
--env-file .env \
myapp/migrate:latest up
# 方式二:Kubernetes InitContainer
# 见下方 K8s 示例
Kubernetes 部署示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 3
template:
spec:
containers:
- name: app
image: myapp/app:latest
envFrom:
- secretRef:
name: app-secrets
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitserver
spec:
replicas: 1
template:
spec:
containers:
- name: gitserver
image: myapp/gitserver:latest
ports:
- containerPort: 8022 # HTTP
- containerPort: 2222 # SSH
envFrom:
- secretRef:
name: app-secrets
volumeMounts:
- name: repos
mountPath: /data/repos
volumes:
- name: repos
persistentVolumeClaim:
claimName: git-repos
---
apiVersion: batch/v1
kind: Job
metadata:
name: migrate
spec:
template:
spec:
containers:
- name: migrate
image: myapp/migrate:latest
envFrom:
- secretRef:
name: app-secrets
args: ["up"]
restartPolicy: Never
构建缓存
使用 Docker BuildKit 的构建缓存:
--mount=type=cache,target=/usr/local/cargo/registry— crates.io 依赖--mount=type=cache,target=/usr/local/cargo/git— git 依赖--mount=type=cache,target=target— 编译产物
建议挂载持久化缓存卷以加速增量构建:
docker buildx create --use
docker buildx build \
--cache-from=type=local,src=/tmp/cargo-cache \
--cache-to=type=local,dest=/tmp/cargo-cache \
-f docker/app.Dockerfile -t myapp/app .
跨平台构建
默认构建 x86_64 Linux 可执行文件。构建其他平台:
# ARM64
BUILD_TARGET=aarch64-unknown-linux-gnu ./docker/build.sh
# 需先安装对应 target:
rustup target add aarch64-unknown-linux-gnu