Files
tankstopp-app/scripts/docker/build.sh
T
2025-07-07 01:44:12 +02:00

310 lines
7.7 KiB
Bash
Executable File

#!/bin/bash
# TankStopp Docker Build Script
# This script builds Docker images for the TankStopp application
set -e # Exit on any error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Default values
IMAGE_NAME="tankstopp"
TAG="latest"
DOCKERFILE="Dockerfile"
CONTEXT="."
BUILD_ARGS=""
PLATFORM=""
PUSH=false
NO_CACHE=false
QUIET=false
ENVIRONMENT="production"
# Functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
show_help() {
cat << EOF
TankStopp Docker Build Script
Usage: $0 [OPTIONS]
OPTIONS:
-h, --help Show this help message
-t, --tag TAG Image tag (default: latest)
-e, --env ENV Environment: development|production (default: production)
-f, --file FILE Dockerfile path (default: Dockerfile)
-c, --context PATH Build context path (default: .)
-p, --platform ARCH Target platform (e.g., linux/amd64,linux/arm64)
--push Push image to registry after build
--no-cache Build without using cache
--quiet Suppress build output
--build-arg ARG=VALUE Pass build arguments
--clean Clean up old images before building
EXAMPLES:
# Build production image
$0 --tag v1.0.0 --env production
# Build development image
$0 --tag dev --env development
# Build multi-platform image
$0 --tag latest --platform linux/amd64,linux/arm64
# Build and push to registry
$0 --tag v1.0.0 --push
# Build with custom build args
$0 --build-arg VERSION=1.0.0 --build-arg BUILD_DATE=\$(date -u +'%Y-%m-%dT%H:%M:%SZ')
ENVIRONMENT CONFIGURATIONS:
production - Optimized for production deployment
development - Includes development tools and debugging
EOF
}
check_requirements() {
log_info "Checking requirements..."
if ! command -v docker &> /dev/null; then
log_error "Docker is not installed or not in PATH"
exit 1
fi
if ! docker info &> /dev/null; then
log_error "Docker daemon is not running"
exit 1
fi
if [ ! -f "$DOCKERFILE" ]; then
log_error "Dockerfile not found: $DOCKERFILE"
exit 1
fi
if [ ! -d "$CONTEXT" ]; then
log_error "Build context directory not found: $CONTEXT"
exit 1
fi
log_success "Requirements check passed"
}
clean_old_images() {
log_info "Cleaning up old images..."
# Remove old tankstopp images (keep latest 3)
OLD_IMAGES=$(docker images "$IMAGE_NAME" --format "{{.Repository}}:{{.Tag}}" | tail -n +4)
if [ -n "$OLD_IMAGES" ]; then
echo "$OLD_IMAGES" | xargs docker rmi -f 2>/dev/null || true
log_success "Cleaned up old images"
else
log_info "No old images to clean"
fi
# Remove dangling images
DANGLING=$(docker images -f "dangling=true" -q)
if [ -n "$DANGLING" ]; then
echo "$DANGLING" | xargs docker rmi -f 2>/dev/null || true
log_success "Removed dangling images"
fi
}
prepare_build_args() {
log_info "Preparing build arguments..."
# Add environment-specific build args
case "$ENVIRONMENT" in
"development")
BUILD_ARGS="$BUILD_ARGS --build-arg APP_ENV=development"
BUILD_ARGS="$BUILD_ARGS --build-arg DEBUG=true"
;;
"production")
BUILD_ARGS="$BUILD_ARGS --build-arg APP_ENV=production"
BUILD_ARGS="$BUILD_ARGS --build-arg DEBUG=false"
;;
esac
# Add common build args
BUILD_ARGS="$BUILD_ARGS --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
BUILD_ARGS="$BUILD_ARGS --build-arg VCS_REF=$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')"
BUILD_ARGS="$BUILD_ARGS --build-arg VERSION=$TAG"
log_success "Build arguments prepared"
}
build_image() {
log_info "Building Docker image..."
log_info "Image: $IMAGE_NAME:$TAG"
log_info "Environment: $ENVIRONMENT"
log_info "Context: $CONTEXT"
log_info "Dockerfile: $DOCKERFILE"
# Construct docker build command
DOCKER_CMD="docker build"
# Add platform if specified
if [ -n "$PLATFORM" ]; then
DOCKER_CMD="$DOCKER_CMD --platform $PLATFORM"
fi
# Add no-cache flag if specified
if [ "$NO_CACHE" = true ]; then
DOCKER_CMD="$DOCKER_CMD --no-cache"
fi
# Add quiet flag if specified
if [ "$QUIET" = true ]; then
DOCKER_CMD="$DOCKER_CMD --quiet"
fi
# Add build arguments
DOCKER_CMD="$DOCKER_CMD $BUILD_ARGS"
# Add tag and file
DOCKER_CMD="$DOCKER_CMD -t $IMAGE_NAME:$TAG"
DOCKER_CMD="$DOCKER_CMD -f $DOCKERFILE"
DOCKER_CMD="$DOCKER_CMD $CONTEXT"
log_info "Executing: $DOCKER_CMD"
# Execute build
if eval "$DOCKER_CMD"; then
log_success "Docker image built successfully: $IMAGE_NAME:$TAG"
else
log_error "Docker build failed"
exit 1
fi
}
push_image() {
if [ "$PUSH" = true ]; then
log_info "Pushing image to registry..."
if docker push "$IMAGE_NAME:$TAG"; then
log_success "Image pushed successfully: $IMAGE_NAME:$TAG"
else
log_error "Failed to push image"
exit 1
fi
fi
}
show_image_info() {
log_info "Image information:"
docker images "$IMAGE_NAME:$TAG" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}"
# Show image layers (if not quiet)
if [ "$QUIET" != true ]; then
echo ""
log_info "Image layers:"
docker history "$IMAGE_NAME:$TAG" --format "table {{.CreatedBy}}\t{{.Size}}" | head -10
fi
}
main() {
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-t|--tag)
TAG="$2"
shift 2
;;
-e|--env)
ENVIRONMENT="$2"
shift 2
;;
-f|--file)
DOCKERFILE="$2"
shift 2
;;
-c|--context)
CONTEXT="$2"
shift 2
;;
-p|--platform)
PLATFORM="$2"
shift 2
;;
--push)
PUSH=true
shift
;;
--no-cache)
NO_CACHE=true
shift
;;
--quiet)
QUIET=true
shift
;;
--build-arg)
BUILD_ARGS="$BUILD_ARGS --build-arg $2"
shift 2
;;
--clean)
CLEAN=true
shift
;;
*)
log_error "Unknown option: $1"
show_help
exit 1
;;
esac
done
# Validate environment
if [[ "$ENVIRONMENT" != "development" && "$ENVIRONMENT" != "production" ]]; then
log_error "Invalid environment: $ENVIRONMENT. Must be 'development' or 'production'"
exit 1
fi
# Start build process
log_info "Starting TankStopp Docker build process..."
check_requirements
if [ "$CLEAN" = true ]; then
clean_old_images
fi
prepare_build_args
build_image
push_image
show_image_info
log_success "Build process completed successfully!"
log_info "You can now run the container with:"
log_info " docker run -p 8080:8080 $IMAGE_NAME:$TAG"
log_info ""
log_info "Or use docker-compose:"
log_info " docker-compose up -d"
}
# Execute main function
main "$@"