/ scripts / container-build.sh
container-build.sh
  1  #!/bin/bash
  2  set -euo pipefail
  3  
  4  # FerrisProof Container Build Script
  5  # Optimized for Podman but works with Docker too
  6  
  7  # Colors for output
  8  RED='\033[0;31m'
  9  GREEN='\033[0;32m'
 10  YELLOW='\033[1;33m'
 11  BLUE='\033[0;34m'
 12  NC='\033[0m' # No Color
 13  
 14  # Configuration
 15  CONTAINER_ENGINE=${CONTAINER_ENGINE:-"podman"}
 16  IMAGE_NAME=${IMAGE_NAME:-"ferris-proof"}
 17  IMAGE_TAG=${IMAGE_TAG:-"latest"}
 18  DOCKERFILE=${DOCKERFILE:-"Containerfile.alpine"}
 19  REGISTRY=${REGISTRY:-""}
 20  PLATFORM=${PLATFORM:-"linux/amd64"}
 21  
 22  log_info() {
 23      echo -e "${BLUE}[INFO]${NC} $1"
 24  }
 25  
 26  log_success() {
 27      echo -e "${GREEN}[SUCCESS]${NC} $1"
 28  }
 29  
 30  log_warning() {
 31      echo -e "${YELLOW}[WARNING]${NC} $1"
 32  }
 33  
 34  log_error() {
 35      echo -e "${RED}[ERROR]${NC} $1"
 36  }
 37  
 38  check_container_engine() {
 39      if ! command -v "$CONTAINER_ENGINE" &> /dev/null; then
 40          log_error "$CONTAINER_ENGINE not found"
 41          if [ "$CONTAINER_ENGINE" = "podman" ]; then
 42              log_info "Install Podman: https://podman.io/getting-started/installation"
 43              log_info "Falling back to Docker..."
 44              if command -v docker &> /dev/null; then
 45                  CONTAINER_ENGINE="docker"
 46                  log_info "Using Docker instead"
 47              else
 48                  log_error "Neither Podman nor Docker found"
 49                  exit 1
 50              fi
 51          else
 52              exit 1
 53          fi
 54      fi
 55      
 56      log_info "Using container engine: $CONTAINER_ENGINE"
 57  }
 58  
 59  build_image() {
 60      local full_image_name="$IMAGE_NAME:$IMAGE_TAG"
 61      if [ -n "$REGISTRY" ]; then
 62          full_image_name="$REGISTRY/$full_image_name"
 63      fi
 64      
 65      log_info "Building image: $full_image_name"
 66      log_info "Using Containerfile: $DOCKERFILE"
 67      log_info "Platform: $PLATFORM"
 68      
 69      local build_args=()
 70      
 71      # Podman-specific optimizations
 72      if [ "$CONTAINER_ENGINE" = "podman" ]; then
 73          build_args+=(
 74              "--layers"
 75              "--platform=$PLATFORM"
 76          )
 77      fi
 78      
 79      # Docker-specific optimizations
 80      if [ "$CONTAINER_ENGINE" = "docker" ]; then
 81          build_args+=(
 82              "--platform=$PLATFORM"
 83          )
 84      fi
 85      
 86      # Build the image
 87      if $CONTAINER_ENGINE build \
 88          "${build_args[@]}" \
 89          -f "$DOCKERFILE" \
 90          -t "$full_image_name" \
 91          .; then
 92          log_success "Image built successfully: $full_image_name"
 93      else
 94          log_error "Failed to build image"
 95          exit 1
 96      fi
 97      
 98      # Show image size
 99      local image_size
100      if [ "$CONTAINER_ENGINE" = "podman" ]; then
101          image_size=$($CONTAINER_ENGINE images --format "{{.Size}}" "$full_image_name")
102      else
103          image_size=$($CONTAINER_ENGINE images --format "table {{.Size}}" "$full_image_name" | tail -n1)
104      fi
105      log_info "Image size: $image_size"
106      
107      return 0
108  }
109  
110  test_image() {
111      local full_image_name="$IMAGE_NAME:$IMAGE_TAG"
112      if [ -n "$REGISTRY" ]; then
113          full_image_name="$REGISTRY/$full_image_name"
114      fi
115      
116      log_info "Testing image: $full_image_name"
117      
118      # Test basic functionality
119      if $CONTAINER_ENGINE run --rm "$full_image_name" --version; then
120          log_success "Image test passed"
121      else
122          log_error "Image test failed"
123          exit 1
124      fi
125      
126      # Test help command
127      if $CONTAINER_ENGINE run --rm "$full_image_name" --help > /dev/null; then
128          log_success "Help command test passed"
129      else
130          log_error "Help command test failed"
131          exit 1
132      fi
133  }
134  
135  push_image() {
136      if [ -z "$REGISTRY" ]; then
137          log_warning "No registry specified, skipping push"
138          return 0
139      fi
140      
141      local full_image_name="$REGISTRY/$IMAGE_NAME:$IMAGE_TAG"
142      
143      log_info "Pushing image: $full_image_name"
144      
145      if $CONTAINER_ENGINE push "$full_image_name"; then
146          log_success "Image pushed successfully"
147      else
148          log_error "Failed to push image"
149          exit 1
150      fi
151  }
152  
153  show_usage() {
154      echo "FerrisProof Container Build Script"
155      echo
156      echo "Usage: $0 [OPTIONS] [COMMAND]"
157      echo
158      echo "Commands:"
159      echo "  build    Build the container image (default)"
160      echo "  test     Test the built image"
161      echo "  push     Push image to registry"
162      echo "  all      Build, test, and push"
163      echo
164      echo "Options:"
165      echo "  --help, -h           Show this help message"
166      echo "  --engine ENGINE      Container engine (podman|docker, default: podman)"
167      echo "  --name NAME          Image name (default: ferris-proof)"
168      echo "  --tag TAG            Image tag (default: latest)"
169      echo "  --dockerfile FILE    Containerfile to use (default: Containerfile.alpine)"
170      echo "  --registry REGISTRY  Registry to push to (optional)"
171      echo "  --platform PLATFORM  Target platform (default: linux/amd64)"
172      echo
173      echo "Environment Variables:"
174      echo "  CONTAINER_ENGINE     Container engine to use"
175      echo "  IMAGE_NAME           Image name"
176      echo "  IMAGE_TAG            Image tag"
177      echo "  DOCKERFILE           Containerfile path"
178      echo "  REGISTRY             Registry URL"
179      echo "  PLATFORM             Target platform"
180      echo
181      echo "Examples:"
182      echo "  $0 build"
183      echo "  $0 --engine docker --tag v1.0.0 build"
184      echo "  $0 --registry ghcr.io/ferris-proof --tag latest all"
185  }
186  
187  main() {
188      local command="build"
189      
190      # Parse arguments
191      while [[ $# -gt 0 ]]; do
192          case $1 in
193              --help|-h)
194                  show_usage
195                  exit 0
196                  ;;
197              --engine)
198                  CONTAINER_ENGINE="$2"
199                  shift 2
200                  ;;
201              --name)
202                  IMAGE_NAME="$2"
203                  shift 2
204                  ;;
205              --tag)
206                  IMAGE_TAG="$2"
207                  shift 2
208                  ;;
209              --dockerfile)
210                  DOCKERFILE="$2"
211                  shift 2
212                  ;;
213              --registry)
214                  REGISTRY="$2"
215                  shift 2
216                  ;;
217              --platform)
218                  PLATFORM="$2"
219                  shift 2
220                  ;;
221              build|test|push|all)
222                  command="$1"
223                  shift
224                  ;;
225              *)
226                  log_error "Unknown option: $1"
227                  show_usage
228                  exit 1
229                  ;;
230          esac
231      done
232      
233      check_container_engine
234      
235      case $command in
236          build)
237              build_image
238              ;;
239          test)
240              test_image
241              ;;
242          push)
243              push_image
244              ;;
245          all)
246              build_image
247              test_image
248              push_image
249              ;;
250          *)
251              log_error "Unknown command: $command"
252              show_usage
253              exit 1
254              ;;
255      esac
256      
257      log_success "Container operations completed successfully! 🎉"
258  }
259  
260  main "$@"