Files
foxhunt/DOCKER_BUILD_QUICK_REF.md

13 KiB

Docker Build Script - Quick Reference

Script: scripts/build_docker_images.sh Purpose: Production-ready Docker image building with automatic versioning Created: 2025-10-29 Status: Production Ready


Quick Start

# Build and push (default)
./scripts/build_docker_images.sh

# Build only, no push
./scripts/build_docker_images.sh --no-push

# Test build plan (dry-run)
./scripts/build_docker_images.sh --dry-run

# Build specific Dockerfile
./scripts/build_docker_images.sh --dockerfile Dockerfile.runpod

# Build for specific platform
./scripts/build_docker_images.sh --platform linux/amd64

# Skip validation
./scripts/build_docker_images.sh --skip-validation

Features

1. Automatic Versioning

  • Git commit hash: eaa8e030 (or eaa8e030-dirty if uncommitted changes)
  • Timestamp: 20251029_210810 (YYYYMMDD_HHMMSS UTC)
  • Latest tag: Always tagged as latest

Example tags:

jgrusewski/foxhunt:latest
jgrusewski/foxhunt:eaa8e030
jgrusewski/foxhunt:20251029_210810

2. BuildKit Optimization

  • Enabled: DOCKER_BUILDKIT=1 automatically set
  • Cache mounts: Speeds up rebuilds
  • Progress output: --progress=plain for CI/CD

3. Validation

  • Entrypoint scripts: Checks /entrypoint.sh and /entrypoint-generic.sh
  • CUDA runtime: Verifies /usr/local/cuda exists
  • cuDNN libraries: Validates libcudnn presence (warning if missing)
  • Skip option: Use --skip-validation to bypass

4. Reporting

  • Image size: Human-readable format (e.g., "4.82GB")
  • Layer breakdown: Shows top 10 layers
  • Build time: Measures and reports total build duration

5. Error Handling

  • Exit codes:
    • 0: Success
    • 1: Build failed
    • 2: Validation failed
    • 3: Push failed
    • 4: Invalid arguments
  • Prerequisites check: Verifies Docker, Git, BuildKit, Dockerfile existence

Command Reference

Basic Options

Option Description Example
--dockerfile FILE Dockerfile to build --dockerfile Dockerfile.runpod
--no-push Build only, skip push --no-push
--dry-run Show build plan --dry-run
--platform PLATFORM Build for platform --platform linux/amd64
--skip-validation Skip validation --skip-validation
-h, --help Show help -h

Example Workflows

1. Development Iteration (build locally, test, then push):

# Build locally
./scripts/build_docker_images.sh --no-push

# Test image
docker run --rm jgrusewski/foxhunt:latest --help

# Push after testing
docker push jgrusewski/foxhunt:latest
docker push jgrusewski/foxhunt:eaa8e030
docker push jgrusewski/foxhunt:20251029_210810

2. CI/CD Pipeline (build, validate, push):

# Full build with all validations
DOCKER_BUILDKIT=1 ./scripts/build_docker_images.sh

3. Multi-Platform Build (future):

# Build for both amd64 and arm64
./scripts/build_docker_images.sh --platform linux/amd64,linux/arm64

Prerequisites

Required

  • Docker: Version 20.10+ with daemon running
  • Git: Working git repository with commit history
  • Dockerfile: Must exist (default: Dockerfile.runpod)

Optional

  • BuildKit: Automatically detected and used if available
  • Docker Hub login: Required for --push (checks docker info)

Validation Details

Volume Mount Architecture

The script validates images built with volume mount architecture (Runpod deployment):

  • Binaries: Not embedded in image (stored on /runpod-volume/binaries/)
  • Entrypoints: Must exist in image (/entrypoint.sh, /entrypoint-generic.sh)
  • CUDA runtime: Must be present (/usr/local/cuda)
  • cuDNN: Validated but not required (warning if missing)

Note: For standard builds (binaries embedded), modify validate_binaries() function.


Output Examples

Successful Build

==============================================================================
FOXHUNT DOCKER BUILD SCRIPT
==============================================================================

==============================================================================
CHECKING PREREQUISITES
==============================================================================

[SUCCESS] Docker: Docker version 27.5.1
[SUCCESS] Git: git version 2.43.0
[SUCCESS] Git repository detected
[SUCCESS] Dockerfile: Dockerfile.runpod
[SUCCESS] Docker daemon running
[SUCCESS] BuildKit available: v0.12.4

==============================================================================
GENERATING VERSION TAGS
==============================================================================

[INFO] Git commit: eaa8e030
[INFO] Timestamp: 20251029_210810
[SUCCESS] Tags generated:
  - jgrusewski/foxhunt:latest
  - jgrusewski/foxhunt:eaa8e030
  - jgrusewski/foxhunt:20251029_210810

==============================================================================
BUILDING DOCKER IMAGE
==============================================================================

[INFO] BuildKit enabled
[INFO] Build command:
  DOCKER_BUILDKIT=1 docker build --build-arg GIT_COMMIT=eaa8e030 ...

[INFO] Starting build...
[SUCCESS] Build completed in 120s

==============================================================================
VALIDATING IMAGE
==============================================================================

[INFO] Checking entrypoint scripts...
[SUCCESS] Entrypoint script exists: /entrypoint.sh
[SUCCESS] Generic entrypoint script exists: /entrypoint-generic.sh
[INFO] Checking CUDA libraries...
[SUCCESS] CUDA runtime present: /usr/local/cuda
[INFO] Checking cuDNN libraries...
[SUCCESS] cuDNN library present
[SUCCESS] Image validation complete

==============================================================================
IMAGE SIZE REPORT
==============================================================================

[INFO] Image size: 4.82 GB
[INFO] Layer breakdown:
...

==============================================================================
PUSHING IMAGES TO REGISTRY
==============================================================================

[INFO] Pushing: jgrusewski/foxhunt:latest
[SUCCESS] Pushed: jgrusewski/foxhunt:latest
[INFO] Pushing: jgrusewski/foxhunt:eaa8e030
[SUCCESS] Pushed: jgrusewski/foxhunt:eaa8e030
[INFO] Pushing: jgrusewski/foxhunt:20251029_210810
[SUCCESS] Pushed: jgrusewski/foxhunt:20251029_210810
[SUCCESS] All images pushed successfully

==============================================================================
BUILD SUMMARY
==============================================================================

[SUCCESS] Build completed successfully

Image tags:
  - jgrusewski/foxhunt:latest
  - jgrusewski/foxhunt:eaa8e030
  - jgrusewski/foxhunt:20251029_210810

Images pushed to Docker Hub: https://hub.docker.com/r/jgrusewski/foxhunt
Total build time: 120s

[SUCCESS] Done!

Dry-Run Output

[WARNING] DRY RUN MODE - No actual changes will be made

[INFO] Build command:
  DOCKER_BUILDKIT=1 docker build --build-arg GIT_COMMIT=eaa8e030-dirty ...

[WARNING] DRY RUN: Would execute build command above
[SUCCESS] Dry-run completed successfully

Troubleshooting

Error: "Docker daemon is not running"

# Start Docker daemon
sudo systemctl start docker

# Or on macOS
open -a Docker

Error: "Not logged in to Docker Hub"

# Login to Docker Hub
docker login

# Enter username: jgrusewski
# Enter password: <your-password>

Error: "Dockerfile not found"

# Check available Dockerfiles
ls -la Dockerfile*

# Specify correct Dockerfile
./scripts/build_docker_images.sh --dockerfile Dockerfile.runpod

Error: "Working directory has uncommitted changes"

This is a warning, not an error. The script tags the image as <commit>-dirty to indicate uncommitted changes.

# Commit changes to remove warning
git add -A
git commit -m "Your commit message"

# Or continue with dirty tag (safe)
./scripts/build_docker_images.sh

Error: "Validation failed"

# Skip validation if not needed
./scripts/build_docker_images.sh --skip-validation

# Or investigate validation logs
docker run --rm jgrusewski/foxhunt:latest test -f /entrypoint.sh
docker run --rm jgrusewski/foxhunt:latest test -d /usr/local/cuda

Integration with CI/CD

GitHub Actions

name: Build Docker Image

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push
        run: ./scripts/build_docker_images.sh

GitLab CI

docker-build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
    - ./scripts/build_docker_images.sh
  only:
    - main

Advanced Usage

Custom Build Args

Edit the script to add custom build arguments:

# In build_image() function, add:
build_args+=("--build-arg" "CUSTOM_ARG=value")

Multi-Stage Builds

The script supports multi-stage Dockerfiles. No changes required.

Cache Configuration

Enable advanced caching:

# Add to build_args in build_image():
build_args+=("--cache-from" "jgrusewski/foxhunt:latest")
build_args+=("--build-arg" "BUILDKIT_INLINE_CACHE=1")

Platform-Specific Builds

# Build for AMD64 only
./scripts/build_docker_images.sh --platform linux/amd64

# Build for ARM64 only
./scripts/build_docker_images.sh --platform linux/arm64

# Multi-platform (requires buildx)
docker buildx create --use
./scripts/build_docker_images.sh --platform linux/amd64,linux/arm64

Script Internals

File Structure

scripts/build_docker_images.sh (531 lines)
├── Color definitions (RED, GREEN, YELLOW, BLUE, CYAN)
├── Configuration (registry, image name, expected binaries)
├── Helper functions (print_*, time_diff, format_bytes)
├── Argument parsing (parse_args)
├── Validation functions
│   ├── check_prerequisites
│   ├── get_version_tags
│   ├── validate_binaries
│   └── get_image_size
├── Build functions
│   ├── build_image
│   └── push_images
└── Main execution (main)

Key Functions

Function Purpose Exit Code
check_prerequisites Verify Docker, Git, BuildKit, Dockerfile 4
get_version_tags Generate git commit, timestamp, latest tags -
build_image Execute Docker build with BuildKit 1
validate_binaries Check entrypoints, CUDA, cuDNN 2
push_images Push all tags to Docker Hub 3

Maintenance

Adding New Binaries to Validate

Edit the EXPECTED_BINARIES array:

EXPECTED_BINARIES=(
    "train_tft_parquet"
    "train_mamba2_parquet"
    "train_dqn"
    "train_ppo"
    "new_binary_name"  # Add new binary here
)

Changing Default Dockerfile

Edit the DEFAULT_DOCKERFILE variable:

DEFAULT_DOCKERFILE="Dockerfile.production"

Changing Docker Registry

Edit the DOCKER_REGISTRY variable:

DOCKER_REGISTRY="myregistry"
IMAGE_NAME="myimage"

  • CLAUDE.md: System architecture and deployment guide
  • RUNPOD_VOLUME_MOUNT_ARCHITECTURE.md: Runpod deployment details
  • RUNPOD_DEPLOY_QUICK_START.md: Quick start for Runpod deployment
  • Dockerfile.runpod: Volume mount architecture Dockerfile

Script Metadata

Attribute Value
File scripts/build_docker_images.sh
Lines 531
Permissions rwxrwxr-x (executable)
Dependencies Docker 20.10+, Git 2.x, bash 4.x+
Exit Codes 0 (success), 1 (build), 2 (validation), 3 (push), 4 (args)
Default Dockerfile Dockerfile.runpod
Default Registry jgrusewski/foxhunt

Testing Checklist

  • --help flag shows usage
  • --dry-run shows build plan without executing
  • --no-push builds locally without pushing
  • Prerequisites check validates Docker, Git, Dockerfile
  • Version tags generate correctly (commit, timestamp, latest)
  • BuildKit detection works
  • Validation checks entrypoints and CUDA
  • Image size reporting works
  • Color-coded output displays correctly
  • Error handling with correct exit codes
  • Actual build completes successfully (run without --dry-run)
  • Push to Docker Hub succeeds (requires login)

Version History

Version Date Changes
1.0.0 2025-10-29 Initial production-ready release

Next Steps:

  1. Test actual build: ./scripts/build_docker_images.sh --no-push
  2. Verify image: docker run --rm jgrusewski/foxhunt:latest --help
  3. Test push: docker login && ./scripts/build_docker_images.sh