Kurs Python · Moduł 5: Flask i aplikacje webowe
Deployment - publikacja w internecie
W tej lekcji15
Gratulacje! Darwin tutaj z ostatnią lekcją Module 5 - deployment aplikacji Flask!
Zbudowałeś/aś funkcjonującą aplikację Safari Database z formularzami, autentykacją i templates. Teraz czas opublikować ją w internecie, żeby świat mógł z niej korzystać!
Analogia Safari: Deployment to jak otwarcie parku dla publiczności - dotychczas park działał tylko wewnętrznie (localhost), teraz otwierasz bramy dla turystów z całego świata (internet)!
Development vs Production
Development (localhost)
app.run(debug=True) - serwer deweloperski
Auto-reload po zmianie kodu
Szczegółowe błędy w przeglądarce
Localhost tylko - nie dostępny z internetu
Wolny - nie zoptymalizowany
Production (internet)
WSGI server (Gunicorn, uWSGI)
Bez debug=True - bezpieczeństwo!
Zmienne środowiskowe - SECRET_KEY, DATABASE_URL
Dostępny publicznie - każdy może wejść
Szybki - zoptymalizowany
NIGDY nie używaj app.run(debug=True) w produkcji!
WSGI Server - Gunicorn
Gunicorn (Green Unicorn) to popularny WSGI server dla aplikacji Flask/Django.
WSGI = Web Server Gateway Interface - standard komunikacji między serwerem a aplikacją Python.
Instalacja
1pip install gunicornUruchomienie
1# Basic
2gunicorn app:app
3
4# Z określeniem portu i workerów
5gunicorn app:app --bind 0.0.0.0:8000 --workers 4
6
7# Z reload (dev tylko)
8gunicorn app:app --reloadFormat: gunicorn <module>:<app_variable>
app- nazwa pliku (app.py)app- nazwa zmiennej Flask (app = Flask(name))
Przygotowanie do deployment
1. Plik requirements.txt
Zapisz wszystkie zależności:
1pip freeze > requirements.txtrequirements.txt:
1Flask==3.0.0
2Flask-WTF==1.2.1
3Flask-Login==0.6.3
4Werkzeug==3.0.1
5gunicorn==21.2.02. Zmienne środowiskowe
NIGDY nie commituj SECRET_KEY i wrażliwych danych do git!
Użyj zmiennych środowiskowych:
1# app.py
2import os
3
4app = Flask(__name__)
5
6# Pobierz z environment variables
7app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY') or 'dev-fallback-key'
8app.config['DATABASE_URL'] = os.environ.get('DATABASE_URL') or 'sqlite:///dev.db'
9
10# Debug tylko w dev
11app.config['DEBUG'] = os.environ.get('FLASK_ENV') == 'development'3. .gitignore
1# .gitignore
2venv/
3__pycache__/
4*.pyc
5*.pyo
6.env
7instance/
8.DS_Store4. Procfile (dla platform jak Render/Heroku)
1web: gunicorn app:appProcfile mówi platformie, jak uruchomić Twoją aplikację.
5. runtime.txt (opcjonalnie)
1python-3.11.0Określa wersję Pythona.
Deployment na Render (FREE!)
Render to nowoczesna platforma hostingowa z darmowym planem. Świetna alternatywa dla Heroku!
Krok 1: Przygotuj aplikację
Struktura projektu:
1safari_web/
2├── app.py
3├── models.py
4├── forms.py
5├── requirements.txt
6├── Procfile
7├── .gitignore
8├── templates/
9│ └── ...
10└── static/
11 └── ...app.py - ostatnie linie:
1if __name__ == '__main__':
2 # Tylko dla local development
3 app.run(debug=True)Render uruchomi przez Procfile, więc if __name__ nie wykona się!
Krok 2: Push do GitHub
1git init
2git add .
3git commit -m "Initial commit - Safari Database"
4git branch -M main
5git remote add origin https://github.com/twoj-username/safari-web.git
6git push -u origin mainKrok 3: Utwórz Web Service na Render
Wejdź na https://render.com i zarejestruj się (FREE)
Kliknij "New +" → "Web Service"
Połącz GitHub repository
Wybierz repozytorium
safari-webKonfiguracja:
- Name: safari-database
- Environment: Python 3
- Build Command:
pip install -r requirements.txt - Start Command:
gunicorn app:app - Plan: Free
Environment Variables - dodaj:
SECRET_KEY=your-random-secret-key-hereFLASK_ENV=production
Kliknij "Create Web Service"
Krok 4: Deploy!
Render automatycznie:
- Instaluje zależności (
pip install -r requirements.txt) - Uruchamia Gunicorn (
gunicorn app:app) - Przydziela domenę (
https://safari-database.onrender.com)
Gratulacje! Twoja aplikacja jest LIVE!
Deployment na Railway (również FREE!)
Railway to kolejna świetna platforma z prostym setupem.
Kroki:
- https://railway.app - zarejestruj się
- "New Project" → "Deploy from GitHub repo"
- Wybierz repozytorium
- Railway automatycznie wykryje Flask!
- Dodaj Environment Variables:
SECRET_KEYFLASK_ENV=production
- Railway automatycznie deploy!
Domain: https://safari-database.up.railway.app
Deployment checklist
Przed deployment upewnij się:
Bezpieczeństwo
DEBUG = Falsew produkcji- SECRET_KEY jako zmienna środowiskowa
- Hasła hashowane (werkzeug.security)
- CSRF protection włączone (Flask-WTF)
- .gitignore zawiera
venv/,.env
Pliki
- requirements.txt aktualny
- Procfile utworzony
- .gitignore utworzony
- Static files poprawnie skonfigurowane
Baza danych
- W dev: SQLite
- W prod: PostgreSQL (Render/Railway FREE tier!)
- DATABASE_URL jako zmienna środowiskowa
Testy
- Aplikacja działa lokalnie
- Wszystkie routes działają
- Formularze działają
- Logowanie/rejestracja działa
Baza danych w produkcji
SQLite (Development)
1app.config['DATABASE_URL'] = 'sqlite:///safari.db'Problemy: SQLite nie jest rekomendowane dla produkcji (problemy z współbieżnością).
PostgreSQL (Production)
Render/Railway oferują FREE PostgreSQL!
Render: Add PostgreSQL Database → skopiuj DATABASE_URL
1import os
2
3database_url = os.environ.get('DATABASE_URL')
4
5if database_url and database_url.startswith('postgres://'):
6 # Render używa postgres://, ale SQLAlchemy potrzebuje postgresql://
7 database_url = database_url.replace('postgres://', 'postgresql://', 1)
8
9app.config['SQLALCHEMY_DATABASE_URI'] = database_url or 'sqlite:///dev.db'Static files w produkcji
Flask automatycznie serwuje pliki z static/, ale w produkcji lepiej użyć CDN lub Nginx.
Podstawowa konfiguracja Flask:
1# app.py
2app = Flask(__name__)
3
4# Flask automatycznie serwuje static files z /static/
5# http://yourapp.com/static/css/style.cssW templates:
1<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
2<script src="{{ url_for('static', filename='js/script.js') }}"></script>Monitorowanie i logi
Render Logs
Dashboard → Twój Web Service → Logs
Railway Logs
Project → Twój Service → Logs
Przykładowe logi:
1[2024-01-15 10:23:45] INFO: Starting gunicorn 21.2.0
2[2024-01-15 10:23:45] INFO: Listening at: http://0.0.0.0:10000
3[2024-01-15 10:23:45] INFO: Using worker: sync
4[2024-01-15 10:23:45] INFO: Booting worker with pid: 42Aktualizacja aplikacji
Render/Railway
- Zmiany w kodzie lokalnie
- Commit do git:
1git add . 2git commit -m "Update: Add new feature" 3git push origin main - Render/Railway automatycznie deploy nową wersję!
Auto-deploy = push to GitHub → automatyczny deploy!
Własna domena (opcjonalnie)
Zamiast safari-database.onrender.com możesz użyć własnej domeny:
- Kup domenę (np.
safaridatabase.com) - Render/Railway → Settings → Custom Domain
- Dodaj CNAME record u rejestratora domeny
- Gotowe!
https://safaridatabase.com→ Twoja aplikacja
Alternatywne platformy
1. Fly.io
- FREE tier
- Globalny deployment
- Świetna dokumentacja
2. PythonAnywhere
- FREE tier dla Flask
- Prosty setup
- Dobre dla początkujących
3. DigitalOcean App Platform
- $5/miesiąc
- Więcej kontroli
- Skalowalne
4. AWS/Google Cloud/Azure
- Zaawansowane
- Droższe
- Pełna kontrola
Przykład production-ready app.py
1# app.py
2import os
3from flask import Flask, render_template, redirect, url_for, flash
4from flask_login import LoginManager, login_user, logout_user, login_required, current_user
5from flask_sqlalchemy import SQLAlchemy
6
7app = Flask(__name__)
8
9# Configuration from environment variables
10app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY') or 'dev-key-change-in-production'
11app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL') or 'sqlite:///dev.db'
12app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
13
14# Fix for Render PostgreSQL URL
15if app.config['SQLALCHEMY_DATABASE_URI'].startswith('postgres://'):
16 app.config['SQLALCHEMY_DATABASE_URI'] = app.config['SQLALCHEMY_DATABASE_URI'].replace('postgres://', 'postgresql://', 1)
17
18db = SQLAlchemy(app)
19login_manager = LoginManager(app)
20login_manager.login_view = 'login'
21
22# Models, routes, etc...
23
24if __name__ == '__main__':
25 # Only for local development
26 port = int(os.environ.get('PORT', 5000))
27 app.run(host='0.0.0.0', port=port, debug=os.environ.get('FLASK_ENV') == 'development')Podsumowanie
W tej lekcji nauczyłeś/aś się:
- Różnica między development a production
- WSGI servers (Gunicorn)
- Przygotowanie aplikacji do deployment
- Zmienne środowiskowe (SECRET_KEY, DATABASE_URL)
- Deployment na Render (FREE!)
- Deployment na Railway (FREE!)
- Deployment checklist
- Bazy danych w produkcji (PostgreSQL)
- Static files w produkcji
- Monitorowanie i logi
- Aktualizacja aplikacji (auto-deploy)
Analogia Safari finalna: Deployment to jak grand opening parku safari - przygotowałeś infrastrukturę (kod), zatrudniłeś pracowników (WSGI server), zabezpieczyłeś park (SECRET_KEY, HTTPS), i otworzyłeś bramy dla turystów z całego świata (internet)! Twoja aplikacja Flask żyje i działa 24/7 w chmurze!
Gratulacje Module 5!
Zbudowałeś/aś kompletną aplikację webową z:
- Frontend (HTML, CSS, JavaScript)
- Backend (Flask)
- Routing i view functions
- Jinja2 templates
- Formularze z walidacją (Flask-WTF)
- Autentykacja (Flask-Login)
- Deployment w internecie (Render/Railway)
Safari Database jest teraz LIVE i dostępna dla każdego w internecie!
Darwin jest z Ciebie dumny! Przygotuj się na kolejne moduły, gdzie poznasz zaawansowane techniki Python i AI!
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Czym jest deployment aplikacji webowej?
2. Czym jest Gunicorn?
To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Układanie w pionie
Ułóż typowe kroki deploymentu aplikacji Flask:
- Klikanie w kolejności
Ułóż komendę generującą requirements.txt:
- Edytor kodu
Napisz klasę Config z SECRET_KEY pobieranym ze zmiennej środowiskowej.
- Układanie w poziomie
Ułóż elementy dekoratora route:
- Układanie w pionie
Uporządkuj kroki tworzenia aplikacji Flask:
- Edytor kodu
Napisz route '/api/species' zwracający listę gatunków jako JSON.
- Edytor kodu
Utwórz route '/' w Flask zwracający 'Witaj na Safari!'.
- Edytor kodu
Wyrenderuj szablon 'index.html' przekazując zmienną title.
- Układanie w pionie
Uporządkuj etapy obsługi żądania HTTP:
- Edytor kodu
Zdefiniuj klasę LoginForm z polami username i password.
- Edytor kodu
Zbuduj aplikację Safari Species Portal z: listą gatunków, dodawaniem nowych, logowaniem użytkowników i podstawowym stylem CSS.