每个环境有独立的 Dockerfile,共享公共基础设施。
envs/ ├── golang-1.22.3/ │ └── Dockerfile # Golang 环境的 Dockerfile ├── java-17/ │ └── Dockerfile # Java 环境的 Dockerfile ├── python-3.11/ │ └── Dockerfile # Python 环境的 Dockerfile └── ... 公共基础设施(所有环境共享): ├── image-scripts/ # 公共镜像脚本 │ └── claude-restore.sh # Claude 配置恢复 ├── setup/ # 公共安装脚本 │ ├── node-install.sh # Node.js 安装 │ └── ...
所有环境的 Dockerfile 都可以使用:
# Node.js 安装(公共) COPY setup/node-install.sh /tmp/node-install.sh RUN chmod +x /tmp/node-install.sh && /tmp/node-install.sh # Claude Code 配置(公共) RUN mkdir -p /opt/cnb/scripts COPY image-scripts/claude-restore.sh /opt/cnb/scripts/claude-restore.sh RUN chmod +x /opt/cnb/scripts/claude-restore.sh
每个环境完全自定义:
# envs/golang-1.22.3/Dockerfile FROM golang:1.22.3 RUN go install gopls@latest ENV GOPATH=/go
# envs/java-17/Dockerfile FROM maven:3.9-eclipse-temurin-17 RUN curl -fsSL https://code-server.dev/install.sh | sh
# 在主分支创建新环境目录
git checkout main
mkdir envs/nodejs-20
# 编辑 envs/nodejs-20/Dockerfile FROM node:20 RUN apt-get update && apt-get install -y git vim # 公共基础设施 COPY setup/node-install.sh /tmp/node-install.sh RUN chmod +x /tmp/node-install.sh && /tmp/node-install.sh COPY image-scripts/claude-restore.sh /opt/cnb/scripts/claude-restore.sh RUN chmod +x /opt/cnb/scripts/claude-restore.sh WORKDIR /workspace
# 提交到主分支
git add envs/nodejs-20/
git commit -m "Add Node.js 20 environment"
git push origin main
# 创建分支(分支名与环境目录名一致)
git checkout -b nodejs-20
# 提交时 Git hook 自动复制 Dockerfile
git commit --allow-empty -m "Initialize Node.js 20"
# → 自动复制 envs/nodejs-20/Dockerfile 到根目录
# → 自动生成 cnb.yml
# 推送触发 CI/CD
git push origin nodejs-20
# 构建单个环境
bash dev/build-env.sh golang-1.22.3
# 构建并推送
bash dev/build-env.sh golang-1.22.3 --push
# 构建所有环境
bash dev/build-env.sh --all
# 直接使用环境的 Dockerfile 构建
docker build -f envs/golang-1.22.3/Dockerfile -t test:latest .
# 运行测试
docker run --rm -it test:latest bash
# 在主分支修改公共脚本
git checkout main
vim image-scripts/claude-restore.sh
git commit -m "Update Claude restore script"
git push origin main
# 各环境分支合并即可
git checkout golang-1.22.3
git merge main
git push # CI/CD 自动重新构建
# 在主分支修改环境的 Dockerfile
git checkout main
vim envs/golang-1.22.3/Dockerfile
git commit -m "Update Golang environment"
git push origin main
# 在环境分支合并
git checkout golang-1.22.3
git merge main
git commit --allow-empty -m "Update Dockerfile"
git push # Git hook 复制最新 Dockerfile,CI/CD 重新构建
# ✓ 好 - 使用公共脚本 COPY setup/node-install.sh /tmp/ RUN chmod +x /tmp/node-install.sh && /tmp/node-install.sh # ✗ 差 - 重复实现 RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
FROM <base-image> # 1. 环境特定配置 RUN apt-get update && apt-get install -y ... ENV ... RUN ... # 2. 公共基础设施(所有环境统一) # Node.js COPY setup/node-install.sh /tmp/ RUN chmod +x /tmp/node-install.sh && /tmp/node-install.sh # Claude Code RUN mkdir -p /opt/cnb/scripts COPY image-scripts/claude-restore.sh /opt/cnb/scripts/ RUN chmod +x /opt/cnb/scripts/claude-restore.sh # 3. 工作目录 WORKDIR /workspace
# ✓ 好 - 先复制依赖文件,再复制代码 COPY requirements.txt . RUN pip install -r requirements.txt COPY . . # ✗ 差 - 一次性复制,改代码就要重新安装依赖 COPY . . RUN pip install -r requirements.txt
FROM golang:1.22.3 RUN apt-get update && apt-get install -y git vim curl # Go 工具 RUN go install golang.org/x/tools/gopls@latest # Go 环境变量 ENV GOPATH=/go GOPROXY=https://goproxy.cn,direct # 公共基础设施 COPY setup/node-install.sh /tmp/ RUN chmod +x /tmp/node-install.sh && /tmp/node-install.sh COPY image-scripts/claude-restore.sh /opt/cnb/scripts/ RUN chmod +x /opt/cnb/scripts/claude-restore.sh WORKDIR /workspace
FROM maven:3.9-eclipse-temurin-17 RUN apt-get update && apt-get install -y git vim # Maven 配置 RUN mkdir -p /root/.m2 && \ echo '<settings>...</settings>' > /root/.m2/settings.xml # code-server RUN curl -fsSL https://code-server.dev/install.sh | sh # 公共基础设施 COPY setup/node-install.sh /tmp/ RUN chmod +x /tmp/node-install.sh && /tmp/node-install.sh COPY image-scripts/claude-restore.sh /opt/cnb/scripts/ RUN chmod +x /opt/cnb/scripts/claude-restore.sh WORKDIR /workspace
FROM alpine:3.18 # Alpine 使用 apk RUN apk add --no-cache git vim bash # 安装特定工具 RUN apk add --no-cache go # 公共基础设施(脚本需要支持 Alpine) COPY setup/node-install.sh /tmp/ RUN chmod +x /tmp/node-install.sh && /tmp/node-install.sh COPY image-scripts/claude-restore.sh /opt/cnb/scripts/ RUN chmod +x /opt/cnb/scripts/claude-restore.sh WORKDIR /workspace
每个环境分支推送时自动构建:
# cnb.yml
main:
push:
- stages:
- name: Build and push image
script: |
IMAGE_TAG="${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}/${CNB_BRANCH}:latest"
docker build -t $IMAGE_TAG .
docker push $IMAGE_TAG
主分支推送时构建所有环境:
# GitHub Actions 示例
on:
push:
branches: [main]
jobs:
build-all:
runs-on: ubuntu-latest
strategy:
matrix:
env: [golang-1.22.3, java-17, python-3.11]
steps:
- uses: actions/checkout@v2
- run: bash dev/build-env.sh ${{ matrix.env }} --push
envs/ 下的目录名一致bash dev/install-hooks.sh