Docker 建置與推送管線
DevOps7 個節點 · 6 條連接devops
視覺化
ex-docker-build-push.osop.yaml
# Docker Build, Scan, and Push Pipeline
# Multi-stage build with vulnerability scanning and multi-registry push
osop_version: "2.0"
id: docker-build-push
name: "Docker 建置與推送管線"
nodes:
- id: checkout
type: cicd
purpose: Check out source code and determine build metadata
subtype: github-actions
runtime:
platform: github-actions
trigger: push
branches: [main, "release/*"]
outputs: [commit_sha, branch, build_tag]
- id: lint_dockerfile
type: cli
purpose: Lint Dockerfile for best practices using hadolint
runtime:
command: "hadolint Dockerfile --format json"
inputs: [commit_sha]
outputs: [lint_result]
timeout_sec: 30
- id: build_image
type: cli
purpose: Build multi-platform Docker image with BuildKit layer caching
runtime:
command: |
docker buildx build \
--platform linux/amd64,linux/arm64 \
--cache-from type=registry,ref=${REGISTRY}/app:cache \
--cache-to type=registry,ref=${REGISTRY}/app:cache,mode=max \
--tag ${REGISTRY}/app:${build_tag} \
--tag ${REGISTRY}/app:latest \
--file Dockerfile \
--load .
inputs: [lint_result, build_tag]
outputs: [image_id, image_digest]
timeout_sec: 600
explain: |
Uses BuildKit for efficient caching and multi-platform support.
Both amd64 and arm64 images are built in a single pass.
- id: trivy_scan
type: cli
purpose: Scan built image for CVEs and misconfigurations using Trivy
runtime:
command: "trivy image --severity HIGH,CRITICAL --format json --exit-code 1 ${REGISTRY}/app:${build_tag}"
inputs: [image_id]
outputs: [scan_report, vulnerability_count]
timeout_sec: 300
retry_policy:
max_retries: 2
backoff_sec: 10
- id: sign_image
type: cli
purpose: Sign the container image with Cosign for supply chain integrity
runtime:
command: "cosign sign --key cosign.key ${REGISTRY}/app@${image_digest}"
inputs: [image_digest]
outputs: [signature]
security:
credentials: [COSIGN_PRIVATE_KEY, COSIGN_PASSWORD]
timeout_sec: 60
- id: push_registries
type: cli
purpose: Push signed image to ECR and GitHub Container Registry
runtime:
command: |
docker push ${REGISTRY}/app:${build_tag} &&
docker tag ${REGISTRY}/app:${build_tag} ghcr.io/org/app:${build_tag} &&
docker push ghcr.io/org/app:${build_tag}
inputs: [signature, image_id]
outputs: [push_digest_ecr, push_digest_ghcr]
security:
credentials: [AWS_ECR_TOKEN, GHCR_TOKEN]
timeout_sec: 300
- id: deploy_staging
type: cli
purpose: Update staging Kubernetes deployment with new image tag
runtime:
command: "kubectl set image deployment/app app=${REGISTRY}/app:${build_tag} -n staging"
inputs: [push_digest_ecr]
outputs: [rollout_status]
timeout_sec: 180
edges:
- from: checkout
to: lint_dockerfile
mode: sequential
- from: lint_dockerfile
to: build_image
mode: sequential
- from: build_image
to: trivy_scan
mode: sequential
- from: trivy_scan
to: sign_image
mode: conditional
condition: "vulnerability_count.critical == 0"
- from: sign_image
to: push_registries
mode: sequential
- from: push_registries
to: deploy_staging
mode: sequential