docker image su registry e create con pyinstaller

This commit is contained in:
2025-11-30 21:19:06 +01:00
parent 3943172db8
commit fd192c7f6b
12 changed files with 701 additions and 87 deletions

View File

@@ -1,34 +1,118 @@
FROM python:3.12-slim
# Multi-stage build con PyInstaller per protezione totale del codice
# Stage 1: Build con PyInstaller
FROM python:3.12-slim AS builder
# Installa uv
# Installa uv e PyInstaller
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# Installa binutils richiesto da PyInstaller
RUN apt-get update && apt-get install -y binutils && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copia pyproject.toml, codice sorgente e file statici
# NOTA: env/ NON viene copiato - sarà montato come volume esterno
# Copia i file necessari per la build
COPY pyproject.toml ./
COPY src/ ./src/
COPY certs/ ./certs/
COPY matlab_func/ ./matlab_func/
# Installa le dipendenze
RUN uv pip install --system -e .
# Installa le dipendenze e PyInstaller
RUN uv pip install --system -e . && \
uv pip install --system pyinstaller
# Compila tutti i file Python in bytecode
# Usa -OO per rimuovere docstring e assert (ottimizzazione massima)
RUN python -OO -m compileall /app/src || true
# Compila tutti gli entry point con PyInstaller
# Ogni entry point diventa un binario standalone
# Include metadata per pacchetti che lo richiedono
RUN pyinstaller \
--onefile \
--name load_orchestrator \
--collect-all src \
--collect-all certs \
--collect-all matlab_func \
--collect-all aioftp \
--collect-all aiomysql \
--collect-all aiofiles \
--collect-all aiosmtplib \
--collect-all cryptography \
--hidden-import=src \
--hidden-import=src.utils \
--hidden-import=src.refactory_scripts \
src/load_orchestrator.py && \
pyinstaller \
--onefile \
--name elab_orchestrator \
--collect-all src \
--collect-all certs \
--collect-all matlab_func \
--collect-all aioftp \
--collect-all aiomysql \
--collect-all aiofiles \
--collect-all aiosmtplib \
--collect-all cryptography \
--hidden-import=src \
--hidden-import=src.utils \
--hidden-import=src.refactory_scripts \
src/elab_orchestrator.py && \
pyinstaller \
--onefile \
--name send_orchestrator \
--collect-all src \
--collect-all certs \
--collect-all matlab_func \
--collect-all aioftp \
--collect-all aiomysql \
--collect-all aiofiles \
--collect-all aiosmtplib \
--collect-all cryptography \
--hidden-import=src \
--hidden-import=src.utils \
--hidden-import=src.refactory_scripts \
src/send_orchestrator.py && \
pyinstaller \
--onefile \
--name ftp_csv_receiver \
--collect-all src \
--collect-all certs \
--collect-all matlab_func \
--collect-all aioftp \
--collect-all aiomysql \
--collect-all aiofiles \
--collect-all aiosmtplib \
--collect-all cryptography \
--hidden-import=src \
--hidden-import=src.utils \
--hidden-import=src.refactory_scripts \
src/ftp_csv_receiver.py
# Rimuovi tutti i file sorgente .py, lasciando solo i .pyc compilati in __pycache__
RUN find /app/src -type f -name "*.py" -delete
# Crea directory per runtime (saranno montate come volumi)
RUN mkdir -p /app/dist/logs /app/dist/aseftp/csvfs /app/dist/matlab_runtime /app/dist/env
# Crea directory per i log, FTP, MATLAB e ENV (sarà montata)
RUN mkdir -p /app/logs /app/aseftp/csvfs /app/certs /app/matlab_runtime /app/matlab_func /app/env
# ====================================================================
# STAGE 2: IMMAGINE FINALE (RUNTIME MINIMA)
# Contiene solo il binario compilato, nessun codice sorgente.
# ====================================================================
FROM python:3.12-slim
WORKDIR /app
# Copia tutti i binari compilati
COPY --from=builder /app/dist/load_orchestrator ./load_orchestrator
COPY --from=builder /app/dist/elab_orchestrator ./elab_orchestrator
COPY --from=builder /app/dist/send_orchestrator ./send_orchestrator
COPY --from=builder /app/dist/ftp_csv_receiver ./ftp_csv_receiver
# Copia i dati statici necessari
COPY certs/ ./certs/
COPY matlab_func/ ./matlab_func/
# Copia le directory vuote per runtime (saranno montate come volumi)
RUN mkdir -p ./logs ./aseftp/csvfs ./matlab_runtime ./env
# Rendi tutti gli eseguibili executable
RUN chmod +x ./load_orchestrator ./elab_orchestrator ./send_orchestrator ./ftp_csv_receiver
# Variabili ambiente
ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH=/app
# Disabilita la creazione di nuovi file .pyc a runtime (non necessari dato che abbiamo già i .pyc)
ENV PYTHONDONTWRITEBYTECODE=1
# Il comando verrà specificato nel docker-compose.yml per ogni servizio
CMD ["python", "-m", "src.elab_orchestrator"]
# Default: elab_orchestrator (sarà sovrascritto da docker-compose)
CMD ["./elab_orchestrator"]

View File

@@ -18,12 +18,14 @@ COPY matlab_func/ ./matlab_func/
RUN uv pip install --python=/usr/local/bin/python3 --target=/app/deps .
# Compila tutti i file Python in bytecode
RUN python -OO -m compileall /app/src || true
# Usa -m compileall per generare .pyc standard (non .opt-2.pyc)
RUN python -m compileall /app/src
# Rimuovi tutti i file sorgente .py, lasciando solo i .pyc compilati
RUN find /app/src -type f -name "*.py" -delete
# Manteniamo i file .py per compatibilità (Python userà comunque i .pyc precompilati)
# Nota: Il codice sorgente è visibile ma Python esegue sempre il bytecode .pyc
# Per protezione completa del codice, considera l'uso di PyArmor o simili
# Rimuovi anche i .py dalle dipendenze
# Rimuovi i .py dalle dipendenze per ridurre la dimensione
RUN find /app/deps -type f -name "*.py" -delete || true
# Crea directory vuote per runtime (saranno montate come volumi)

View File

@@ -1,36 +1,11 @@
services:
mysql:
image: mysql:8.0
container_name: mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-Ase@2025}
MYSQL_DATABASE: ${MYSQL_DATABASE:-ase_lar}
MYSQL_USER: ${MYSQL_USER:-ase_lar}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-ase_lar}
TZ: Europe/Rome
volumes:
- mysql_data:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
networks:
- app-network
ports:
- "3306:3306"
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-Ase@2025}" ]
interval: 10s
timeout: 5s
retries: 3
labels:
logging: "alloy"
logging_jobname: "mysql"
orchestrator-1-load:
build: .
image: 192.168.1.204:5000/orchestrator-app:latest
container_name: orchestrator-1-load
restart: unless-stopped
command: [ "python", "-m", "src.load_orchestrator" ]
command: ["./load_orchestrator"]
environment:
APP_ENV_PATH: /app
DB_HOST: ${VIP:-192.168.1.210}
ORCHESTRATOR_ID: 1
TZ: Europe/Rome
@@ -44,11 +19,12 @@ services:
labels:
logging: "alloy"
orchestrator-2-elab:
build: .
image: 192.168.1.204:5000/orchestrator-app:latest
container_name: orchestrator-2-elab
restart: unless-stopped
command: [ "python", "-m", "src.elab_orchestrator" ]
command: ["./elab_orchestrator"]
environment:
APP_ENV_PATH: /app
DB_HOST: ${VIP:-192.168.1.210}
ORCHESTRATOR_ID: 2
TZ: Europe/Rome
@@ -62,11 +38,12 @@ services:
labels:
logging: "alloy"
orchestrator-3-send:
build: .
image: 192.168.1.204:5000/orchestrator-app:latest
container_name: orchestrator-3-send
restart: unless-stopped
command: [ "python", "-m", "src.send_orchestrator" ]
command: ["./send_orchestrator"]
environment:
APP_ENV_PATH: /app
DB_HOST: ${VIP:-192.168.1.210}
ORCHESTRATOR_ID: 3
TZ: Europe/Rome
@@ -80,11 +57,12 @@ services:
labels:
logging: "alloy"
ftp-server-1:
build: .
image: 192.168.1.204:5000/orchestrator-app:latest
container_name: ftp-server-1
restart: unless-stopped
command: [ "python", "-m", "src.ftp_csv_receiver" ]
command: ["./ftp_csv_receiver"]
environment:
APP_ENV_PATH: /app
DB_HOST: ${VIP:-192.168.1.210}
FTP_INSTANCE_ID: 1
FTP_MODE: ftp
@@ -108,11 +86,12 @@ services:
labels:
logging: "alloy"
sftp-server-1:
build: .
image: 192.168.1.204:5000/orchestrator-app:latest
container_name: sftp-server-1
restart: unless-stopped
command: [ "python", "-m", "src.ftp_csv_receiver" ]
command: ["./ftp_csv_receiver"]
environment:
APP_ENV_PATH: /app
DB_HOST: ${VIP:-192.168.1.210}
FTP_INSTANCE_ID: 11
FTP_MODE: sftp
@@ -185,5 +164,4 @@ services:
networks:
app-network:
volumes:
mysql_data:
app-logs:

View File

@@ -0,0 +1,189 @@
services:
mysql:
image: mysql:8.0
container_name: mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-Ase@2025}
MYSQL_DATABASE: ${MYSQL_DATABASE:-ase_lar}
MYSQL_USER: ${MYSQL_USER:-ase_lar}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-ase_lar}
TZ: Europe/Rome
volumes:
- mysql_data:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
networks:
- app-network
ports:
- "3306:3306"
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-Ase@2025}" ]
interval: 10s
timeout: 5s
retries: 3
labels:
logging: "alloy"
logging_jobname: "mysql"
orchestrator-1-load:
build: .
container_name: orchestrator-1-load
restart: unless-stopped
command: [ "python", "-m", "src.load_orchestrator" ]
environment:
DB_HOST: ${VIP:-192.168.1.210}
ORCHESTRATOR_ID: 1
TZ: Europe/Rome
volumes:
- app-logs:/app/logs
- ./env:/app/env:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
networks:
- app-network
labels:
logging: "alloy"
orchestrator-2-elab:
build: .
container_name: orchestrator-2-elab
restart: unless-stopped
command: [ "python", "-m", "src.elab_orchestrator" ]
environment:
DB_HOST: ${VIP:-192.168.1.210}
ORCHESTRATOR_ID: 2
TZ: Europe/Rome
volumes:
- app-logs:/app/logs
- ./env:/app/env:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
networks:
- app-network
labels:
logging: "alloy"
orchestrator-3-send:
build: .
container_name: orchestrator-3-send
restart: unless-stopped
command: [ "python", "-m", "src.send_orchestrator" ]
environment:
DB_HOST: ${VIP:-192.168.1.210}
ORCHESTRATOR_ID: 3
TZ: Europe/Rome
volumes:
- app-logs:/app/logs
- ./env:/app/env:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
networks:
- app-network
labels:
logging: "alloy"
ftp-server-1:
build: .
container_name: ftp-server-1
restart: unless-stopped
command: [ "python", "-m", "src.ftp_csv_receiver" ]
environment:
DB_HOST: ${VIP:-192.168.1.210}
FTP_INSTANCE_ID: 1
FTP_MODE: ftp
TZ: Europe/Rome
FTP_PASSIVE_PORT: "40000"
FTP_EXTERNAL_IP: ${VIP:-192.168.1.210}
# File Processing Behavior
# DELETE_AFTER_PROCESSING: "true" # Cancella file dopo elaborazione corretta (default: false = mantiene i file)
volumes:
- app-logs:/app/logs
- ./aseftp:/app/aseftp
- ./env:/app/env:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
networks:
- app-network
ports:
- "40000-40499:40000-40499"
expose:
- "21"
labels:
logging: "alloy"
sftp-server-1:
build: .
container_name: sftp-server-1
restart: unless-stopped
command: [ "python", "-m", "src.ftp_csv_receiver" ]
environment:
DB_HOST: ${VIP:-192.168.1.210}
FTP_INSTANCE_ID: 11
FTP_MODE: sftp
FTP_PORT: "22"
TZ: Europe/Rome
# File Processing Behavior
# DELETE_AFTER_PROCESSING: "true" # Cancella file dopo elaborazione corretta (default: false = mantiene i file)
volumes:
- app-logs:/app/logs
- ./aseftp:/app/aseftp
- ./env:/app/env:ro
- ./ssh_host_key:/app/ssh_host_key:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
networks:
- app-network
ports:
- "22:22"
labels:
logging: "alloy"
haproxy:
image: haproxy:2.8-alpine
container_name: haproxy
restart: unless-stopped
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
networks:
- app-network
ports:
- "21:21"
- "8404:8404"
labels:
logging: "alloy"
keepalived:
image: alpine:latest
container_name: keepalived
restart: unless-stopped
cap_add:
- NET_ADMIN
- NET_BROADCAST
- NET_RAW
network_mode: host
volumes:
- ./keepalived-master.conf:/etc/keepalived/keepalived.conf:ro
command: sh -c "apk add --no-cache keepalived && keepalived -n -D -l -f /etc/keepalived/keepalived.conf"
alloy:
image: grafana/alloy:latest
container_name: alloy
restart: unless-stopped
environment:
TZ: Europe/Rome
volumes:
- ./alloy-config.alloy:/etc/alloy/config.alloy:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/host/root:ro
command:
- run
- --server.http.listen-addr=0.0.0.0:12345
- --storage.path=/var/lib/alloy/data
- /etc/alloy/config.alloy
ports:
- "12345:12345" # Alloy UI
networks:
- app-network
networks:
app-network:
volumes:
mysql_data:
app-logs:

2
vm1/env/ftp.ini vendored
View File

@@ -33,5 +33,5 @@
[csv]
Infos = IP|Subnet|Gateway
[ts_pini]:
[ts_pini]
path_match = [276_208_TS0003]:TS0003|[Neuchatel_CDP]:TS7|[TS0006_EP28]:=|[TS0007_ChesaArcoiris]:=|[TS0006_EP28_3]:=|[TS0006_EP28_4]:TS0006_EP28_4|[TS0006_EP28_5]:TS0006_EP28_5|[TS18800]:=|[Granges_19 100]:=|[Granges_19 200]:=|[Chesa_Arcoiris_2]:=|[TS0006_EP28_1]:=|[TS_PS_Petites_Croisettes]:=|[_Chesa_Arcoiris_1]:=|[TS_test]:=|[TS-VIME]:=

4
vm1/env/load.ini vendored
View File

@@ -1,5 +1,5 @@
[logging]:
[logging]
logFilename = /app/logs/load_raw_data.log
[threads]:
[threads]
max_num = 5

View File

@@ -22,7 +22,7 @@ frontend mysql_frontend
backend mysql_backend
mode tcp
server mysql1 mysql:3306 check
server mysql1 192.168.1.201:3306 check
frontend ftp_control
bind *:21