3d_model / .github /workflows /docker-build.yml
Azan
Clean deployment build (Squashed)
7a87926
name: Build and Push Docker Image
on:
push:
branches:
- main
- dev
paths:
- "ylff/**"
- "scripts/**"
- "configs/**"
- "*.py"
- "*.yml"
- "*.yaml"
- "*.toml"
- "*.txt"
- "Dockerfile*"
tags:
- "v*"
pull_request:
branches:
- main
- dev
paths:
- "ylff/**"
- "scripts/**"
- "configs/**"
- "*.py"
- "*.yml"
- "*.yaml"
- "*.toml"
- "*.txt"
- "Dockerfile*"
# Ensure base image is available before building
workflow_run:
workflows: ["Build Heavy Dependencies Base Image"]
types:
- completed
# Concurrency Settings - Prevent multiple deployments from running at once
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
AWS_REGION: us-east-1
ECR_REPOSITORY: ylff
permissions:
contents: read
id-token: write
jobs:
build:
runs-on: ubuntu-latest-m
timeout-minutes: 60
if: >-
${{
(github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success')
&& (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
}}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
lfs: true
- name: Clear disk space before build
run: |
echo "Clearing disk space before Docker build..."
df -h
# Clean system packages safely
sudo rm -rf /usr/share/doc /usr/share/man /usr/share/locale /usr/share/zoneinfo || true
sudo apt-get clean || true
sudo rm -rf /var/lib/apt/lists/* || true
docker system prune -f || true
# Clean temporary directories safely
find /tmp -maxdepth 1 -mindepth 1 -not -name "snap-private-tmp" -not -name "systemd-private-*" -exec rm -rf {} + 2>/dev/null || true
find /var/tmp -maxdepth 1 -mindepth 1 -not -name "cloud-init" -not -name "systemd-private-*" -exec rm -rf {} + 2>/dev/null || true
echo "Disk cleanup completed"
df -h
- name: Set up Docker Buildx (OPTIMIZED for parallel builds)
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
network=host
env.BUILDKIT_STEP_LOG_MAX_SIZE=10485760
env.BUILDKIT_STEP_LOG_MAX_SPEED=10485760
buildkitd-flags: --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
buildkitd-config-inline: |
[worker.oci]
max-parallelism = 4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::211125621822:role/github-actions-role
aws-region: ${{ env.AWS_REGION }}
role-session-name: GitHubActionsSession
output-credentials: true
- name: Ensure ECR repository exists
run: |
echo "πŸ” Checking if ECR repository exists..."
if aws ecr describe-repositories --repository-names ${{ env.ECR_REPOSITORY }} --region ${{ env.AWS_REGION }} 2>/dev/null; then
echo "βœ… ECR repository already exists: ${{ env.ECR_REPOSITORY }}"
else
echo "πŸ”§ Creating ECR repository: ${{ env.ECR_REPOSITORY }}"
aws ecr create-repository \
--repository-name ${{ env.ECR_REPOSITORY }} \
--region ${{ env.AWS_REGION }} \
--image-scanning-configuration scanOnPush=true \
--encryption-configuration encryptionType=AES256
echo "βœ… ECR repository created successfully"
fi
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Ensure base image repository exists
run: |
echo "πŸ” Checking if base image ECR repository exists..."
if aws ecr describe-repositories --repository-names ylff-base --region ${{ env.AWS_REGION }} 2>/dev/null; then
echo "βœ… Base image ECR repository exists: ylff-base"
else
echo "πŸ”§ Creating base image ECR repository: ylff-base"
aws ecr create-repository \
--repository-name ylff-base \
--region ${{ env.AWS_REGION }} \
--image-scanning-configuration scanOnPush=true \
--encryption-configuration encryptionType=AES256
echo "βœ… Base image ECR repository created successfully"
fi
- name: Check if base image exists, build if missing
id: base-image-check
run: |
echo "πŸ” Checking if base image is available..."
BASE_IMAGE="${{ steps.login-ecr.outputs.registry }}/ylff-base:latest"
# Try to pull the base image to ensure it exists
if docker pull "$BASE_IMAGE" 2>/dev/null; then
echo "βœ… Base image found: $BASE_IMAGE"
echo "πŸ“Š Base image size:"
docker images "$BASE_IMAGE" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
echo "base_image_exists=true" >> $GITHUB_OUTPUT
else
echo "⚠️ Base image not found: $BASE_IMAGE"
echo "πŸ”§ Base image will be built inline (this will take longer)"
echo "base_image_exists=false" >> $GITHUB_OUTPUT
fi
- name: Build base image if missing
if: steps.base-image-check.outputs.base_image_exists == 'false'
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile.base
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/ylff-base:latest
cache-from: |
type=registry,ref=${{ steps.login-ecr.outputs.registry }}/ylff-base:latest
type=registry,ref=${{ steps.login-ecr.outputs.registry }}/ylff-base:cache
cache-to: |
type=registry,ref=${{ steps.login-ecr.outputs.registry }}/ylff-base:cache,mode=max
type=inline
platforms: linux/amd64
provenance: false
env:
DOCKER_BUILDKIT: 1
BUILDKIT_PROGRESS: plain
BUILDKIT_MAX_PARALLELISM: 4
- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image (OPTIMIZED with Pre-built Base Image)
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# SPEED-OPTIMIZED CACHING STRATEGY
# 1. GitHub Actions cache (fast, local) - PRIMARY for speed
# 2. Pre-built base image cache (saves 20-25 minutes!)
# 3. Inline cache only (fastest export, no registry overhead)
cache-from: |
type=registry,ref=${{ steps.login-ecr.outputs.registry }}/ylff-base:latest
type=registry,ref=${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:latest
type=inline
cache-to: |
type=inline,mode=max
type=registry,ref=${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:cache,mode=max
platforms: linux/amd64
provenance: false
build-args: |
BASE_IMAGE=${{ steps.login-ecr.outputs.registry }}/ylff-base:latest
env:
DOCKER_BUILDKIT: 1
BUILDKIT_PROGRESS: plain
# OPTIMIZATION: Enable parallel builds and reduce cache export overhead
BUILDKIT_MAX_PARALLELISM: 4
# Reduce disk usage and cache export time
BUILDKIT_STEP_LOG_MAX_SIZE: 10485760
BUILDKIT_STEP_LOG_MAX_SPEED: 10485760
# Optimize cache export - reduce compression and metadata
BUILDKIT_CACHE_COMPRESS: false
BUILDKIT_CACHE_METADATA: false
- name: Log build optimization results
run: |
echo "πŸš€ BUILD OPTIMIZATION RESULTS:"
echo "βœ… Using pre-built base image from build-base-image.yml"
echo "βœ… Heavy dependencies already cached (COLMAP, PyCOLMAP, hloc, LightGlue)"
echo "βœ… Speed-optimized cache strategy: GitHub Actions + Registry (read) + Inline (write)"
echo "βœ… Expected time savings: 20-25 minutes per build"
echo ""
echo "πŸ”§ Cache Optimizations Applied:"
echo "- Using inline cache for fastest export"
echo "- GitHub Actions cache as primary (fastest local access)"
echo "- BuildKit cache compression disabled"
echo "- BuildKit cache metadata disabled"
echo "- Multi-stage build optimization with base image"
- name: Clean up after Docker build
if: always()
run: |
echo "Cleaning up after Docker build..."
docker system prune -f || true
df -h