Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Give agents more agency

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    pigfoot

    github-actions-container-build

    pigfoot/github-actions-container-build
    Productivity
    2

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Build multi-architecture container images in GitHub Actions. Matrix builds (public repos with native ARM64), QEMU emulation (private repos), or ARM64 larger runners (Team/Enterprise)...

    SKILL.md

    GitHub Actions Container Build

    Build multi-architecture container images in GitHub Actions using Podman and native ARM64 runners.

    Core Principles

    Choose Your Workflow

    CRITICAL: Ask these questions before generating any workflow.

    Question 1: Is your GitHub repository public?

    • Yes → Use github-actions-workflow-matrix-build.yml (free standard ARM64 runners, 10-50x faster)
    • No → Go to Question 2

    Question 2: Do you have GitHub Team/Enterprise + willing to pay for ARM64 builds?

    • Yes → Use ARM64 larger runners (custom setup required, paid per minute)
    • No → Use github-actions-workflow-qemu.yml (free QEMU emulation, slower but works on free tier)

    1. Push-by-Digest (2025 Best Practice - Default)

    Matrix builds use push-by-digest pattern:

    • Images pushed by digest without intermediate :amd64/:arm64 tags
    • Only tiny digest files (~70 bytes) transfer as artifacts
    • Registry stays clean (no tag clutter)
    • Same debug experience with --platform flag
    # Build job
    - name: Push by digest
      run: |
        podman push \
          --digestfile /tmp/digest \
          localhost/build:${{ matrix.arch }} \
          docker://${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
    
    # Merge job
    - name: Create manifest from digests
      run: |
        podman manifest create "$IMAGE:latest"
        podman manifest add "$IMAGE:latest" "docker://$IMAGE@${AMD64_DIGEST}"
        podman manifest add "$IMAGE:latest" "docker://$IMAGE@${ARM64_DIGEST}"
        podman manifest push --all "$IMAGE:latest" "docker://$IMAGE:latest"
    

    Debug specific architecture:

    podman pull --platform linux/arm64 ghcr.io/OWNER/REPO:latest
    

    2. Matrix Builds (Public Repos)

    For public repositories - use GitHub-hosted standard ARM64 runners:

    • 10-50x faster builds (native vs. emulation)
    • Better reliability and accuracy
    • Lower CI costs
    • Completely free for public repos
    • Not available for private repos
    strategy:
      matrix:
        include:
          - arch: amd64
            runner: ubuntu-24.04
          - arch: arm64
            runner: ubuntu-24.04-arm  # Standard ARM64 runner (public repos only)
    

    3. QEMU Builds (Private Repos - Free Tier)

    For private repositories on free tier - use QEMU emulation:

    • Works on GitHub Free plan
    • Slower (10-50x) than native ARM64 runners
    • Uses docker/setup-qemu-action for ARM64 emulation
    • Single-job pattern with --platform linux/amd64,linux/arm64
    runs-on: ubuntu-latest
    steps:
      - uses: docker/setup-qemu-action@v3
      - run: podman build --platform linux/amd64,linux/arm64 --manifest ...
    

    4. Podman Over Docker

    Use Podman for container builds:

    • Rootless by default (better security)
    • No daemon required
    • Native multi-arch manifest support
    • OCI compliant
    • Must use podman manifest push --all (not podman push)
    • Format: Use OCI (default) for modern registries; use --format v2s2 only for Quay.io or cross-registry (see references for details)
    • Network: Use --network=host flag for builds to avoid container networking SSL issues on GitHub Actions ubuntu-24.04 (see Troubleshooting section)

    5. podman-static for Heredoc Support

    Ubuntu 24.04's bundled podman (4.9.3) uses buildah 1.33.7 which doesn't support heredoc syntax. Install podman-static for full BuildKit compatibility:

    - name: Install podman-static
      run: |
        ARCH=$(uname -m)
        if [ "$ARCH" = "x86_64" ]; then
          PODMAN_ARCH="amd64"
        else
          PODMAN_ARCH="arm64"
        fi
        curl -fsSL -o /tmp/podman-linux-${PODMAN_ARCH}.tar.gz \
          https://github.com/mgoltzsche/podman-static/releases/latest/download/podman-linux-${PODMAN_ARCH}.tar.gz
        cd /tmp && tar -xzf podman-linux-${PODMAN_ARCH}.tar.gz
        sudo cp -f podman-linux-${PODMAN_ARCH}/usr/local/bin/* /usr/bin/
        podman system migrate
    

    Important: Install to /usr/bin/ (not /usr/local/bin/) to avoid AppArmor issues.

    Quick Start

    For Public Repos (Matrix Build)

    1. Copy workflow template:

      cp ${CLAUDE_SKILL_DIR}/assets/github-actions-workflow-matrix-build.yml .github/workflows/build.yml
      
    2. Customize Containerfile path:

      -f ./Containerfile.python-uv  # or your Containerfile
      
    3. Add your Containerfile (see secure-container-build plugin for templates)

    For Private Repos (QEMU)

    1. Copy workflow template:

      cp ${CLAUDE_SKILL_DIR}/assets/github-actions-workflow-qemu.yml .github/workflows/build.yml
      
    2. Follow steps 2-3 from above.

    Workflow Structure

    Matrix Build Workflow (Push-by-Digest)

    1. Build job (matrix): Build and push images by digest on native runners
    2. Merge job: Download digests, create and push multi-arch manifest

    QEMU Workflow

    1. Single job: Build multi-arch manifest directly with --platform flag

    Multi-arch Build Approaches

    Approach Artifact Size Registry Overhead Best For
    Push-by-digest (default) ~70 bytes 1x Production
    Architecture tags None 2x (tags + manifest) Debugging
    OCI artifacts Full images 3x Maximum privacy

    See references/github-actions-best-practices.md for detailed comparison.

    ARM64 Larger Runners (Private Repos with Team/Enterprise)

    For private repositories with GitHub Team or Enterprise Cloud plans:

    Standard ARM64 runners (ubuntu-24.04-arm) don't work in private repos. Instead, create ARM64 larger runners:

    Setup steps:

    1. Go to Organization Settings → Actions → Runners → New runner
    2. Select "Larger runners"
    3. Choose "Ubuntu 24.04 by Arm Limited" partner image
    4. Name your runner (e.g., my-org-arm64-runner)
    5. Configure size (e.g., 4-core, 16GB RAM)

    Update workflow to use custom runner:

    strategy:
      matrix:
        include:
          - arch: amd64
            runner: ubuntu-24.04
          - arch: arm64
            runner: my-org-arm64-runner  # Your custom ARM64 larger runner name
    

    Cost:

    • Billed per minute (not included in free minutes)
    • ~37% cheaper than x64 larger runners
    • Ref: Actions runner pricing

    Registry Configuration

    GitHub Container Registry (GHCR) - Default

    env:
      REGISTRY: ghcr.io
      IMAGE_NAME: ${{ github.repository }}
    
    - name: Login to GHCR
      run: |
        echo "${{ secrets.GITHUB_TOKEN }}" | podman login "${{ env.REGISTRY }}" \
          -u "${{ github.actor }}" \
          --password-stdin
    

    Docker Hub (Optional)

    - name: Login to Docker Hub
      run: |
        echo "${{ secrets.DOCKERHUB_TOKEN }}" | podman login docker.io \
          -u "${{ secrets.DOCKERHUB_USERNAME }}" \
          --password-stdin
    
    # Push to Docker Hub
    podman manifest push --all "$IMAGE:latest" \
      "docker://docker.io/${{ secrets.DOCKERHUB_USERNAME }}/app:latest"
    

    Debugging Multi-arch Images

    # Pull specific architecture
    podman pull --platform linux/arm64 ghcr.io/OWNER/REPO:latest
    
    # Inspect manifest
    podman manifest inspect ghcr.io/OWNER/REPO:latest
    
    # Verify architectures
    podman manifest inspect ghcr.io/OWNER/REPO:latest | jq '.manifests[].platform'
    

    Reference Documentation

    For detailed information, see references/github-actions-best-practices.md.

    Containerfile Templates

    For Containerfile templates and security best practices, see the secure-container-build plugin which provides:

    • Production-ready templates for Python/uv, Bun, Node.js/pnpm, Golang, and Rust
    • Wolfi runtime images with non-root users
    • Multi-stage build patterns
    • Allocator optimization for Rust

    Troubleshooting

    Common Issues

    Container networking SSL errors (ubuntu-24.04 runners):

    • Symptom: UNKNOWN_CERTIFICATE_VERIFICATION_ERROR or SSL certificate verification failures during bun install, npm install, pip install, etc. inside containers

    • Cause: GitHub Actions ubuntu-24.04 runner image 20251208.163.1+ has container networking configuration changes that break SSL/TLS connections from inside containers

    • Solution: Add --network=host flag to podman build:

      podman build \
        --network=host \
        --format docker \
        --platform linux/${{ matrix.arch }} \
        -f ./Containerfile \
        .
      
    • Verification: Test repository at https://github.com/pigfoot/test-bun-ssl-issue

    • GitHub Issue: https://github.com/actions/runner-images/issues/13422

    • Note: This is a known issue with ubuntu-24.04 runners. The --network=host workaround reduces network isolation during build but is acceptable for CI/CD use cases.

    Authentication failed:

    • Ensure GITHUB_TOKEN has package write permission
    • Check registry URL and credentials

    Manifest add failed:

    • Verify architecture-specific images exist in registry
    • Check digest format is correct (sha256:...)

    ARM64 runner not available:

    • Standard ARM64 runners only work for public repos
    • For private repos, use QEMU or larger runners

    podman-static installation fails:

    • Verify correct architecture detection
    • Check GitHub releases for podman-static availability

    AppArmor issues:

    • Install binaries to /usr/bin/ not /usr/local/bin/
    • Run podman system migrate after installation

    Wrong architecture pulled:

    • Always use --platform flag when pulling
    • Use --format docker when building for compatibility
    Recommended Servers
    MantleKit Launch Planner
    MantleKit Launch Planner
    Hugging Face
    Hugging Face
    Nanobanana
    Nanobanana
    Repository
    pigfoot/claude-code-hubs
    Files