# Docker 构建指南 ## 前提条件 - Docker 20.10+ - Cargo.lock 已存在(`cargo generate-lockfile`) - 网络能够访问 crates.io ## 快速开始 ```bash # 构建全部镜像(默认 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 服务器地址 | ## 数据库迁移 镜像启动前先运行迁移: ```bash # 方式一:直接运行 docker run --rm \ --env-file .env \ myapp/migrate:latest up # 方式二:Kubernetes InitContainer # 见下方 K8s 示例 ``` ## Kubernetes 部署示例 ```yaml 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` — 编译产物 建议挂载持久化缓存卷以加速增量构建: ```bash 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 可执行文件。构建其他平台: ```bash # ARM64 BUILD_TARGET=aarch64-unknown-linux-gnu ./docker/build.sh # 需先安装对应 target: rustup target add aarch64-unknown-linux-gnu ```