16 KiB
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
- Setup Registry Docker Privato
- Protezione Codice Sorgente (Bytecode)
- Build e Push dell'Immagine
- Aggiornamento Docker Compose
- Deploy sulle VM
Setup Registry Docker Privato
Opzione 1: Registry Locale Semplice (HTTP - Solo per sviluppo)
# 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
# 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.
# 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
# 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)
# 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
# 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
# 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:
# 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:
- Compilare tutti i file Python in bytecode (
.pyc) usando Python con ottimizzazione-OO - Rimuovere tutti i file sorgente
.py - Mantenere solo i file bytecode compilati in
__pycache__/
# 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:
# 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
.pyin/app/src - ✅ Presenza di file
.pyccompilati - ✅ 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
./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:standardodistroless(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
# 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
- ✅ Verifica prerequisiti (Docker)
- ✅ Controlla che esistano Dockerfile e directory progetto
- ✅ Mostra configurazione e chiede conferma
- ✅ Builda l'immagine Docker
- ✅ Tagga l'immagine per il registry
- ✅ Mostra informazioni sull'immagine (dimensione, layer)
- ✅ Opzionalmente testa l'immagine localmente
- ✅ Pusha l'immagine al registry
- ✅ 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
./scripts/update-compose-image.sh <registry_url> <image_name> <tag>
Esempio
# 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
- ✅ Crea backup dei file docker-compose.yml (
.backup) - ✅ Sostituisce
build: .conimage: registry_url/image_name:tag - ✅ Aggiorna entrambi i file vm1/ e vm2/
Prima e Dopo
Prima:
orchestrator-1-load:
build: .
container_name: orchestrator-1-load
...
Dopo:
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:
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
- Versioning: Usa tag semantici (v1.0.0, v1.1.0) invece di
latestper produzione - Backup: Monta un volume per
/var/lib/registryper persistenza - Security: Usa HTTPS e autenticazione per registri in produzione
- Cleanup: Rimuovi regolarmente immagini vecchie dal registry
- Testing: Testa sempre l'immagine localmente prima del push
- Documentation: Documenta le modifiche in ogni versione
Troubleshooting
Errore: "connection refused" durante il push
Soluzione:
# 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:
{
"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:
docker login 192.168.1.203:5000
Le immagini non si aggiornano sulle VM
Soluzione:
# Forza il pull della nuova immagine
docker compose pull
docker compose up -d --force-recreate
Note
- Lo script
build-and-push-image.shbuilderà l'immagine dalla directory/home/alex/devel/proxmox-ha-setup/vm1 - I file docker-compose.yml in
vm1/evm2/devono usarebuild: .per i servizi orchestrator - Puoi usare più tag per la stessa immagine (es:
latest,v1.0.0,production)