276 lines
8.8 KiB
Bash
Executable File
276 lines
8.8 KiB
Bash
Executable File
#!/bin/bash
|
||
# build-and-push-image.sh
|
||
# Script per buildare l'immagine Docker degli orchestrator e pusharla su un registry privato
|
||
# Uso: ./build-and-push-image.sh [registry_url] [image_name] [tag] [dockerfile_type]
|
||
# Esempio: ./build-and-push-image.sh registry.example.com:5000 orchestrator-app latest distroless
|
||
|
||
set -e
|
||
|
||
# ==================== CONFIGURAZIONE ====================
|
||
|
||
# Directory del progetto (dove si trova il Dockerfile)
|
||
PROJECT_DIR="/home/alex/devel/proxmox-ha-setup/vm1"
|
||
|
||
# Parametri da riga di comando con valori di default
|
||
REGISTRY_URL=${1:-"192.168.1.204:5000"}
|
||
IMAGE_NAME=${2:-"orchestrator-app"}
|
||
TAG=${3:-"latest"}
|
||
DOCKERFILE_TYPE=${4:-"standard"}
|
||
|
||
# Determina quale Dockerfile usare
|
||
if [[ "$DOCKERFILE_TYPE" == "distroless" ]]; then
|
||
DOCKERFILE="Dockerfile.distroless"
|
||
BUILD_TYPE="Distroless (Multi-stage)"
|
||
else
|
||
DOCKERFILE="Dockerfile"
|
||
BUILD_TYPE="Standard (python:3.12-slim)"
|
||
fi
|
||
|
||
# Nome completo dell'immagine
|
||
FULL_IMAGE_NAME="${REGISTRY_URL}/${IMAGE_NAME}:${TAG}"
|
||
LOCAL_IMAGE_NAME="${IMAGE_NAME}:${TAG}"
|
||
|
||
# Colors
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m'
|
||
|
||
# ==================== FUNZIONI ====================
|
||
|
||
print_header() {
|
||
echo -e "${BLUE}================================================${NC}"
|
||
echo -e "${BLUE}$1${NC}"
|
||
echo -e "${BLUE}================================================${NC}"
|
||
}
|
||
|
||
print_success() { echo -e "${GREEN}✓ $1${NC}"; }
|
||
print_warning() { echo -e "${YELLOW}⚠ $1${NC}"; }
|
||
print_error() { echo -e "${RED}✗ $1${NC}"; }
|
||
print_info() { echo -e "${CYAN}ℹ $1${NC}"; }
|
||
|
||
check_command() {
|
||
if ! command -v $1 &> /dev/null; then
|
||
print_error "$1 non trovato. Installalo prima di continuare."
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
show_usage() {
|
||
echo "Uso: $0 [registry_url] [image_name] [tag] [dockerfile_type]"
|
||
echo ""
|
||
echo "Parametri opzionali (valori di default):"
|
||
echo " registry_url - URL del registry privato (default: 192.168.1.204:5000)"
|
||
echo " image_name - Nome dell'immagine (default: orchestrator-app)"
|
||
echo " tag - Tag dell'immagine (default: latest)"
|
||
echo " dockerfile_type - Tipo di Dockerfile: 'standard' o 'distroless' (default: standard)"
|
||
echo ""
|
||
echo "Dockerfile Types:"
|
||
echo " standard - Usa Dockerfile (python:3.12-slim, ~333MB)"
|
||
echo " distroless - Usa Dockerfile.distroless (gcr.io/distroless, ~180MB, più sicuro)"
|
||
echo ""
|
||
echo "Esempi:"
|
||
echo " $0 # Build standard locale"
|
||
echo " $0 registry.example.com:5000 # Registry custom, standard"
|
||
echo " $0 registry.example.com:5000 my-app latest distroless # Build distroless"
|
||
echo " $0 192.168.1.204:5000 orchestrator-app v1.0.0 distroless # Produzione distroless"
|
||
echo ""
|
||
}
|
||
|
||
# ==================== VALIDAZIONE ====================
|
||
|
||
# Mostra help se richiesto
|
||
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
|
||
show_usage
|
||
exit 0
|
||
fi
|
||
|
||
# ==================== SCRIPT PRINCIPALE ====================
|
||
|
||
print_header "BUILD E PUSH IMMAGINE DOCKER"
|
||
|
||
# Check prerequisites
|
||
print_info "Verifica prerequisiti..."
|
||
check_command "docker"
|
||
print_success "Docker trovato"
|
||
|
||
# Verifica che la directory del progetto esista
|
||
if [ ! -d "$PROJECT_DIR" ]; then
|
||
print_error "Directory del progetto non trovata: $PROJECT_DIR"
|
||
exit 1
|
||
fi
|
||
|
||
# Verifica che il Dockerfile richiesto esista
|
||
if [ ! -f "$PROJECT_DIR/$DOCKERFILE" ]; then
|
||
print_error "Dockerfile non trovato: $PROJECT_DIR/$DOCKERFILE"
|
||
if [[ "$DOCKERFILE_TYPE" == "distroless" ]]; then
|
||
print_warning "Il Dockerfile.distroless non esiste. Usa 'standard' o crea il file."
|
||
fi
|
||
exit 1
|
||
fi
|
||
|
||
print_info ""
|
||
print_info "Configurazione build:"
|
||
print_info " Directory progetto: $PROJECT_DIR"
|
||
print_info " Dockerfile: ${CYAN}$DOCKERFILE${NC}"
|
||
print_info " Build type: ${CYAN}$BUILD_TYPE${NC}"
|
||
print_info " Registry: $REGISTRY_URL"
|
||
print_info " Nome immagine: $IMAGE_NAME"
|
||
print_info " Tag: $TAG"
|
||
print_info " Nome completo: ${CYAN}$FULL_IMAGE_NAME${NC}"
|
||
print_info ""
|
||
|
||
# Conferma dall'utente
|
||
read -p "Procedere con la build? (Y/n) " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
||
print_warning "Build annullata dall'utente"
|
||
exit 0
|
||
fi
|
||
|
||
# ==================== BUILD ====================
|
||
|
||
print_header "STEP 1: Build dell'immagine Docker"
|
||
|
||
print_info "Inizio build dell'immagine..."
|
||
print_info "Comando: docker build -f $DOCKERFILE -t $LOCAL_IMAGE_NAME $PROJECT_DIR"
|
||
echo ""
|
||
|
||
# Build dell'immagine con Dockerfile specificato
|
||
if docker build -f "$PROJECT_DIR/$DOCKERFILE" -t "$LOCAL_IMAGE_NAME" "$PROJECT_DIR"; then
|
||
print_success "Build completata con successo"
|
||
else
|
||
print_error "Build fallita"
|
||
exit 1
|
||
fi
|
||
|
||
# Tag dell'immagine per il registry
|
||
print_info "Tagging dell'immagine per il registry..."
|
||
docker tag "$LOCAL_IMAGE_NAME" "$FULL_IMAGE_NAME"
|
||
print_success "Immagine taggata: $FULL_IMAGE_NAME"
|
||
|
||
# ==================== INFORMAZIONI IMMAGINE ====================
|
||
|
||
print_header "STEP 2: Informazioni immagine"
|
||
|
||
# Mostra le informazioni sull'immagine
|
||
IMAGE_SIZE=$(docker images "$LOCAL_IMAGE_NAME" --format "{{.Size}}")
|
||
IMAGE_ID=$(docker images "$LOCAL_IMAGE_NAME" --format "{{.ID}}")
|
||
|
||
print_info "ID Immagine: $IMAGE_ID"
|
||
print_info "Dimensione: $IMAGE_SIZE"
|
||
print_info ""
|
||
|
||
# Mostra i layer dell'immagine (opzionale)
|
||
print_info "Layer dell'immagine:"
|
||
docker history "$LOCAL_IMAGE_NAME" --human --format "table {{.Size}}\t{{.CreatedBy}}" | head -10
|
||
|
||
# ==================== TEST OPZIONALE ====================
|
||
|
||
print_header "STEP 3: Test immagine (opzionale)"
|
||
|
||
read -p "Vuoi testare l'immagine localmente prima del push? (y/N) " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
print_info "Avvio container di test..."
|
||
print_info "Premere Ctrl+C per interrompere il test"
|
||
echo ""
|
||
|
||
# Test con un comando semplice
|
||
if docker run --rm "$LOCAL_IMAGE_NAME" python --version; then
|
||
print_success "Test completato con successo"
|
||
else
|
||
print_warning "Test fallito - ma puoi comunque procedere con il push"
|
||
fi
|
||
echo ""
|
||
fi
|
||
|
||
# ==================== PUSH AL REGISTRY ====================
|
||
|
||
print_header "STEP 4: Push al registry"
|
||
|
||
print_info "Verifica connessione al registry..."
|
||
|
||
# Verifica se il registry è raggiungibile (solo per http/https)
|
||
if [[ "$REGISTRY_URL" =~ ^(localhost|127\.0\.0\.1) ]]; then
|
||
print_warning "Registry locale detectato - assicurati che sia in esecuzione"
|
||
else
|
||
print_info "Registry remoto: $REGISTRY_URL"
|
||
fi
|
||
|
||
read -p "Procedere con il push dell'immagine? (Y/n) " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
||
print_warning "Push annullato dall'utente"
|
||
print_info "L'immagine locale è disponibile come: $LOCAL_IMAGE_NAME"
|
||
exit 0
|
||
fi
|
||
|
||
print_info "Push dell'immagine al registry..."
|
||
echo ""
|
||
|
||
# Push dell'immagine
|
||
if docker push "$FULL_IMAGE_NAME"; then
|
||
print_success "Push completato con successo!"
|
||
else
|
||
print_error "Push fallito"
|
||
print_warning "Verifica che:"
|
||
print_warning " 1. Il registry sia in esecuzione e raggiungibile"
|
||
print_warning " 2. Hai eseguito 'docker login $REGISTRY_URL'"
|
||
print_warning " 3. Il registry accetti connessioni insicure se necessario"
|
||
exit 1
|
||
fi
|
||
|
||
# ==================== PULIZIA OPZIONALE ====================
|
||
|
||
print_header "STEP 5: Pulizia (opzionale)"
|
||
|
||
read -p "Vuoi rimuovere l'immagine locale dopo il push? (y/N) " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
print_info "Rimozione immagine locale..."
|
||
docker rmi "$LOCAL_IMAGE_NAME" "$FULL_IMAGE_NAME" 2>/dev/null || true
|
||
print_success "Immagine locale rimossa"
|
||
else
|
||
print_info "Immagine locale mantenuta: $LOCAL_IMAGE_NAME"
|
||
fi
|
||
|
||
# ==================== RIEPILOGO ====================
|
||
|
||
print_header "BUILD E PUSH COMPLETATI! 🎉"
|
||
|
||
print_info ""
|
||
print_info "Riepilogo:"
|
||
print_info " Tipo build: ${CYAN}$BUILD_TYPE${NC}"
|
||
print_info " Dockerfile: ${CYAN}$DOCKERFILE${NC}"
|
||
print_info " Immagine: ${GREEN}$FULL_IMAGE_NAME${NC}"
|
||
print_info " Dimensione: $IMAGE_SIZE"
|
||
print_info " Registry: $REGISTRY_URL"
|
||
print_info ""
|
||
|
||
# Messaggio specifico per il tipo di build
|
||
if [[ "$DOCKERFILE_TYPE" == "distroless" ]]; then
|
||
print_info "Note Distroless:"
|
||
print_info " ✓ Immagine più piccola e sicura"
|
||
print_info " ✓ Solo bytecode Python (.pyc)"
|
||
print_info " ✓ Nessuna shell (debug solo tramite log)"
|
||
print_info " ✓ Ideale per produzione"
|
||
else
|
||
print_info "Note Standard:"
|
||
print_info " ✓ Include shell per debugging"
|
||
print_info " ✓ Bytecode Python (.pyc)"
|
||
print_info " ✓ Ideale per sviluppo e staging"
|
||
fi
|
||
|
||
print_info ""
|
||
print_info "Per utilizzare l'immagine nei docker-compose.yml:"
|
||
print_info " Sostituisci 'build: .' con:"
|
||
print_info " ${CYAN}image: $FULL_IMAGE_NAME${NC}"
|
||
print_info ""
|
||
print_info "Per pullare l'immagine su un'altra macchina:"
|
||
print_info " ${CYAN}docker pull $FULL_IMAGE_NAME${NC}"
|
||
print_info ""
|
||
print_success "Operazione completata con successo!"
|