Skip to content

Latest commit

 

History

History
798 lines (600 loc) · 16.6 KB

File metadata and controls

798 lines (600 loc) · 16.6 KB

Guida Deployment - Dashboard Lemmario AtLiTeG

Panoramica

Questa guida fornisce istruzioni dettagliate per il deployment della Dashboard Lemmario AtLiTeG in vari ambienti (sviluppo, staging, produzione). L'applicazione utilizza Docker per garantire consistenza tra ambienti.

Prerequisiti

Software Richiesto

  • Docker: v20.10+ (Installa Docker)
  • Docker Compose: v2.0+ (incluso con Docker Desktop)
  • Git: v2.30+ (per clonare repository)
  • Node.js: v20+ (solo per sviluppo locale senza Docker)
  • npm: v10+ (incluso con Node.js)

Verifica Installazioni

docker --version
# Docker version 20.10.x o superiore

docker-compose --version
# Docker Compose version v2.x.x o superiore

node --version
# v20.x.x o superiore (opzionale)

npm --version
# 10.x.x o superiore (opzionale)

Struttura Deployment

File di Configurazione

atliteg-map/
├── Lemmario_figma/
│   ├── Dockerfile              # Multi-stage build
│   ├── docker-compose.yml      # Orchestrazione servizi
│   ├── nginx.conf              # Configurazione Nginx
│   ├── .dockerignore           # File esclusi da build
│   ├── package.json            # Dipendenze Node.js
│   └── vite.config.ts          # Configurazione Vite
├── data/                        # Dataset (mounted as volume)
│   ├── Lemmi_forme_atliteg_updated.csv
│   └── Ambiti geolinguistici newline.json
└── docs/                        # Documentazione

Ambiente di Sviluppo

Opzione 1: Dev Server Locale (Vite)

Vantaggi: Hot Module Replacement (HMR), debugging facile Quando usarlo: Sviluppo attivo con modifiche frequenti

# 1. Naviga nella directory del progetto
cd /home/ale/docker/atliteg-map/Lemmario_figma

# 2. Installa dipendenze
npm ci --legacy-peer-deps

# 3. Avvia dev server
npm run dev

# 4. Apri browser su http://localhost:5173

Configurazione Vite (vite.config.ts):

export default defineConfig({
  server: {
    port: 5173,
    host: true,  // Espone su 0.0.0.0
    strictPort: true,
    watch: {
      usePolling: true,  // Necessario per Docker volumes
    },
  },
});

Variabili d'Ambiente (.env.development):

VITE_API_BASE_URL=http://localhost:5173
VITE_DATA_PATH=/data

Opzione 2: Docker Development

Vantaggi: Ambiente identico a produzione, isolamento Quando usarlo: Testing deployment, verifica build

# 1. Naviga nella directory
cd /home/ale/docker/atliteg-map/Lemmario_figma

# 2. Build immagine
docker-compose build

# 3. Avvia container
docker-compose up -d

# 4. Apri browser su http://localhost:9000

Monitoring:

# Visualizza logs
docker-compose logs -f

# Verifica status container
docker-compose ps

# Restart servizio
docker-compose restart

# Stop servizi
docker-compose down

Ambiente di Produzione

Deployment Docker (Consigliato)

Step 1: Preparazione Server

# Installa Docker su server Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Aggiungi utente al gruppo docker
sudo usermod -aG docker $USER
newgrp docker

# Installa Docker Compose
sudo apt-get update
sudo apt-get install docker-compose-plugin

# Verifica installazioni
docker --version
docker compose version

Step 2: Clona Repository

# SSH nel server
ssh user@your-server.com

# Clona repository
git clone https://github.com/your-org/atliteg-map.git
cd atliteg-map/Lemmario_figma

# (Opzionale) Checkout branch specifico
git checkout production

Step 3: Configurazione Ambiente

Crea file .env.production:

# Configurazione Produzione
NODE_ENV=production
VITE_API_BASE_URL=https://your-domain.com
VITE_DATA_PATH=/data

# Nginx
NGINX_PORT=9000
NGINX_WORKERS=auto
NGINX_WORKER_CONNECTIONS=1024

# Health Check
HEALTH_CHECK_INTERVAL=30s
HEALTH_CHECK_TIMEOUT=3s
HEALTH_CHECK_RETRIES=3

Opzionale: Modifica docker-compose.yml per produzione:

version: '3.8'

services:
  lemmario-dashboard:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - NODE_ENV=production
    container_name: atliteg-lemmario-prod
    restart: unless-stopped
    ports:
      - "9000:9000"
    volumes:
      - ../data:/usr/share/nginx/html/data:ro
    environment:
      - NODE_ENV=production
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 40s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - atliteg-network

networks:
  atliteg-network:
    driver: bridge

Step 4: Build e Deploy

# Build immagine ottimizzata
docker-compose build --no-cache

# Avvia container in background
docker-compose up -d

# Verifica logs
docker-compose logs -f

# Verifica health check
docker ps
# STATUS: Up X minutes (healthy)

Step 5: Verifica Deployment

# Test endpoint
curl -I http://localhost:9000

# Dovrebbe ritornare:
# HTTP/1.1 200 OK
# Content-Type: text/html

# Test health check
curl http://localhost:9000/health

# Verifica metriche container
docker stats lemmario-dashboard

Configurazione Nginx Reverse Proxy (Opzionale)

Se vuoi esporre l'applicazione su dominio pubblico con HTTPS:

File /etc/nginx/sites-available/atliteg:

server {
    listen 80;
    server_name atliteg.example.com;

    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name atliteg.example.com;

    # SSL Certificates (Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/atliteg.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/atliteg.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Security Headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;

    # Proxy to Docker container
    location / {
        proxy_pass http://localhost:9000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    # Gzip Compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript 
               application/x-javascript application/xml+rss 
               application/json application/javascript;

    # Logs
    access_log /var/log/nginx/atliteg-access.log;
    error_log /var/log/nginx/atliteg-error.log;
}

Abilita configurazione:

# Crea symbolic link
sudo ln -s /etc/nginx/sites-available/atliteg /etc/nginx/sites-enabled/

# Test configurazione
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

# Ottieni certificato SSL (Let's Encrypt)
sudo certbot --nginx -d atliteg.example.com

Dockerfile Multi-Stage Build

Analisi Dockerfile

# Stage 1: Builder
FROM node:20-alpine AS builder

WORKDIR /app

# Copia package files
COPY package*.json ./

# Installa dipendenze
RUN npm ci --legacy-peer-deps

# Copia sorgenti
COPY . .

# Build produzione
RUN npm run build

# Stage 2: Production
FROM nginx:alpine

# Copia configurazione Nginx
COPY nginx.conf /etc/nginx/nginx.conf

# Copia build artifacts da builder
COPY --from=builder /app/dist /usr/share/nginx/html

# Esponi porta 9000
EXPOSE 9000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --quiet --tries=1 --spider http://localhost:9000/ || exit 1

# Start Nginx
CMD ["nginx", "-g", "daemon off;"]

Ottimizzazioni

Layer Caching:

  • package*.json copiati prima dei sorgenti
  • Rebuild solo se dipendenze cambiano

Multi-Stage:

  • Builder stage: 1.2GB (Node.js + deps)
  • Production stage: 45MB (Nginx + static files)
  • Riduzione 96% dimensione immagine finale

Alpine Linux:

  • Immagine base minimale
  • Riduzione superficie di attacco
  • Aggiornamenti sicurezza rapidi

Configurazione Nginx

File nginx.conf

worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # Logging
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;

    # Performance
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Gzip Compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml text/javascript 
               application/x-javascript application/xml+rss 
               application/json application/javascript image/svg+xml;
    gzip_disable "msie6";

    server {
        listen 9000;
        server_name localhost;
        root /usr/share/nginx/html;
        index index.html;

        # Security Headers
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;

        # Cache static assets
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }

        # SPA Fallback
        location / {
            try_files $uri $uri/ /index.html;
        }

        # Health check endpoint
        location /health {
            access_log off;
            return 200 "healthy\n";
            add_header Content-Type text/plain;
        }

        # Data files (CSV/GeoJSON)
        location /data/ {
            expires 1d;
            add_header Cache-Control "public, must-revalidate";
        }
    }
}

Ottimizzazioni Nginx

  1. Gzip Compression: Riduce payload 70-80%
  2. Cache Headers: Browser cache per static assets (1 anno)
  3. Sendfile: Zero-copy file serving (performance)
  4. Keepalive: Riusa connessioni TCP
  5. Security Headers: Protezione XSS, clickjacking

Aggiornamenti e Manutenzione

Aggiornamento Applicazione

# 1. SSH nel server
ssh user@your-server.com
cd atliteg-map/Lemmario_figma

# 2. Pull ultimi cambiamenti
git pull origin production

# 3. Rebuild immagine
docker-compose build --no-cache

# 4. Restart container (zero-downtime con health check)
docker-compose up -d

# 5. Verifica logs
docker-compose logs -f --tail=100

# 6. Cleanup immagini vecchie
docker image prune -f

Aggiornamento Dati (CSV/GeoJSON)

# Opzione 1: Update file su host
cd /home/ale/docker/atliteg-map/data
# Sostituisci file CSV/GeoJSON
cp nuovo_file.csv Lemmi_forme_atliteg_updated.csv

# Il volume Docker monta la directory, nessun restart necessario
# L'applicazione ricarica i dati al prossimo refresh browser

# Opzione 2: Update da repository
git pull origin production
# Se i dati sono nel repo, vengono aggiornati automaticamente

Rollback

# Rollback a commit precedente
git log --oneline  # Trova commit hash
git checkout <commit-hash>

# Rebuild e redeploy
docker-compose build --no-cache
docker-compose up -d

# Verifica rollback
docker-compose logs -f

Backup

# Backup container image
docker save atliteg-lemmario:latest | gzip > atliteg-backup-$(date +%Y%m%d).tar.gz

# Backup dati
tar -czf data-backup-$(date +%Y%m%d).tar.gz ../data/

# Backup configurazioni
tar -czf config-backup-$(date +%Y%m%d).tar.gz \
  docker-compose.yml Dockerfile nginx.conf .env.production

Restore

# Restore image
docker load < atliteg-backup-20240115.tar.gz

# Restore dati
tar -xzf data-backup-20240115.tar.gz -C /path/to/restore/

# Restart container
docker-compose up -d

Monitoring e Logging

Monitoring Docker

# Real-time stats
docker stats lemmario-dashboard

# Output:
# CONTAINER ID   CPU %   MEM USAGE / LIMIT   MEM %   NET I/O
# abc123         0.5%    85MiB / 2GiB        4.2%    1.2MB / 850kB

# Inspect container
docker inspect lemmario-dashboard

# Health status
docker ps --filter name=lemmario-dashboard --format "{{.Status}}"

Logging

# View logs
docker-compose logs -f

# Logs ultimi 100 righe
docker-compose logs --tail=100

# Logs con timestamp
docker-compose logs -t

# Logs specifici servizio
docker-compose logs lemmario-dashboard

# Export logs
docker-compose logs > logs-$(date +%Y%m%d).log

Nginx Access Logs

# Exec nel container
docker exec -it lemmario-dashboard sh

# View access log
tail -f /var/log/nginx/access.log

# View error log
tail -f /var/log/nginx/error.log

# Exit
exit

Performance Tuning

Ottimizzazione Docker

Aumenta risorse container (docker-compose.yml):

services:
  lemmario-dashboard:
    # ... altre configurazioni ...
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

Ottimizzazione Nginx

Aumenta worker connections (nginx.conf):

events {
    worker_connections 2048;  # Default: 1024
    use epoll;  # Linux event model
}

Abilita caching Nginx:

http {
    proxy_cache_path /tmp/nginx-cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;

    server {
        location / {
            proxy_cache my_cache;
            proxy_cache_valid 200 1h;
            add_header X-Cache-Status $upstream_cache_status;
        }
    }
}

Sicurezza

Hardening Docker

# Run container come non-root user
# Modifica Dockerfile:
USER nginx

# Limita capabilities
docker-compose.yml:
  cap_drop:
    - ALL
  cap_add:
    - NET_BIND_SERVICE

# Read-only filesystem
  read_only: true
  tmpfs:
    - /tmp
    - /var/run

Hardening Nginx

# Nascondi versione Nginx
server_tokens off;

# Limita dimensione body
client_max_body_size 10M;

# Timeout
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;

# Rate limiting
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
limit_req zone=mylimit burst=20;

Troubleshooting

Container Non Si Avvia

# Verifica logs
docker-compose logs

# Verifica conflitti porta
sudo lsof -i :9000
# Uccidi processo se necessario
sudo kill -9 <PID>

# Rebuild pulito
docker-compose down -v
docker-compose build --no-cache
docker-compose up -d

Errori Build

# Pulisci cache Docker
docker builder prune -af

# Rebuild senza cache
docker-compose build --no-cache --pull

# Verifica spazio disco
df -h

Performance Lente

# Verifica risorse container
docker stats

# Aumenta memoria allocata (Docker Desktop)
# Settings > Resources > Memory: 4GB+

# Prune risorse inutilizzate
docker system prune -a

Checklist Deployment

Pre-Deployment

  • Codice committato su branch production
  • Tests passano (unit + E2E)
  • Build locale successo (npm run build)
  • Nessun errore ESLint/TypeScript
  • Dataset CSV/GeoJSON aggiornati
  • Variabili ambiente configurate (.env.production)
  • Documentazione aggiornata
  • Changelog aggiornato

Deployment

  • Docker e Docker Compose installati su server
  • Repository clonato/aggiornato
  • Build immagine Docker successo
  • Container avviato (docker-compose up -d)
  • Health check passa
  • Logs non mostrano errori
  • Accessibile su porta 9000
  • Nginx reverse proxy configurato (se applicabile)
  • SSL certificato installato (se applicabile)

Post-Deployment

  • Test funzionalità critiche
    • Caricamento dati CSV/GeoJSON
    • Filtri funzionano
    • Ricerca funziona
    • Mappa visualizza correttamente
    • Timeline navigabile
    • Dettaglio lemma si apre
  • Performance accettabili
    • LCP < 2.5s
    • FID < 100ms
    • Bundle size < 500KB
  • Accessibilità verificata (axe DevTools)
  • Monitoring attivo
  • Backup eseguito
  • Team notificato

Riferimenti