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(oreaa8e030-dirtyif 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=1automatically set - Cache mounts: Speeds up rebuilds
- Progress output:
--progress=plainfor CI/CD
3. Validation
- Entrypoint scripts: Checks
/entrypoint.shand/entrypoint-generic.sh - CUDA runtime: Verifies
/usr/local/cudaexists - cuDNN libraries: Validates
libcudnnpresence (warning if missing) - Skip option: Use
--skip-validationto 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: Success1: Build failed2: Validation failed3: Push failed4: 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(checksdocker 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"
Related Documentation
- 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
--helpflag shows usage--dry-runshows build plan without executing--no-pushbuilds 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:
- Test actual build:
./scripts/build_docker_images.sh --no-push - Verify image:
docker run --rm jgrusewski/foxhunt:latest --help - Test push:
docker login && ./scripts/build_docker_images.sh