本文目录导读:

Shell脚本在多阶段构建Docker镜像中主要用于自动化构建流程,以下是几种常见的实现方式:
基础多阶段构建脚本
#!/bin/bash
# 多阶段构建Docker镜像
set -e
# 构建参数
APP_NAME="myapp"
VERSION=$(date +%Y%m%d-%H%M%S)
# 构建阶段
docker build \
--build-arg BUILD_VERSION=${VERSION} \
-t ${APP_NAME}:build \
-f Dockerfile.multistage \
--target builder \
.
# 最终阶段
docker build \
--build-arg BUILD_VERSION=${VERSION} \
-t ${APP_NAME}:${VERSION} \
-t ${APP_NAME}:latest \
-f Dockerfile.multistage \
--target final \
.
echo "镜像构建完成: ${APP_NAME}:${VERSION}"
带缓存的优化脚本
#!/bin/bash
set -e
# 配置
REGISTRY="registry.example.com"
APP="myapp"
TAG=$(git rev-parse --short HEAD)
# 利用缓存加速构建
docker build \
--cache-from ${REGISTRY}/${APP}:build-cache \
--cache-from ${REGISTRY}/${APP}:latest \
--target builder \
-t ${REGISTRY}/${APP}:build-cache \
-f Dockerfile.multistage \
.
docker build \
--cache-from ${REGISTRY}/${APP}:build-cache \
--cache-from ${REGISTRY}/${APP}:latest \
--target final \
-t ${REGISTRY}/${APP}:${TAG} \
-t ${REGISTRY}/${APP}:latest \
-f Dockerfile.multistage \
.
# 推送镜像
docker push ${REGISTRY}/${APP}:${TAG}
docker push ${REGISTRY}/${APP}:latest
对应的Dockerfile示例
# Dockerfile.multistage
# 第一阶段:构建阶段
FROM golang:1.21-alpine AS builder
ARG BUILD_VERSION
WORKDIR /app
# 复制依赖文件
COPY go.mod go.sum ./
RUN go mod download
# 复制源代码
COPY . .
# 构建应用
RUN CGO_ENABLED=0 GOOS=linux go build \
-ldflags="-X main.Version=${BUILD_VERSION}" \
-o /app/myapp .
# 第二阶段:测试阶段(可选)
FROM builder AS test
RUN go test ./... -v
# 第三阶段:最终镜像
FROM alpine:3.19 AS final
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /app/myapp .
# 配置运行时
EXPOSE 8080
USER nobody
ENTRYPOINT ["./myapp"]
高级多阶段构建脚本
#!/bin/bash
set -euo pipefail
# 配置
REPO="${REPO:-myapp}"
TAG="${TAG:-$(git describe --tags --always)}"
PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
log() {
echo -e "${GREEN}[INFO]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
exit 1
}
# 参数处理
while [[ $# -gt 0 ]]; do
case $1 in
--push) PUSH=true ;;
--no-cache) NO_CACHE="--no-cache" ;;
*) error "未知参数: $1" ;;
esac
shift
done
# 构建函数
build_stage() {
local target=$1
local tag=$2
local cache_from=""
if [ -z "${NO_CACHE:-}" ]; then
cache_from="--cache-from ${REPO}:${target}-cache"
fi
docker buildx build \
${cache_from} \
${NO_CACHE:-} \
--platform ${PLATFORMS} \
--target ${target} \
-t ${REPO}:${tag} \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
--build-arg VCS_REF=$(git rev-parse --short HEAD) \
${PUSH:+--push} \
.
}
# 清理旧缓存
log "清理旧的构建缓存..."
docker builder prune -f 2>/dev/null || true
# 多阶段构建
log "开始多阶段构建..."
# 阶段1: 依赖安装
log "阶段1: 安装依赖"
build_stage "dependencies" "deps-cache"
# 阶段2: 编译
log "阶段2: 编译项目"
build_stage "builder" "build-cache"
# 阶段3: 测试
log "阶段3: 运行测试"
build_stage "test" "test"
# 阶段4: 最终镜像
log "阶段4: 创建最终镜像"
build_stage "final" "${TAG}"
build_stage "final" "latest"
log "多阶段构建完成!"
支持多架构的构建脚本
#!/bin/bash set -e # 创建构建器 docker buildx create --name multiarch --use || true docker buildx inspect --bootstrap # 并行构建所有阶段 docker buildx build \ --platform linux/amd64,linux/arm64,linux/arm/v7 \ --target builder \ -t app:build-cache \ --cache-to type=inline \ . docker buildx build \ --platform linux/amd64,linux/arm64,linux/arm/v7 \ --target final \ -t app:latest \ -t app:$(git rev-parse --short HEAD) \ --cache-from app:build-cache \ --push \ .
CI/CD集成示例
# .gitlab-ci.yml
variables:
IMAGE_TAG: $CI_COMMIT_SHORT_SHA
stages:
- build
build_image:
stage: build
script:
- |
./build.sh \
--registry $CI_REGISTRY \
--tag $IMAGE_TAG \
--push
only:
- main
最佳实践:
- 使用
set -e确保脚本在错误时停止 - 合理使用构建缓存加速构建
- 分离开发和构建阶段,优化最终镜像大小
- 使用环境变量管理配置
- 添加适当的日志输出和错误处理
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播