# Local CI/CD Pipeline Testing Guide **Created**: 2025-10-29 **Purpose**: Simulate GitLab CI/CD pipeline locally before deployment **Script**: `scripts/local_ci_pipeline.sh` --- ## Overview The local CI/CD pipeline simulator replicates GitLab CI/CD stages for testing Docker image builds and deployments before pushing to GitLab. This ensures: 1. **Build validation**: Docker image builds successfully with CUDA 12.4.1 + cuDNN 9 2. **Test validation**: GLIBC 2.35, CUDA libraries, entrypoints work correctly 3. **Push readiness**: Image can be pushed to Docker Hub registry --- ## Quick Start ### 1. Full Pipeline (Build + Test + Push) ```bash ./scripts/local_ci_pipeline.sh ``` ### 2. Test Build Only (Skip Push) ```bash ./scripts/local_ci_pipeline.sh --skip-push ``` ### 3. Dry-Run (Show Commands) ```bash ./scripts/local_ci_pipeline.sh --dry-run ``` ### 4. Verbose Output ```bash ./scripts/local_ci_pipeline.sh --verbose --skip-push ``` --- ## Pipeline Stages ### Stage 0: Pre-Flight Checks (๐Ÿ”) **Duration**: ~3 seconds **Validates**: - Docker daemon running - Docker BuildKit available - Docker Hub authentication (if pushing) - Dockerfile exists (`Dockerfile.runpod`) - Git repository status **Output**: ``` โœ“ All required commands available โœ“ Docker daemon running โœ“ Docker Hub authenticated โœ“ Dockerfile found: Dockerfile.runpod โœ“ Git repository validated ``` ### Stage 1: Build (๐Ÿ”จ) **Duration**: ~2-3 minutes **Executes**: ```bash docker build -f Dockerfile.runpod -t jgrusewski/foxhunt:latest . ``` **Validates**: - Dockerfile syntax - CUDA 12.4.1 + cuDNN 9 base image pull - Image layers build successfully - Final image exists **Output**: ``` โœ“ Docker image built successfully: 4.80 GB ``` ### Stage 2: Test (๐Ÿงช) **Duration**: ~10-20 seconds **Validates**: #### Test 1: GLIBC Version ```bash docker run --rm jgrusewski/foxhunt:latest ldd --version ``` **Expected**: GLIBC 2.35 (Ubuntu 22.04) #### Test 2: CUDA Libraries **Required Libraries**: - `libcuda.so.1` (CUDA driver) - `libcurand.so.10` (CUDA random) - `libcublas.so.12` (CUDA BLAS) - `libcublasLt.so.12` (CUDA BLAS Light) - `libcudnn.so.9` (cuDNN 9) #### Test 3: nvidia-smi (Optional) **Checks**: GPU driver availability on host **Note**: Warns if not available (normal for CI/CD without GPU) #### Test 4: Binary GLIBC Dependencies **Validates**: System binaries link against GLIBC 2.35 #### Test 5: Entrypoint Scripts **Checks**: - `/entrypoint.sh` exists and executable - `/entrypoint-generic.sh` exists and executable - `--help` command works **Output**: ``` โœ“ GLIBC 2.35 validated โœ“ CUDA libraries validated โœ“ nvidia-smi available, driver version: 550.120 โœ“ Binary GLIBC dependencies validated โœ“ Entrypoint script exists and is executable ``` ### Stage 3: Push (๐Ÿš€) **Duration**: ~1-5 minutes (depends on network) **Executes**: ```bash docker push jgrusewski/foxhunt:latest ``` **Validates**: - Docker Hub authentication - Image push succeeds - Warns to set repository to PRIVATE **Output**: ``` โœ“ Image pushed successfully: jgrusewski/foxhunt:latest โš  WARNING: Set Docker Hub repository to PRIVATE if not already ``` --- ## Command Options | Option | Description | Use Case | |--------|-------------|----------| | `--dry-run` | Show commands without executing | Preview pipeline actions | | `--skip-push` | Skip push stage | Local testing only | | `--verbose` | Enable verbose output | Debugging build issues | | `--help` | Show help message | View usage instructions | --- ## Exit Codes | Code | Meaning | Action | |------|---------|--------| | 0 | Success | All stages passed | | 1 | Stage failure | Check error output and logs | --- ## Troubleshooting ### Error: Docker daemon not running ```bash # Start Docker daemon sudo systemctl start docker # Verify docker info ``` ### Error: Docker Hub authentication failed ```bash # Login to Docker Hub docker login # Enter credentials for jgrusewski account ``` ### Error: Docker build failed ```bash # Check build logs cat /tmp/docker_build.log # Verify Dockerfile exists ls -la Dockerfile.runpod # Check disk space df -h ``` ### Error: GLIBC version mismatch ```bash # Expected: GLIBC 2.35 (Ubuntu 22.04) # If mismatch, check Dockerfile base image docker run --rm jgrusewski/foxhunt:latest ldd --version ``` ### Error: CUDA libraries missing ```bash # Check CUDA installation in image docker run --rm jgrusewski/foxhunt:latest sh -c "ls /usr/local/cuda/lib64/" # Verify cuDNN docker run --rm jgrusewski/foxhunt:latest sh -c "ldconfig -p | grep cudnn" ``` ### Warning: nvidia-smi not available ``` โš  WARNING: This is normal for CI/CD environments without GPU โš  WARNING: GPU will be available in Runpod deployment ``` --- ## Pipeline Metrics ### Typical Run Times | Stage | Duration | Size | |-------|----------|------| | Pre-flight | ~3s | - | | Build | ~2-3 min | 4.8 GB | | Test | ~10-20s | - | | Push | ~1-5 min | 4.8 GB | | **Total** | **~4-9 min** | **4.8 GB** | ### Resource Requirements | Resource | Minimum | Recommended | |----------|---------|-------------| | Disk Space | 10 GB | 20 GB | | RAM | 4 GB | 8 GB | | Docker | 20.10+ | 24.0+ | --- ## Integration with GitLab CI/CD ### .gitlab-ci.yml Template ```yaml stages: - build - test - push variables: DOCKER_IMAGE: jgrusewski/foxhunt:latest DOCKERFILE: Dockerfile.runpod build: stage: build image: docker:latest services: - docker:dind script: - docker build -f $DOCKERFILE -t $DOCKER_IMAGE . only: - main test: stage: test image: docker:latest services: - docker:dind script: # GLIBC validation - docker run --rm $DOCKER_IMAGE ldd --version | grep "2.35" # CUDA library checks - docker run --rm $DOCKER_IMAGE sh -c "ldconfig -p | grep libcuda.so.1" - docker run --rm $DOCKER_IMAGE sh -c "ldconfig -p | grep libcurand.so.10" - docker run --rm $DOCKER_IMAGE sh -c "ldconfig -p | grep libcublas.so.12" - docker run --rm $DOCKER_IMAGE sh -c "ldconfig -p | grep libcublasLt.so.12" - docker run --rm $DOCKER_IMAGE sh -c "ldconfig -p | grep libcudnn.so.9" # Entrypoint validation - docker run --rm $DOCKER_IMAGE sh -c "[ -x /entrypoint.sh ]" - docker run --rm $DOCKER_IMAGE sh -c "[ -x /entrypoint-generic.sh ]" only: - main push: stage: push image: docker:latest services: - docker:dind script: - docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_TOKEN - docker push $DOCKER_IMAGE only: - main ``` ### GitLab CI/CD Variables Add these variables to GitLab project settings: | Variable | Type | Value | Protected | |----------|------|-------|-----------| | `DOCKER_HUB_USER` | Variable | `jgrusewski` | Yes | | `DOCKER_HUB_TOKEN` | Variable | `` | Yes | --- ## Next Steps After successful local pipeline run: 1. **Verify Docker Hub**: Check image at https://hub.docker.com/r/jgrusewski/foxhunt 2. **Set PRIVATE**: Update repository visibility in Docker Hub settings 3. **Test Runpod**: Deploy to Runpod with volume mount 4. **Validate Training**: Run hyperopt demos with GPU 5. **Push to GitLab**: Commit `.gitlab-ci.yml` and trigger CI/CD --- ## Additional Resources - **Dockerfile**: `/home/jgrusewski/Work/foxhunt/Dockerfile.runpod` - **Entrypoint**: `/home/jgrusewski/Work/foxhunt/entrypoint.sh` - **Build Logs**: `/tmp/docker_build.log` - **Push Logs**: `/tmp/docker_push.log` - **Docker Hub**: https://hub.docker.com/r/jgrusewski/foxhunt - **Runpod**: https://www.runpod.io/console/pods --- ## Example Output ### Successful Pipeline Run ``` ======================================== ๐Ÿš€ LOCAL CI/CD PIPELINE SIMULATOR ======================================== โ„น Simulating GitLab CI/CD pipeline locally โ„น Image: jgrusewski/foxhunt:latest โ„น Dockerfile: Dockerfile.runpod ======================================== ๐Ÿ” STAGE 0: PRE-FLIGHT CHECKS ======================================== โœ“ All required commands available โœ“ Docker daemon running โœ“ Docker Hub authenticated โœ“ Dockerfile found: Dockerfile.runpod โœ“ Git repository validated โฑ Pre-flight checks completed in 0m 3s ======================================== ๐Ÿ”จ STAGE 1: BUILD ======================================== โœ“ Docker image built successfully: 4.80 GB โฑ Build completed in 2m 34s ======================================== ๐Ÿงช STAGE 2: TEST ======================================== โœ“ GLIBC 2.35 validated โœ“ CUDA libraries validated โœ“ nvidia-smi available, driver version: 550.120 โœ“ Binary GLIBC dependencies validated โœ“ Entrypoint script exists and is executable โฑ Test completed in 0m 18s ======================================== ๐Ÿš€ STAGE 3: PUSH ======================================== โœ“ Image pushed successfully: jgrusewski/foxhunt:latest โš  WARNING: Set Docker Hub repository to PRIVATE if not already โฑ Push completed in 3m 12s ======================================== โœ… PIPELINE COMPLETE ======================================== โ„น Pipeline Summary: โ€ข Image: jgrusewski/foxhunt:latest โ€ข Dockerfile: Dockerfile.runpod โ€ข Mode: Full execution โ€ข Push: Completed โœ“ Total pipeline time: 6m 7s โ„น GitLab CI/CD readiness: โœ… โ€ข Build stage: Validated โ€ข Test stage: Validated โ€ข Push stage: Validated ``` --- ## Summary The `local_ci_pipeline.sh` script provides: โœ… **Complete CI/CD simulation** - All GitLab stages tested locally โœ… **Fast iteration** - Catch issues before GitLab deployment โœ… **GLIBC validation** - Ensures 2.35 compatibility โœ… **CUDA validation** - Verifies CUDA 12.4.1 + cuDNN 9 โœ… **Entrypoint testing** - Validates volume mount architecture โœ… **Color-coded output** - Easy to read success/error states โœ… **Stage timing** - Performance metrics for each stage โœ… **Error handling** - Exit on first failure (CI/CD behavior) **Total Time**: 4-9 minutes (vs. 10-15 min on GitLab CI/CD) **Cost**: $0 (vs. GitLab CI/CD minutes) **Reliability**: 100% local control before cloud deployment