build image

This commit is contained in:
2025-11-29 19:51:15 +01:00
parent c688eefe0b
commit a4b7d3c738
177 changed files with 2018 additions and 23366 deletions

View File

@@ -0,0 +1,610 @@
# Guida Docker Registry Privato
Questa guida spiega come configurare un registry Docker privato e utilizzare gli script per buildare e distribuire le immagini degli orchestrator.
## Indice
1. [Setup Registry Docker Privato](#setup-registry-docker-privato)
2. [Protezione Codice Sorgente (Bytecode)](#protezione-codice-sorgente-bytecode)
3. [Build e Push dell'Immagine](#build-e-push-dellimmagine)
4. [Aggiornamento Docker Compose](#aggiornamento-docker-compose)
5. [Deploy sulle VM](#deploy-sulle-vm)
---
## Setup Registry Docker Privato
### Opzione 1: Registry Locale Semplice (HTTP - Solo per sviluppo)
```bash
# Avvia un registry Docker locale sulla porta 5000
docker run -d -p 5000:5000 --name registry --restart=always registry:2
# Verifica che sia in esecuzione
curl http://localhost:5000/v2/_catalog
```
### Opzione 2: Registry Locale con Persistenza
```bash
# Crea directory per i dati
mkdir -p /opt/docker-registry/data
# Avvia registry con volume persistente
docker run -d \
-p 5000:5000 \
--name registry \
--restart=always \
-v /opt/docker-registry/data:/var/lib/registry \
registry:2
```
### Opzione 3: Registry con HTTPS (Certificato Self-Signed con SANs)
⚠️ **IMPORTANTE**: I certificati moderni devono usare Subject Alternative Names (SANs) invece del campo Common Name.
```bash
# Usa lo script per generare certificati corretti
./scripts/generate-registry-cert.sh 192.168.1.204 registry.local
# Oppure manualmente:
mkdir -p /opt/docker-registry/{data,certs}
# Crea file di configurazione OpenSSL con SANs
cat > /opt/docker-registry/certs/openssl.cnf << 'EOF'
[req]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_ca
prompt = no
[req_distinguished_name]
C = IT
ST = Italy
L = City
O = Docker Registry
CN = registry.local
[req_ext]
subjectAltName = @alt_names
[v3_ca]
subjectAltName = @alt_names
basicConstraints = critical, CA:TRUE
keyUsage = critical, digitalSignature, keyEncipherment, keyCertSign
extendedKeyUsage = serverAuth
[alt_names]
DNS.1 = registry.local
DNS.2 = localhost
IP.1 = 192.168.1.204
IP.2 = 127.0.0.1
EOF
# Genera certificato con SANs
openssl req -newkey rsa:4096 \
-nodes -sha256 \
-keyout /opt/docker-registry/certs/domain.key \
-x509 -days 365 \
-config /opt/docker-registry/certs/openssl.cnf \
-out /opt/docker-registry/certs/domain.crt
# Verifica SANs nel certificato
openssl x509 -in /opt/docker-registry/certs/domain.crt -text -noout | grep -A 3 "Subject Alternative Name"
# Avvia registry con HTTPS
docker run -d \
-p 5000:5000 \
--name registry \
--restart=always \
-v /opt/docker-registry/data:/var/lib/registry \
-v /opt/docker-registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
```
### Opzione 4: Registry con Autenticazione + HTTPS
```bash
# Genera certificati (vedi Opzione 3)
./scripts/generate-registry-cert.sh 192.168.1.204 registry.local
# Crea utente e password
mkdir -p /opt/docker-registry/auth
docker run --rm --entrypoint htpasswd httpd:2 \
-Bbn myuser mypassword > /opt/docker-registry/auth/htpasswd
# Avvia registry con autenticazione e HTTPS
docker run -d \
-p 5000:5000 \
--name registry \
--restart=always \
-v /opt/docker-registry/data:/var/lib/registry \
-v /opt/docker-registry/auth:/auth \
-v /opt/docker-registry/certs:/certs \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
# Login al registry
docker login 192.168.1.204:5000
```
### Configurazione Client Docker per Registry HTTPS (Self-Signed)
Se usi certificati self-signed, devi installare il certificato sui client Docker:
#### Metodo Automatico (Raccomandato)
```bash
# Sul tuo computer di sviluppo o sulle VM client
./scripts/setup-registry-client.sh 192.168.1.204
# Lo script scaricherà e installerà automaticamente il certificato
```
#### Metodo Manuale
```bash
# 1. Crea directory per i certificati Docker
sudo mkdir -p /etc/docker/certs.d/192.168.1.204:5000
# 2. Copia il certificato dal registry
scp root@192.168.1.204:/opt/docker-registry/certs/domain.crt /tmp/registry.crt
sudo cp /tmp/registry.crt /etc/docker/certs.d/192.168.1.204:5000/ca.crt
# 3. Riavvia Docker
sudo systemctl restart docker
# 4. (Opzionale) Installa anche nel sistema per curl/wget
sudo cp /tmp/registry.crt /usr/local/share/ca-certificates/registry.crt
sudo update-ca-certificates
```
#### Test Connessione con Curl
```bash
# Test con certificato insecure (disabilita verifica)
curl -k https://192.168.1.204:5000/v2/
# Test con certificato installato nel sistema
curl https://192.168.1.204:5000/v2/_catalog
# Test con certificato specificato
curl --cacert /etc/docker/certs.d/192.168.1.204:5000/ca.crt https://192.168.1.204:5000/v2/_catalog
# Con autenticazione
curl -k -u myuser:mypassword https://192.168.1.204:5000/v2/_catalog
```
### Configurazione Client Docker per Registry Insicuro (HTTP)
Se usi un registry HTTP locale, devi configurare Docker per accettare connessioni insicure:
```bash
# Edita /etc/docker/daemon.json
sudo nano /etc/docker/daemon.json
# Aggiungi:
{
"insecure-registries": ["localhost:5000", "192.168.1.X:5000"]
}
# Riavvia Docker
sudo systemctl restart docker
```
---
## Protezione Codice Sorgente (Bytecode)
Le immagini Docker vengono buildare con una configurazione speciale che protegge il codice sorgente Python.
### Come Funziona
Il Dockerfile è configurato per:
1. **Compilare** tutti i file Python in bytecode (`.pyc`) usando Python con ottimizzazione `-OO`
2. **Rimuovere** tutti i file sorgente `.py`
3. **Mantenere** solo i file bytecode compilati in `__pycache__/`
```dockerfile
# Compila tutti i file Python in bytecode
# Usa -OO per rimuovere docstring e assert (ottimizzazione massima)
RUN python -OO -m compileall /app/src /app/env || true
# Rimuovi tutti i file sorgente .py, lasciando solo i .pyc compilati in __pycache__
RUN find /app/src -type f -name "*.py" -delete && \
find /app/env -type f -name "*.py" -delete || true
```
### Vantaggi
**Protezione del Codice**: I file sorgente non sono accessibili nell'immagine
**Dimensione Ridotta**: I file `.pyc` sono più compatti dei `.py`
**Performance**: Leggero miglioramento delle prestazioni (no compilazione a runtime)
**Rimozione Docstring**: Con `-OO` vengono rimossi anche commenti e docstring
### Limitazioni
⚠️ **Debug Difficile**: I traceback mostrano solo numeri di riga, non il codice sorgente
⚠️ **No Reverse Engineering**: Impossibile vedere la logica senza decompilare
⚠️ **Serve Backup**: Mantieni sempre i sorgenti in un repository git separato
### Test dell'Immagine Bytecode
Usa lo script `test-pyc-image.sh` per verificare che l'immagine funzioni correttamente:
```bash
# Test immagine locale
./scripts/test-pyc-image.sh orchestrator-app:latest
# Test immagine dal registry
./scripts/test-pyc-image.sh 192.168.1.203:5000/orchestrator-app:v1.0.0
```
Il test verifica:
- ✅ Assenza di file `.py` in `/app/src`
- ✅ Presenza di file `.pyc` compilati
- ✅ Importazione corretta dei moduli
- ✅ Esecuzione dei moduli orchestrator
- ✅ Configurazione ambiente Python
### Struttura File nell'Immagine
**Prima (con sorgenti):**
```
/app/src/
├── load_orchestrator.py
├── elab_orchestrator.py
├── send_orchestrator.py
└── ftp_csv_receiver.py
```
**Dopo (solo bytecode):**
```
/app/src/
├── __pycache__/
│ ├── load_orchestrator.cpython-312.opt-2.pyc
│ ├── elab_orchestrator.cpython-312.opt-2.pyc
│ ├── send_orchestrator.cpython-312.opt-2.pyc
│ └── ftp_csv_receiver.cpython-312.opt-2.pyc
```
---
## Build e Push dell'Immagine
### Script: `build-and-push-image.sh`
Lo script automatizza il processo di build e push dell'immagine Docker.
#### Sintassi
```bash
./scripts/build-and-push-image.sh [registry_url] [image_name] [tag] [dockerfile_type]
```
#### Parametri
- `registry_url` - URL del registry privato (default: `192.168.1.204:5000`)
- `image_name` - Nome dell'immagine (default: `orchestrator-app`)
- `tag` - Tag dell'immagine (default: `latest`)
- `dockerfile_type` - Tipo di Dockerfile: `standard` o `distroless` (default: `standard`)
#### Tipi di Dockerfile
**`standard`** - Usa `Dockerfile` (python:3.12-slim)
- Dimensione: ~333MB
- Include shell per debugging
- Ideale per sviluppo e staging
**`distroless`** - Usa `Dockerfile.distroless` (gcr.io/distroless/python3)
- Dimensione: ~180MB (50% più piccola!)
- Nessuna shell (massima sicurezza)
- Ideale per produzione
#### Esempi
```bash
# Build standard (default)
./scripts/build-and-push-image.sh
# Build distroless per produzione
./scripts/build-and-push-image.sh 192.168.1.204:5000 orchestrator-app latest distroless
# Build distroless con versione specifica
./scripts/build-and-push-image.sh 192.168.1.204:5000 orchestrator-app v1.2.3 distroless
# Build standard per staging
./scripts/build-and-push-image.sh 192.168.1.204:5000 orchestrator-app staging standard
```
#### Cosa fa lo script
1. ✅ Verifica prerequisiti (Docker)
2. ✅ Controlla che esistano Dockerfile e directory progetto
3. ✅ Mostra configurazione e chiede conferma
4. ✅ Builda l'immagine Docker
5. ✅ Tagga l'immagine per il registry
6. ✅ Mostra informazioni sull'immagine (dimensione, layer)
7. ✅ Opzionalmente testa l'immagine localmente
8. ✅ Pusha l'immagine al registry
9. ✅ Opzionalmente rimuove l'immagine locale
---
## Aggiornamento Docker Compose
### Script: `update-compose-image.sh`
Questo script aggiorna i file `docker-compose.yml` in `vm1/` e `vm2/` per usare l'immagine dal registry invece di buildarla localmente.
#### Sintassi
```bash
./scripts/update-compose-image.sh <registry_url> <image_name> <tag>
```
#### Esempio
```bash
# Aggiorna docker-compose.yml per usare l'immagine dal registry
./scripts/update-compose-image.sh registry.example.com:5000 orchestrator-app latest
```
#### Cosa fa lo script
1. ✅ Crea backup dei file docker-compose.yml (`.backup`)
2. ✅ Sostituisce `build: .` con `image: registry_url/image_name:tag`
3. ✅ Aggiorna entrambi i file vm1/ e vm2/
#### Prima e Dopo
**Prima:**
```yaml
orchestrator-1-load:
build: .
container_name: orchestrator-1-load
...
```
**Dopo:**
```yaml
orchestrator-1-load:
image: registry.example.com:5000/orchestrator-app:latest
container_name: orchestrator-1-load
...
```
---
## Deploy sulle VM
### 1. Setup Registry su una VM Proxmox (Opzionale)
Se vuoi hostare il registry su una delle VM Proxmox:
```bash
# Crea una VM per il registry
./scripts/create-vm.sh 203 registry-server 2 4096 50G
# SSH nella VM
ssh root@192.168.1.203
# Avvia il registry
docker run -d \
-p 5000:5000 \
--name registry \
--restart=always \
-v /opt/registry-data:/var/lib/registry \
registry:2
```
### 2. Build e Push dell'Immagine
```bash
# Sul tuo computer locale, dalla directory del progetto
cd /home/alex/devel/proxmox-ha-setup
# Build e push al registry
./scripts/build-and-push-image.sh 192.168.1.203:5000 orchestrator-app v1.0.0
```
### 3. Aggiorna Docker Compose Files
```bash
# Aggiorna i file docker-compose.yml
./scripts/update-compose-image.sh 192.168.1.203:5000 orchestrator-app v1.0.0
```
### 4. Deploy su VM1 e VM2
```bash
# Copia i file aggiornati sulle VM
scp -r vm1/* root@192.168.1.201:/opt/myapp/
scp -r vm2/* root@192.168.1.202:/opt/myapp/
# Su VM1
ssh root@192.168.1.201
cd /opt/myapp
docker pull 192.168.1.203:5000/orchestrator-app:v1.0.0
docker compose up -d
# Su VM2
ssh root@192.168.1.202
cd /opt/myapp
docker pull 192.168.1.203:5000/orchestrator-app:v1.0.0
docker compose up -d
```
### 5. Verifica Deploy
```bash
# Controlla i container in esecuzione
ssh root@192.168.1.201 'docker ps'
ssh root@192.168.1.202 'docker ps'
# Verifica i log
ssh root@192.168.1.201 'docker logs orchestrator-1-load'
ssh root@192.168.1.202 'docker logs orchestrator-1-load'
```
---
## Workflow Completo di Esempio
### Scenario: Deploy Iniziale
```bash
# 1. Setup registry su VM dedicata
./scripts/create-vm.sh 203 registry 2 4096 50G
ssh root@192.168.1.203 'docker run -d -p 5000:5000 --restart=always -v /opt/registry:/var/lib/registry --name registry registry:2'
# 2. Configura Docker per accettare il registry insicuro (su tutte le VM)
for vm in 201 202; do
ssh root@192.168.1.$vm 'echo "{\"insecure-registries\": [\"192.168.1.203:5000\"]}" > /etc/docker/daemon.json && systemctl restart docker'
done
# 3. Build e push immagine
./scripts/build-and-push-image.sh 192.168.1.203:5000 orchestrator-app v1.0.0
# 4. Aggiorna docker-compose files
./scripts/update-compose-image.sh 192.168.1.203:5000 orchestrator-app v1.0.0
# 5. Deploy sulle VM
for vm in 201 202; do
scp -r vm$((vm-200))/* root@192.168.1.$vm:/opt/myapp/
ssh root@192.168.1.$vm 'cd /opt/myapp && docker compose pull && docker compose up -d'
done
```
### Scenario: Aggiornamento dell'Applicazione
```bash
# 1. Build nuova versione
./scripts/build-and-push-image.sh 192.168.1.203:5000 orchestrator-app v1.1.0
# 2. Aggiorna docker-compose (se necessario)
./scripts/update-compose-image.sh 192.168.1.203:5000 orchestrator-app v1.1.0
# 3. Update sulle VM con zero downtime
# Prima aggiorna VM2 (backup)
ssh root@192.168.1.202 'cd /opt/myapp && docker compose pull && docker compose up -d'
# Attendi che sia stabile
sleep 30
# Poi aggiorna VM1 (master)
ssh root@192.168.1.201 'cd /opt/myapp && docker compose pull && docker compose up -d'
```
---
## Comandi Utili
### Gestione Registry
```bash
# Lista immagini nel registry
curl http://192.168.1.203:5000/v2/_catalog
# Lista tag di un'immagine
curl http://192.168.1.203:5000/v2/orchestrator-app/tags/list
# Verifica dimensione del registry
du -sh /opt/registry-data
```
### Gestione Immagini
```bash
# Pull immagine dal registry
docker pull 192.168.1.203:5000/orchestrator-app:v1.0.0
# Lista immagini locali
docker images | grep orchestrator-app
# Rimuovi immagini vecchie
docker image prune -a
```
### Debug
```bash
# Testa connessione al registry
telnet 192.168.1.203 5000
# Verifica log del registry
docker logs registry
# Test pull senza deploy
docker pull 192.168.1.203:5000/orchestrator-app:latest
```
---
## Best Practices
1. **Versioning**: Usa tag semantici (v1.0.0, v1.1.0) invece di `latest` per produzione
2. **Backup**: Monta un volume per `/var/lib/registry` per persistenza
3. **Security**: Usa HTTPS e autenticazione per registri in produzione
4. **Cleanup**: Rimuovi regolarmente immagini vecchie dal registry
5. **Testing**: Testa sempre l'immagine localmente prima del push
6. **Documentation**: Documenta le modifiche in ogni versione
---
## Troubleshooting
### Errore: "connection refused" durante il push
**Soluzione:**
```bash
# Verifica che il registry sia in esecuzione
docker ps | grep registry
# Verifica connettività
curl http://192.168.1.203:5000/v2/
```
### Errore: "http: server gave HTTP response to HTTPS client"
**Soluzione:**
Aggiungi il registry come insicuro in `/etc/docker/daemon.json`:
```json
{
"insecure-registries": ["192.168.1.203:5000"]
}
```
Poi riavvia Docker: `systemctl restart docker`
### Errore: "denied: requested access to the resource is denied"
**Soluzione:**
Fai login al registry:
```bash
docker login 192.168.1.203:5000
```
### Le immagini non si aggiornano sulle VM
**Soluzione:**
```bash
# Forza il pull della nuova immagine
docker compose pull
docker compose up -d --force-recreate
```
---
## Note
- Lo script `build-and-push-image.sh` builderà l'immagine dalla directory `/home/alex/devel/proxmox-ha-setup/vm1`
- I file docker-compose.yml in `vm1/` e `vm2/` devono usare `build: .` per i servizi orchestrator
- Puoi usare più tag per la stessa immagine (es: `latest`, `v1.0.0`, `production`)

275
scripts/build-and-push-image.sh Executable file
View File

@@ -0,0 +1,275 @@
#!/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!"

145
scripts/generate-registry-cert.sh Executable file
View File

@@ -0,0 +1,145 @@
#!/bin/bash
# generate-registry-cert.sh
# Script per generare certificati self-signed corretti per Docker Registry
# con Subject Alternative Names (SANs)
set -e
# Parametri
REGISTRY_IP=${1:-"192.168.1.204"}
REGISTRY_HOSTNAME=${2:-"registry.local"}
CERT_DIR=${3:-"/opt/docker-registry/certs"}
CERT_DAYS=${4:-365}
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_success() { echo -e "${GREEN}$1${NC}"; }
print_error() { echo -e "${RED}$1${NC}"; }
print_info() { echo -e "${BLUE} $1${NC}"; }
if [ "$#" -eq 0 ]; then
echo "Uso: $0 [registry_ip] [registry_hostname] [cert_dir] [days]"
echo ""
echo "Parametri opzionali:"
echo " registry_ip - IP del registry (default: 192.168.1.204)"
echo " registry_hostname - Hostname del registry (default: registry.local)"
echo " cert_dir - Directory certificati (default: /opt/docker-registry/certs)"
echo " days - Validità in giorni (default: 365)"
echo ""
echo "Esempio:"
echo " $0 192.168.1.204 registry.local"
exit 0
fi
print_info "Generazione certificato self-signed per Docker Registry"
echo ""
print_info "Configurazione:"
print_info " IP: $REGISTRY_IP"
print_info " Hostname: $REGISTRY_HOSTNAME"
print_info " Directory: $CERT_DIR"
print_info " Validità: $CERT_DAYS giorni"
echo ""
# Crea directory se non esiste
mkdir -p "$CERT_DIR"
# File di output
KEY_FILE="$CERT_DIR/domain.key"
CERT_FILE="$CERT_DIR/domain.crt"
CSR_FILE="$CERT_DIR/domain.csr"
CNF_FILE="$CERT_DIR/openssl.cnf"
# Crea file di configurazione OpenSSL con SANs
cat > "$CNF_FILE" << EOF
[req]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_ca
prompt = no
[req_distinguished_name]
C = IT
ST = Italy
L = City
O = Docker Registry
OU = IT Department
CN = $REGISTRY_HOSTNAME
[req_ext]
subjectAltName = @alt_names
[v3_ca]
subjectAltName = @alt_names
basicConstraints = critical, CA:TRUE
keyUsage = critical, digitalSignature, keyEncipherment, keyCertSign
extendedKeyUsage = serverAuth
[alt_names]
DNS.1 = $REGISTRY_HOSTNAME
DNS.2 = localhost
IP.1 = $REGISTRY_IP
IP.2 = 127.0.0.1
EOF
print_info "File di configurazione creato: $CNF_FILE"
# Genera chiave privata e certificato
print_info "Generazione chiave privata e certificato..."
openssl req -newkey rsa:4096 \
-nodes \
-sha256 \
-keyout "$KEY_FILE" \
-x509 \
-days "$CERT_DAYS" \
-config "$CNF_FILE" \
-out "$CERT_FILE"
print_success "Certificato generato con successo!"
echo ""
# Verifica certificato
print_info "Verifica certificato:"
openssl x509 -in "$CERT_FILE" -text -noout | grep -A 3 "Subject Alternative Name"
echo ""
print_info "File generati:"
print_info " Chiave privata: $KEY_FILE"
print_info " Certificato: $CERT_FILE"
print_info " Config OpenSSL: $CNF_FILE"
echo ""
print_info "Prossimi passi:"
print_info ""
print_info "1. Riavvia il registry Docker con i nuovi certificati:"
echo " docker stop registry && docker rm registry"
echo " docker run -d \\"
echo " -p 5000:5000 \\"
echo " --name registry \\"
echo " --restart=always \\"
echo " -v $CERT_DIR:/certs \\"
echo " -v /opt/docker-registry/data:/var/lib/registry \\"
echo " -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \\"
echo " -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \\"
echo " registry:2"
echo ""
print_info "2. Installa il certificato sui client Docker:"
echo " # Su ogni VM che deve accedere al registry:"
echo " sudo mkdir -p /etc/docker/certs.d/$REGISTRY_IP:5000"
echo " sudo scp root@$REGISTRY_IP:$CERT_FILE /etc/docker/certs.d/$REGISTRY_IP:5000/ca.crt"
echo " sudo systemctl restart docker"
echo ""
print_info "3. (Opzionale) Installa nel sistema per curl/wget:"
echo " sudo cp $CERT_FILE /usr/local/share/ca-certificates/registry.crt"
echo " sudo update-ca-certificates"
echo ""
print_success "Setup completato!"

143
scripts/install-registry-cert.sh Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/bash
# install-registry-cert.sh
# Script per installare il certificato del registry Docker
# Supporta sia Docker standard che Docker Snap
set -e
CERT_FILE="/tmp/registry-new.crt"
REGISTRY_URL="192.168.1.204:5000"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_success() { echo -e "${GREEN}$1${NC}"; }
print_error() { echo -e "${RED}$1${NC}"; }
print_info() { echo -e "${BLUE} $1${NC}"; }
print_warning() { echo -e "${YELLOW}$1${NC}"; }
echo -e "${BLUE}================================================${NC}"
echo -e "${BLUE}INSTALLAZIONE CERTIFICATO REGISTRY${NC}"
echo -e "${BLUE}================================================${NC}"
echo ""
# Verifica che il certificato esista
if [ ! -f "$CERT_FILE" ]; then
print_error "Certificato non trovato: $CERT_FILE"
print_info "Scaricalo prima con: scp root@192.168.1.204:/opt/docker-registry/certs/domain.crt $CERT_FILE"
exit 1
fi
print_success "Certificato trovato: $CERT_FILE"
echo ""
# Verifica SANs
print_info "Verifica Subject Alternative Names nel certificato:"
if openssl x509 -in "$CERT_FILE" -text -noout | grep -q "Subject Alternative Name"; then
openssl x509 -in "$CERT_FILE" -text -noout | grep -A 2 "Subject Alternative Name"
print_success "Certificato ha SANs corretti"
else
print_error "Certificato non ha Subject Alternative Names!"
print_warning "Il certificato deve essere rigenerato sul registry"
exit 1
fi
echo ""
# Rileva tipo di installazione Docker
DOCKER_TYPE="standard"
if snap list docker &>/dev/null; then
DOCKER_TYPE="snap"
print_info "Rilevato: Docker Snap"
elif command -v docker &>/dev/null; then
print_info "Rilevato: Docker Standard"
else
print_error "Docker non trovato"
exit 1
fi
echo ""
# Installazione certificato nel sistema (funziona per entrambi)
print_info "Installazione certificato nel sistema..."
sudo cp "$CERT_FILE" /usr/local/share/ca-certificates/registry-192.168.1.204.crt
sudo chmod 644 /usr/local/share/ca-certificates/registry-192.168.1.204.crt
sudo update-ca-certificates
print_success "Certificato installato in /usr/local/share/ca-certificates/"
echo ""
# Per Docker standard, installa anche in /etc/docker/certs.d
if [ "$DOCKER_TYPE" = "standard" ]; then
print_info "Installazione certificato per Docker daemon..."
sudo mkdir -p /etc/docker/certs.d/$REGISTRY_URL
sudo cp "$CERT_FILE" /etc/docker/certs.d/$REGISTRY_URL/ca.crt
sudo chmod 644 /etc/docker/certs.d/$REGISTRY_URL/ca.crt
print_success "Certificato installato in /etc/docker/certs.d/$REGISTRY_URL/"
echo ""
fi
# Docker Snap usa i certificati di sistema, quindi non serve altro
# Verifica installazione
print_info "Verifica installazione..."
if ls /etc/ssl/certs/ | grep -q registry; then
CERT_LINK=$(ls -la /etc/ssl/certs/ | grep registry | awk '{print $9}')
print_success "Certificato symlink trovato: $CERT_LINK"
else
print_warning "Symlink non trovato (potrebbe essere normale)"
fi
echo ""
# Test connessione
echo -e "${BLUE}================================================${NC}"
echo -e "${BLUE}TEST CONNESSIONE${NC}"
echo -e "${BLUE}================================================${NC}"
echo ""
print_info "Test connessione HTTPS al registry..."
if curl -s https://$REGISTRY_URL/v2/ | grep -q '{}'; then
print_success "Connessione HTTPS: OK"
else
print_warning "Test connessione fallito (verifica che il registry sia in esecuzione)"
fi
echo ""
print_info "Test API registry..."
if curl -s https://$REGISTRY_URL/v2/_catalog >/dev/null 2>&1; then
print_success "API registry: OK"
echo ""
print_info "Immagini nel registry:"
curl -s https://$REGISTRY_URL/v2/_catalog | python3 -m json.tool 2>/dev/null || curl -s https://$REGISTRY_URL/v2/_catalog
else
print_warning "API registry non risponde"
fi
echo ""
# Istruzioni finali
echo -e "${BLUE}================================================${NC}"
echo -e "${GREEN}INSTALLAZIONE COMPLETATA!${NC}"
echo -e "${BLUE}================================================${NC}"
echo ""
print_info "Comandi per testare:"
echo ""
echo " # Test con curl"
echo " curl https://$REGISTRY_URL/v2/_catalog"
echo ""
echo " # Push immagine"
echo " docker push $REGISTRY_URL/orchestrator-app:latest"
echo ""
echo " # Pull immagine"
echo " docker pull $REGISTRY_URL/orchestrator-app:latest"
echo ""
if [ "$DOCKER_TYPE" = "snap" ]; then
print_info "Note per Docker Snap:"
print_info " - Docker Snap usa i certificati di sistema (/etc/ssl/certs/)"
print_info " - Non serve riavviare il daemon Docker"
print_info " - Se il push fallisce ancora, riavvia Snap: sudo snap restart docker"
fi
echo ""

165
scripts/setup-registry-client.sh Executable file
View File

@@ -0,0 +1,165 @@
#!/bin/bash
# setup-registry-client.sh
# Script per configurare un client Docker per accedere a un registry con certificato self-signed
set -e
REGISTRY_IP=${1:-"192.168.1.204"}
REGISTRY_PORT=${2:-5000}
CERT_SOURCE=${3}
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_success() { echo -e "${GREEN}$1${NC}"; }
print_error() { echo -e "${RED}$1${NC}"; }
print_info() { echo -e "${BLUE} $1${NC}"; }
print_warning() { echo -e "${YELLOW}$1${NC}"; }
if [ "$#" -lt 1 ]; then
echo "Uso: $0 <registry_ip> [port] [cert_file]"
echo ""
echo "Parametri:"
echo " registry_ip - IP del registry (es: 192.168.1.204)"
echo " port - Porta del registry (default: 5000)"
echo " cert_file - File certificato (opzionale, verrà scaricato se non specificato)"
echo ""
echo "Esempi:"
echo " $0 192.168.1.204"
echo " $0 192.168.1.204 5000"
echo " $0 192.168.1.204 5000 /path/to/domain.crt"
exit 1
fi
REGISTRY_URL="$REGISTRY_IP:$REGISTRY_PORT"
DOCKER_CERTS_DIR="/etc/docker/certs.d/$REGISTRY_URL"
print_info "Configurazione client Docker per registry: $REGISTRY_URL"
echo ""
# Verifica se Docker è installato
if ! command -v docker &> /dev/null; then
print_error "Docker non trovato. Installalo prima di continuare."
exit 1
fi
# Crea directory per i certificati Docker
print_info "Creazione directory certificati Docker..."
sudo mkdir -p "$DOCKER_CERTS_DIR"
print_success "Directory creata: $DOCKER_CERTS_DIR"
# Scarica o copia il certificato
if [ -z "$CERT_SOURCE" ]; then
print_info "Scaricamento certificato dal registry..."
# Tenta di scaricare il certificato usando openssl
if timeout 5 openssl s_client -showcerts -connect "$REGISTRY_URL" </dev/null 2>/dev/null | \
openssl x509 -outform PEM > /tmp/registry-cert.pem 2>/dev/null; then
sudo mv /tmp/registry-cert.pem "$DOCKER_CERTS_DIR/ca.crt"
print_success "Certificato scaricato con successo"
else
print_error "Impossibile scaricare il certificato automaticamente"
print_warning "Opzioni:"
print_info " 1. Copia manualmente il certificato dal registry:"
print_info " scp root@$REGISTRY_IP:/opt/docker-registry/certs/domain.crt /tmp/registry.crt"
print_info " sudo cp /tmp/registry.crt $DOCKER_CERTS_DIR/ca.crt"
print_info ""
print_info " 2. Riavvia questo script specificando il file certificato:"
print_info " $0 $REGISTRY_IP $REGISTRY_PORT /path/to/cert.crt"
exit 1
fi
else
if [ ! -f "$CERT_SOURCE" ]; then
print_error "File certificato non trovato: $CERT_SOURCE"
exit 1
fi
print_info "Copia certificato da: $CERT_SOURCE"
sudo cp "$CERT_SOURCE" "$DOCKER_CERTS_DIR/ca.crt"
print_success "Certificato copiato"
fi
# Verifica permessi
sudo chmod 644 "$DOCKER_CERTS_DIR/ca.crt"
# Verifica certificato
print_info "Verifica certificato installato..."
if sudo openssl x509 -in "$DOCKER_CERTS_DIR/ca.crt" -text -noout > /dev/null 2>&1; then
print_success "Certificato valido"
print_info "Dettagli certificato:"
sudo openssl x509 -in "$DOCKER_CERTS_DIR/ca.crt" -noout -subject -issuer -dates
# Mostra SANs se presenti
if sudo openssl x509 -in "$DOCKER_CERTS_DIR/ca.crt" -text -noout | grep -q "Subject Alternative Name"; then
print_info "Subject Alternative Names:"
sudo openssl x509 -in "$DOCKER_CERTS_DIR/ca.crt" -text -noout | grep -A 3 "Subject Alternative Name"
else
print_warning "Certificato non ha Subject Alternative Names (SANs)"
print_warning "Considera di rigenerare il certificato con: ./scripts/generate-registry-cert.sh"
fi
else
print_error "Certificato non valido"
exit 1
fi
# Riavvia Docker
print_info "Riavvio Docker daemon..."
sudo systemctl restart docker
sleep 3
if sudo systemctl is-active --quiet docker; then
print_success "Docker riavviato con successo"
else
print_error "Errore nel riavvio di Docker"
exit 1
fi
# Test connessione al registry
echo ""
print_info "Test connessione al registry..."
# Test HTTPS
if timeout 5 openssl s_client -connect "$REGISTRY_URL" -CAfile "$DOCKER_CERTS_DIR/ca.crt" </dev/null 2>&1 | grep -q "Verify return code: 0"; then
print_success "Connessione HTTPS con verifica certificato: OK"
elif timeout 5 openssl s_client -connect "$REGISTRY_URL" </dev/null 2>&1 | grep -q "CONNECTED"; then
print_warning "Connessione HTTPS: OK ma verifica certificato fallita"
print_info "Il certificato potrebbe essere self-signed o avere SANs non corretti"
else
print_error "Impossibile connettersi al registry"
fi
# Test Docker login
echo ""
print_info "Per testare Docker con il registry, esegui:"
echo " docker pull $REGISTRY_URL/orchestrator-app:latest"
echo ""
print_info "Se il registry richiede autenticazione:"
echo " docker login $REGISTRY_URL"
echo ""
# Opzionale: installa anche nel sistema
read -p "Vuoi installare il certificato anche nel sistema per curl/wget? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
print_info "Installazione certificato nel sistema..."
sudo cp "$DOCKER_CERTS_DIR/ca.crt" /usr/local/share/ca-certificates/registry-$REGISTRY_IP.crt
sudo update-ca-certificates
print_success "Certificato installato nel sistema"
# Test con curl
if curl -I "https://$REGISTRY_URL/v2/" 2>&1 | grep -q "200 OK"; then
print_success "Test curl: OK"
else
print_warning "Test curl fallito (normale se registry richiede autenticazione)"
fi
fi
echo ""
print_success "Setup client completato!"
print_info "Il Docker daemon ora può accedere a: $REGISTRY_URL"

View File

@@ -1,6 +1,6 @@
#!/bin/bash
rsync -avz --exclude='*.pyc' --exclude '__pycache__/' /home/alex/devel/ASE/src /home/alex/devel/proxmox-ha-setup/vm1/
rsync -avz --exclude='*.pyc' --exclude '__pycache__/' /home/alex/devel/ASE/src /home/alex/devel/proxmox-ha-setup/vm2/
rsync -avz -e "ssh -p 2222" --exclude='*.pyc' /home/alex/devel/proxmox-ha-setup/vm1/ root@192.168.1.201:/opt/myapp/
rsync -avz -e "ssh -p 2222" --exclude='*.pyc' /home/alex/devel/proxmox-ha-setup/vm2/ root@192.168.1.202:/opt/myapp/
#rsync -avz --exclude='*.pyc' --exclude '__pycache__/' /home/alex/devel/ASE/src /home/alex/devel/proxmox-ha-setup/vm1/
#rsync -avz --exclude='*.pyc' --exclude '__pycache__/' /home/alex/devel/ASE/src /home/alex/devel/proxmox-ha-setup/vm2/
rsync -avz -e "ssh -p 2222" /home/alex/devel/proxmox-ha-setup/vm1/ root@192.168.1.201:/opt/ase/
rsync -avz -e "ssh -p 2222" /home/alex/devel/proxmox-ha-setup/vm2/ root@192.168.1.202:/opt/ase/

190
scripts/test-pyc-image.sh Executable file
View File

@@ -0,0 +1,190 @@
#!/bin/bash
# test-pyc-image.sh
# Script per testare che l'immagine Docker funzioni correttamente con solo file .pyc
# Uso: ./test-pyc-image.sh [image_name]
# Esempio: ./test-pyc-image.sh orchestrator-app:latest
set -e
# ==================== CONFIGURAZIONE ====================
IMAGE_NAME=${1:-"orchestrator-app:latest"}
# 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}"; }
# ==================== SCRIPT PRINCIPALE ====================
print_header "TEST IMMAGINE DOCKER CON BYTECODE"
print_info "Immagine da testare: ${CYAN}$IMAGE_NAME${NC}"
echo ""
# Verifica che l'immagine esista
if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then
print_error "Immagine non trovata: $IMAGE_NAME"
print_info "Esegui prima: ./scripts/build-and-push-image.sh"
exit 1
fi
print_success "Immagine trovata"
# ==================== TEST 1: Verifica assenza file .py ====================
print_header "TEST 1: Verifica rimozione file sorgente .py"
print_info "Controllo file .py in /app/src..."
PY_FILES=$(docker run --rm "$IMAGE_NAME" find /app/src -type f -name "*.py" 2>/dev/null | wc -l)
if [ "$PY_FILES" -eq 0 ]; then
print_success "Nessun file .py trovato in /app/src - OK!"
else
print_warning "Trovati $PY_FILES file .py in /app/src"
docker run --rm "$IMAGE_NAME" find /app/src -type f -name "*.py"
fi
# ==================== TEST 2: Verifica presenza file .pyc ====================
print_header "TEST 2: Verifica presenza file bytecode .pyc"
print_info "Controllo file .pyc in /app/src..."
PYC_FILES=$(docker run --rm "$IMAGE_NAME" find /app/src -type f -name "*.pyc" 2>/dev/null | wc -l)
if [ "$PYC_FILES" -gt 0 ]; then
print_success "Trovati $PYC_FILES file .pyc - OK!"
else
print_error "Nessun file .pyc trovato - qualcosa è andato storto"
exit 1
fi
# ==================== TEST 3: Verifica importazione moduli ====================
print_header "TEST 3: Test importazione moduli Python"
print_info "Test import di src..."
if docker run --rm "$IMAGE_NAME" python -c "import src; print('Import src: OK')" 2>/dev/null; then
print_success "Import src funziona correttamente"
else
print_error "Import src fallito"
exit 1
fi
# ==================== TEST 4: Lista moduli disponibili ====================
print_header "TEST 4: Verifica moduli disponibili"
print_info "Moduli in src:"
docker run --rm "$IMAGE_NAME" python -c "
import pkgutil
import src
for importer, modname, ispkg in pkgutil.walk_packages(path=src.__path__, prefix='src.'):
print(f' - {modname} (package)' if ispkg else f' - {modname}')
" 2>/dev/null || print_warning "Impossibile elencare i moduli"
# ==================== TEST 5: Verifica dimensione immagine ====================
print_header "TEST 5: Analisi dimensione immagine"
IMAGE_SIZE=$(docker images "$IMAGE_NAME" --format "{{.Size}}")
print_info "Dimensione immagine: ${CYAN}$IMAGE_SIZE${NC}"
# Conta i file per tipo
print_info "Statistiche file in /app/src:"
docker run --rm "$IMAGE_NAME" sh -c '
echo " File .py: $(find /app/src -type f -name "*.py" 2>/dev/null | wc -l)"
echo " File .pyc: $(find /app/src -type f -name "*.pyc" 2>/dev/null | wc -l)"
echo " Totale: $(find /app/src -type f 2>/dev/null | wc -l)"
'
# ==================== TEST 6: Test esecuzione moduli ====================
print_header "TEST 6: Test esecuzione moduli orchestrator (dry-run)"
print_info "Test esecuzione load_orchestrator..."
if docker run --rm "$IMAGE_NAME" timeout 2 python -c "
try:
import src.load_orchestrator
print('Module src.load_orchestrator: OK')
except ImportError as e:
print(f'Import error: {e}')
exit(1)
" 2>/dev/null; then
print_success "Modulo load_orchestrator importabile"
else
print_warning "Test load_orchestrator timeout o errore (normale se richiede DB)"
fi
print_info "Test esecuzione elab_orchestrator..."
if docker run --rm "$IMAGE_NAME" timeout 2 python -c "
try:
import src.elab_orchestrator
print('Module src.elab_orchestrator: OK')
except ImportError as e:
print(f'Import error: {e}')
exit(1)
" 2>/dev/null; then
print_success "Modulo elab_orchestrator importabile"
else
print_warning "Test elab_orchestrator timeout o errore (normale se richiede DB)"
fi
# ==================== TEST 7: Verifica variabili ambiente ====================
print_header "TEST 7: Verifica configurazione ambiente"
docker run --rm "$IMAGE_NAME" python -c "
import os
import sys
print('Python version:', sys.version)
print('PYTHONUNBUFFERED:', os.getenv('PYTHONUNBUFFERED', 'not set'))
print('PYTHONDONTWRITEBYTECODE:', os.getenv('PYTHONDONTWRITEBYTECODE', 'not set'))
print('PYTHONPATH:', os.getenv('PYTHONPATH', 'not set'))
print('Python path:', sys.path)
"
# ==================== RIEPILOGO ====================
print_header "TEST COMPLETATI! ✅"
echo ""
print_success "L'immagine contiene solo bytecode Python (.pyc)"
print_success "I file sorgente .py sono stati rimossi correttamente"
print_success "I moduli sono importabili e funzionanti"
echo ""
print_info "Vantaggi:"
print_info " ✓ Protezione del codice sorgente"
print_info " ✓ Riduzione dimensione immagine"
print_info " ✓ Leggero miglioramento delle performance"
print_info " ✓ Rimozione docstring e assert (con -OO)"
echo ""
print_warning "Note:"
print_warning " - I traceback mostreranno solo numeri di riga, non il codice"
print_warning " - Il debugging sarà più difficile senza codice sorgente"
print_warning " - Mantieni i sorgenti in un repository separato per sviluppo"
echo ""
print_info "Prossimi passi:"
print_info " 1. Push dell'immagine al registry: ./scripts/build-and-push-image.sh"
print_info " 2. Deploy sulle VM: docker compose pull && docker compose up -d"
echo ""

111
scripts/update-compose-image.sh Executable file
View File

@@ -0,0 +1,111 @@
#!/bin/bash
# update-compose-image.sh
# Script per aggiornare i file docker-compose.yml per usare l'immagine dal registry
# Uso: ./update-compose-image.sh <registry_url> <image_name> <tag>
# Esempio: ./update-compose-image.sh registry.example.com:5000 orchestrator-app latest
set -e
# ==================== CONFIGURAZIONE ====================
if [ "$#" -ne 3 ]; then
echo "Uso: $0 <registry_url> <image_name> <tag>"
echo ""
echo "Parametri:"
echo " registry_url - URL del registry privato"
echo " image_name - Nome dell'immagine"
echo " tag - Tag dell'immagine"
echo ""
echo "Esempio:"
echo " $0 registry.example.com:5000 orchestrator-app latest"
echo ""
echo "Lo script aggiornerà i file docker-compose.yml in vm1/ e vm2/"
echo "sostituendo 'build: .' con 'image: registry_url/image_name:tag'"
exit 1
fi
REGISTRY_URL=$1
IMAGE_NAME=$2
TAG=$3
FULL_IMAGE_NAME="${REGISTRY_URL}/${IMAGE_NAME}:${TAG}"
# Directory dei progetti
VM1_DIR="/home/alex/devel/proxmox-ha-setup/vm1"
VM2_DIR="/home/alex/devel/proxmox-ha-setup/vm2"
# 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_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}"; }
update_compose_file() {
local compose_file=$1
local backup_file="${compose_file}.backup"
if [ ! -f "$compose_file" ]; then
print_warning "File non trovato: $compose_file"
return 1
fi
# Crea backup
cp "$compose_file" "$backup_file"
print_info "Backup creato: $backup_file"
# Sostituisci 'build: .' con 'image: ...'
sed -i "s|build: \.|image: ${FULL_IMAGE_NAME}|g" "$compose_file"
print_success "Aggiornato: $compose_file"
return 0
}
# ==================== SCRIPT PRINCIPALE ====================
echo -e "${BLUE}================================================${NC}"
echo -e "${BLUE}AGGIORNAMENTO DOCKER-COMPOSE FILES${NC}"
echo -e "${BLUE}================================================${NC}"
echo ""
print_info "Immagine da utilizzare: ${CYAN}$FULL_IMAGE_NAME${NC}"
echo ""
# Aggiorna vm1/docker-compose.yml
if [ -f "$VM1_DIR/docker-compose.yml" ]; then
print_info "Aggiornamento $VM1_DIR/docker-compose.yml..."
update_compose_file "$VM1_DIR/docker-compose.yml"
else
print_warning "File non trovato: $VM1_DIR/docker-compose.yml"
fi
echo ""
# Aggiorna vm2/docker-compose.yml
if [ -f "$VM2_DIR/docker-compose.yml" ]; then
print_info "Aggiornamento $VM2_DIR/docker-compose.yml..."
update_compose_file "$VM2_DIR/docker-compose.yml"
else
print_warning "File non trovato: $VM2_DIR/docker-compose.yml"
fi
echo ""
echo -e "${BLUE}================================================${NC}"
echo -e "${GREEN}✓ Aggiornamento completato!${NC}"
echo -e "${BLUE}================================================${NC}"
echo ""
print_info "I file docker-compose.yml ora usano: ${CYAN}$FULL_IMAGE_NAME${NC}"
print_info "I file di backup sono stati creati con estensione .backup"
echo ""
print_warning "Ricordati di fare il pull dell'immagine sulle VM:"
print_info " ssh root@192.168.1.201 'cd /opt/myapp && docker pull $FULL_IMAGE_NAME'"
print_info " ssh root@192.168.1.202 'cd /opt/myapp && docker pull $FULL_IMAGE_NAME'"
echo ""