Flask Modulo 8 – Deployment e Produzione


🚀 Modulo 8: Deployment e Produzione

Metti online la tua applicazione Flask e condividila con il mondo!

📚

MODULO
8 di 8

⏱️

TEMPO
60 minuti

🎯

LIVELLO
Master

🎯 Benvenuto nell’Ultimo Modulo!

Congratulazioni! Hai imparato tutto ciò che serve per costruire applicazioni Flask professionali. Ora è il momento di condividere il tuo lavoro con il mondo.

🌐

Accessibile Ovunque
La tua app sarà online 24/7

👥

Multi-utente
Chiunque può usare la tua app

📱

Mobile Ready
Accessibile da qualsiasi dispositivo

💼

Portfolio
Mostra il tuo lavoro a potenziali clienti/datori

💡 Cosa Significa “Deployment”?

Il deployment è il processo di pubblicazione della tua applicazione su un server accessibile da Internet. Pensa a quando pubblichi una foto su Instagram: dalla tua galleria (locale) ai server di Instagram (produzione).

🔧 Preparazione per la Produzione

Prima di pubblicare, dobbiamo preparare l’applicazione per l’ambiente di produzione.

1
Crea requirements.txt

Lista di tutte le dipendenze del progetto:

Terminale
# Genera automaticamente requirements.txt
pip freeze > requirements.txt

📄 requirements.txt (esempio)
Flask==2.3.2
Flask-SQLAlchemy==3.0.5
Flask-Login==0.6.2
Flask-WTF==1.1.1
Flask-Bcrypt==1.0.1
SQLAlchemy==2.0.19
Werkzeug==2.3.6
python-dotenv==1.0.0
gunicorn==20.1.0
psycopg2-binary==2.9.7

2
Crea .env per Variabili d’Ambiente

📄 .env (NON commitare su Git!)
# Ambiente
FLASK_ENV=production
FLASK_DEBUG=False

# Database
DATABASE_URL=postgresql://user:password@localhost/dbname
# O per SQLite
# DATABASE_URL=sqlite:///app.db

# Segreti
SECRET_KEY=la_tua_chiave_segreta_molto_lunga_e_complessa
JWT_SECRET_KEY=altra_chiave_segreta_per_jwt

# Email (se usi email)
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=True
MAIL_USERNAME=tuamail@gmail.com
MAIL_PASSWORD=tua_password_app_specifica

3
Configura Flask per Usare .env

📄 app.py – Configurazione
import os
from flask import Flask
from dotenv import load_dotenv

# Carica variabili d'ambiente da .env
load_dotenv()

app = Flask(__name__)

# Configurazione da variabili d'ambiente
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'fallback-secret-key')
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# Debug mode solo in sviluppo
app.config['DEBUG'] = os.getenv('FLASK_DEBUG', 'False').lower() == 'true'

# Configurazione produzione
if not app.debug:
    app.config.update(
        SESSION_COOKIE_SECURE=True,
        SESSION_COOKIE_HTTPONLY=True,
        SESSION_COOKIE_SAMESITE='Lax',
        PERMANENT_SESSION_LIFETIME=3600
    )

⚙️ WSGI: Il Server per la Produzione

❌ Server di Sviluppo Flask

app.run(debug=True)

  • Solo per sviluppo
  • Single-threaded
  • Nessun load balancing
  • Debug mode attivo (pericoloso in produzione!)
  • Crasha con errori
  • Performance limitate

✅ WSGI Server (Gunicorn)

gunicorn app:app

  • Per produzione
  • Multi-worker/process
  • Load balancing automatico
  • Gestione errori robusta
  • Performance ottimizzate
  • Riavvi automatici

1
Installa Gunicorn

Terminale
pip install gunicorn

2
Crea wsgi.py

📄 wsgi.py
from app import app

if __name__ == "__main__":
    app.run()

3
Avvia con Gunicorn

Terminale – Test Locale
# Semplice
gunicorn app:app

# Con 4 worker (processi)
gunicorn --workers 4 app:app

# Su porta specifica
gunicorn --bind 0.0.0.0:8000 app:app

# Con logging
gunicorn --access-logfile - --error-logfile - app:app

# Per applicazioni più complesse
gunicorn --workers 4 --bind unix:app.sock -m 007 wsgi:app

☁️ Opzioni di Hosting per Flask

🆓

PythonAnywhere

Perfetto per iniziare

  • Piano gratuito disponibile
  • Setup in 5 minuti
  • Console Python nel browser
  • Database MySQL incluso
  • SSL gratuito
  • Limite: 512MB RAM
  • Supporto base
Gratis – $5/mese

🚀

Railway / Render

Moderno e semplice

  • Deploy da Git con un click
  • Auto-deploy su push
  • Database automatico
  • SSL automatico
  • Piano gratuito generoso
  • CI/CD integrato
  • Monitoraggio base
Gratis – $20/mese

🏢

AWS / Google Cloud

Professionale & Scalabile

  • Altamente scalabile
  • Completamente personalizzabile
  • Database managed
  • CDN integrato
  • Backup automatici
  • Monitoraggio avanzato
  • Supporto 24/7
$10 – $100+/mese

🚀 Deployment su Railway (Facile & Gratis)

1

Prepara App

2

Crea Procfile

3

Push su GitHub

4

Connetti Railway

5

Configura Variabili

1
Crea Procfile

Railway usa questo file per sapere come avviare la tua app.

📄 Procfile (senza estensione)
web: gunicorn app:app

Alternative:

# Se il file principale si chiama wsgi.py
web: gunicorn wsgi:app

# Con worker multipli
web: gunicorn --workers 4 app:app

# Se usi un'app factory
web: gunicorn "app:create_app()"

2
Configura runtime.txt (opzionale)

📄 runtime.txt
python-3.11.0

3
Struttura Finale del Progetto

flask-app/
├── app.py              ← File principale
├── wsgi.py            ← Entry point WSGI
├── requirements.txt    ← Dipendenze
├── Procfile           ← Comando di avvio
├── runtime.txt        ← Versione Python (opzionale)
├── .env              ← Variabili locali (NON commitare!)
├── .gitignore        ← Esclude .env, __pycache__, etc.
├── static/
├── templates/
├── models.py
├── forms.py
└── README.md

4
Deploy su Railway – Passo Passo

  1. Crea account su railway.app
  2. Click “New Project” → “Deploy from GitHub repo”
  3. Connetti il tuo account GitHub
  4. Scegli il repository con la tua app Flask
  5. Railway deployerà automaticamente
  6. Vai su Settings → Variables e aggiungi:
    SECRET_KEY=tua_chiave_segreta_lunga
    DATABASE_URL=postgresql://...  # Railway crea DB automaticamente
    FLASK_ENV=production

  7. La tua app è online! 🎉

🎨 Deployment su Render (Alternative)

1
Crea render.yaml

📄 render.yaml
services:
  - type: web
    name: flask-app
    env: python
    buildCommand: pip install -r requirements.txt
    startCommand: gunicorn app:app
    envVars:
      - key: SECRET_KEY
        generateValue: true
      - key: DATABASE_URL
        fromDatabase:
          name: flask-db
          property: connectionString
      - key: FLASK_ENV
        value: production

databases:
  - name: flask-db
    databaseName: flaskdb
    user: flaskuser

2
Deploy su Render

  1. Vai su render.com
  2. Crea account (con GitHub)
  3. Click “New +” → “Web Service”
  4. Connetti repository GitHub
  5. Render rileverà automaticamente render.yaml
  6. Click “Create Web Service”
  7. Il deploy inizia automaticamente

🗄️ Database in Produzione

⚠️ IMPORTANTE: SQLite NON per Produzione!

SQLite è perfetto per sviluppo, ma in produzione usa un database vero:

  • PostgreSQL: Raccomandato – robusto, funzionalità complete
  • MySQL: Buona alternativa – ampiamente supportato
  • SQLite: ❌ Solo sviluppo/testing
1
Configurazione Database PostgreSQL

📄 app.py – Configurazione DB
import os
from flask_sqlalchemy import SQLAlchemy
from urllib.parse import urlparse

app = Flask(__name__)

# Prendi URL database da variabile d'ambiente
database_url = os.getenv('DATABASE_URL')

# Railway/Render forniscono DATABASE_URL già formattata
if database_url:
    # Gestisci caso di Railway che usa postgres:// invece di postgresql://
    if database_url.startswith('postgres://'):
        database_url = database_url.replace('postgres://', 'postgresql://', 1)
    
    app.config['SQLALCHEMY_DATABASE_URI'] = database_url
else:
    # Fallback a SQLite per sviluppo
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

2
Migrazioni Database in Produzione

Terminale – Comandi Migrazione
# In produzione, prima del deploy
flask db upgrade

# O in Railway/Render, aggiungi build command
# buildCommand: "pip install -r requirements.txt && flask db upgrade"

# Se qualcosa va storto
flask db downgrade  # Torna indietro di una migrazione
flask db current    # Vedi migrazione corrente

🔗 Dominio Personalizzato e SSL

1
Configura Dominio Personalizzato

Railway/Render forniscono URL tipo tuoapp.railway.app, ma puoi usare il tuo dominio.

Railway – Settings → Domains
1. Vai su Settings del tuo progetto
2. Click "Domains"
3. Aggiungi il tuo dominio (es: app.tuonome.com)
4. Railway mostrerà record DNS da aggiungere
5. Vai dal tuo registrar di dominio (es: GoDaddy, Namecheap)
6. Aggiungi i record CNAME/A forniti
7. Attendi propagazione DNS (fino a 48h)

2
SSL Gratuito Automatico

Railway/Render forniscono SSL automatico con Let’s Encrypt.

🔐 Perché SSL è Obbligatorio?

  • Sicurezza: Crittografa dati tra browser e server
  • SEO: Google penalizza siti senza HTTPS
  • Credibilità: Mostra il lucchetto verde nel browser
  • Modernità: Browser segnalano siti HTTP come “non sicuri”

📊 Monitoring e Logs in Produzione

1
Configura Logging in Flask

📄 app.py – Configurazione Logging
import logging
from logging.handlers import RotatingFileHandler
import os

def setup_logging(app):
    if not app.debug:
        # Crea directory logs se non esiste
        if not os.path.exists('logs'):
            os.mkdir('logs')
        
        # File handler con rotazione
        file_handler = RotatingFileHandler(
            'logs/flask_app.log',
            maxBytes=10240,
            backupCount=10
        )
        file_handler.setFormatter(logging.Formatter(
            '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
        ))
        file_handler.setLevel(logging.INFO)
        
        app.logger.addHandler(file_handler)
        app.logger.setLevel(logging.INFO)
        app.logger.info('Flask app startup')

# Nel create_app()
setup_logging(app)

2
Strumenti di Monitoring

Strumento Scopo Costo
UptimeRobot Monitora se il sito è online Gratis
Google Analytics Traffico e utenti Gratis
Railway/Render Dashboard Logs, performance, errori Incluso
Sentry Error tracking in tempo reale Piano gratuito
New Relic Performance monitoring Piano gratuito

✅ Checklist Pre-Deployment

🔍 Controlla Ogni Punto Prima di Deployare!

📦 Configurazione

  • requirements.txt aggiornato
  • Procfile presente
  • .env NON commitato (in .gitignore)
  • DEBUG = False in produzione
  • Database configurato (PostgreSQL)

🛡️ Sicurezza

  • SECRET_KEY complessa
  • Password hashate con bcrypt
  • CSRF protection attiva
  • HTTPS/SSL configurato
  • Input validation attiva

🚀 Performance

  • Gunicorn configurato
  • Static files serviti correttamente
  • Database indicizzato
  • Cache configurata (se necessaria)
  • CDN per static files (opzionale)

🔧 Manutenzione

  • Backup database configurato
  • Logging attivo
  • Error pages personalizzate
  • Monitoraggio configurato
  • README.md aggiornato

🔧 Troubleshooting Comuni

1
App Non Si Avvia

# Controlla logs su Railway/Render
Error: No module named 'flask'
→ requirements.txt mancante o incompleto

Error: Address already in use
→ Porta già occupata, cambia PORT in variabili

Error: ImportError
→ Controlla i percorsi degli import

Application error
→ Controlla logs per dettagli specifici

2
Database Connection Error

OperationalError: could not connect to server
→ DATABASE_URL non configurata o errata

ProgrammingError: relation does not exist
→ Migrazioni non applicate: flask db upgrade

InterfaceError: connection already closed
→ Timeout connessione, controlla pool size

psycopg2.OperationalError
→ Database non esiste o credenziali errate

3
Static Files Non Caricati

# In produzione, Flask non serve static files
# Configura web server o usa CDN

# Soluzione 1: Usa whitenoise
pip install whitenoise

# In app.py
from whitenoise import WhiteNoise
app.wsgi_app = WhiteNoise(app.wsgi_app, root='static/')

# Soluzione 2: Configura nginx/apache
# Soluzione 3: Usa CDN (Cloudflare, AWS CloudFront)

🏆 Progetto Finale: Blog Completo

Metti insieme tutto ciò che hai imparato e deploya un blog completo!

1
Requisiti del Blog

  • Frontend: Templates con Bootstrap 5
  • Autenticazione: Registrazione, Login, Logout
  • CRUD Articoli: Create, Read, Update, Delete
  • Commenti: Sistema commenti per articoli
  • Admin Panel: Gestione contenuti
  • Search: Ricerca articoli
  • API REST: Endpoint per app mobile

2
Struttura Database

# Modelli principali
User (id, username, email, password_hash, is_admin)
Post (id, title, content, created_at, user_id)
Comment (id, content, created_at, user_id, post_id)
Category (id, name)
Tag (id, name)

# Relazioni
User 1→N Post
User 1→N Comment
Post 1→N Comment
Post N→N Category
Post N→N Tag

3
Deploy del Blog

  1. Sviluppa localmente il blog
  2. Testa tutto localmente
  3. Crea repository GitHub
  4. Prepara requirements.txt, Procfile, .env
  5. Deploy su Railway o Render
  6. Configura dominio e SSL
  7. Testa in produzione
  8. Condividi il link con amici/colleghi!

🎓

Complimenti! 🎉

Hai completato con successo il corso completo di Flask! Ora possiedi tutte le competenze per costruire e pubblicare applicazioni web professionali.

📚 Riassunto del Percorso

🐍
Modulo 1
Fondamenti

🛣️
Modulo 2
Route & URL

🎨
Modulo 3
Templates

📁
Modulo 4
File Statici

📝
Modulo 5
Form & Input

🗄️
Modulo 6
Database

🔐
Modulo 7
Sicurezza

🚀
Modulo 8
Deployment

🎯 Prossimi Passi

💼 Portfolio

Crea 2-3 progetti completi e pubblicali online

🤝 Contribuisci

Partecipa a progetti open source su GitHub

📈 Avanzato

Impara Docker, CI/CD, Testing, APIs RESTful

“Il viaggio di mille miglia comincia con un singolo passo.”
Ora il tuo viaggio come sviluppatore Flask è iniziato! 🚀

Hai domande o bisogno di aiuto? Cerca su Stack Overflow o unisciti a comunità Flask su Discord/Reddit!

© 2024 Corso Completo Flask – Tutti i diritti riservati

Torna in alto