Kurs Python · Moduł 6: Async i FastAPI
Production Deployment - Docker & Cloud
W tej lekcji5
Witaj! Darwin z ostatnią lekcją Module 6 - deployment FastAPI w produkcji!
Na Twoim laptopie Safari API działa idealnie. Kolega uruchamia je u siebie i dostaje błąd, bo ma inną wersję Pythona, a serwer w chmurze nie ma jeszcze PostgreSQL. Znane "u mnie działa" to najczęstszy problem przy pierwszym wdrożeniu, a Docker rozwiązuje go, pakując aplikację razem z całym środowiskiem.
Analogia Safari: Deployment to jak otwarcie parku safari dla publiczności - musimy zapewnić bezpieczeństwo, skalowalność, i niezawodność 24/7! Kontener to z kolei spakowany plecak wyprawowy: w każdym obozie rozpakowujesz dokładnie ten sam sprzęt.
Dockerfile dla FastAPI
Obraz Dockera to gotowa paczka z systemem, Pythonem, zależnościami i kodem, a kontener to uruchomiona kopia obrazu. Przepis na obraz zapisujemy w pliku Dockerfile. Pierwsza część wybiera bazę i instaluje zależności:
1# Dockerfile
2FROM python:3.11-slim
3
4WORKDIR /app
5
6COPY requirements.txt .
7RUN pip install --no-cache-dir -r requirements.txtFROM wskazuje obraz bazowy - wariant slim jest znacznie mniejszy od pełnego. WORKDIR ustawia katalog roboczy. Zauważ, że najpierw kopiujemy tylko requirements.txt: Docker zapamiętuje każdy krok jako warstwę, więc dopóki lista zależności się nie zmienia, instalacja pakietów przy kolejnych budowaniach pochodzi z cache. --no-cache-dir sprawia, że pip nie zostawia w obrazie pobranych archiwów.
Druga część kopiuje kod i mówi, jak uruchomić aplikację:
1COPY . .
2
3CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]COPY . . przenosi resztę projektu - dodaj plik .dockerignore, żeby nie trafiły tam .venv, .git ani sekrety. --host 0.0.0.0 jest konieczne: domyślny 127.0.0.1 przyjmowałby połączenia tylko z wnętrza kontenera. Zapis CMD jako listy JSON (exec form) sprawia, że uvicorn dostaje sygnał zatrzymania bezpośrednio i może zamknąć się łagodnie.
Obraz budujesz i uruchamiasz dwoma poleceniami:
1docker build -t safari-api .
2docker run -p 8000:8000 safari-api-t nadaje obrazowi nazwę, a kropka oznacza bieżący katalog z Dockerfile. -p 8000:8000 łączy port komputera z portem kontenera, więc API odpowie pod http://localhost:8000.
docker-compose.yml
Aplikacja potrzebuje jeszcze bazy danych. Docker Compose opisuje w jednym pliku kilka usług, które startują razem. Najpierw usługa API:
1version: '3.8'
2
3services:
4 api:
5 build: .
6 ports:
7 - "8000:8000"
8 environment:
9 - DATABASE_URL=postgresql+asyncpg://user:password@db/safari
10 depends_on:
11 - dbbuild: . buduje obraz z naszego Dockerfile. Adres bazy przekazujemy zmienną środowiskową, a nazwa hosta db to po prostu nazwa drugiej usługi - Compose tworzy sieć, w której usługi widzą się po nazwach. Linia version jest dziś przestarzała: aktualna specyfikacja Compose ją ignoruje i wypisuje ostrzeżenie, więc w nowych plikach możesz ją pominąć.
Teraz baza i wolumen:
1 db:
2 image: postgres:15
3 environment:
4 - POSTGRES_USER=user
5 - POSTGRES_PASSWORD=password
6 - POSTGRES_DB=safari
7 volumes:
8 - postgres_data:/var/lib/postgresql/data
9
10volumes:
11 postgres_data:Wolumen postgres_data przechowuje pliki bazy poza kontenerem, więc dane przetrwają jego usunięcie. depends_on ustala tylko kolejność startu, a nie czeka, aż PostgreSQL będzie gotowy na połączenia - aplikacja powinna umieć ponowić próbę albo możesz dodać healthcheck.
Uruchom:
Całość startuje jednym poleceniem, a -d uruchamia ją w tle:
1docker-compose up -dW nowszych instalacjach Dockera Compose jest wtyczką i piszesz docker compose up -d, ze spacją zamiast myślnika. Polecam tę formę, bo starszy samodzielny program docker-compose nie jest już rozwijany.
Production checklist
- Environment variables (DATABASE_URL, SECRET_KEY)
- HTTPS/TLS certificates
- CORS configuration
- Rate limiting
- Logging & monitoring
- Database migrations (Alembic)
- Backup strategy
- Load balancer
Każdy punkt chroni przed innym kłopotem: sekrety w zmiennych środowiskowych nie wyciekną z repozytorium, a Alembic zmienia strukturę bazy bez ręcznego pisania SQL. Hasła z pliku Compose powyżej nadają się tylko do nauki.
Deploy na Render/Railway
Platformy PaaS budują i uruchamiają kontener za Ciebie. Wystarczy połączyć repozytorium:
Render:
- Push to GitHub
- Connect repo na Render
- Dodaj environment variables
- Auto-deploy!
Railway:
- railway init
- railway up
- Gotowe!
railway init i railway up to polecenia wiersza poleceń Railway: pierwsze tworzy projekt, drugie wysyła kod i wdraża go. Szczegóły, na przykład wymagane ustawienia portu, sprawdź w dokumentacji wybranej platformy.
Podsumowanie Module 6
Gratulacje! Ukończyłeś/aś Module 6: FastAPI!
Nauczyłeś/aś się:
- Async/await fundamentals
- FastAPI basics i endpointy
- Pydantic validation
- Async databases (SQLAlchemy)
- JWT authentication
- Testing z pytest
- Production deployment (Docker)
Safari Database API ma teraz wszystko, czego potrzeba do pierwszego wdrożenia: walidację, bazę, uwierzytelnianie, testy i kontener. Ile żądań na sekundę obsłuży, zależy od serwera i bazy, więc przed dużym ruchem zawsze to zmierz.
Darwin jest dumny! Module 7 pogłębi DevOps: testy, jakość kodu, Docker, CI/CD, chmurę i monitoring.
Pamiętaj: kontener to spakowany plecak wyprawy - co zadziałało w obozie treningowym, zadziała na każdej sawannie.
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Dlaczego Docker jest ważny dla aplikacji FastAPI?
2. Co powinien zawierać Dockerfile dla aplikacji FastAPI?
To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Układanie w pionie
Ułóż Dockerfile dla aplikacji FastAPI:
- Układanie w poziomie
Jak zbudować obraz Docker z tagiem 'safari-api'?
- Klikanie w kolejności
Ułóż komendę uruchamiającą kontener na porcie 8000:
- Edytor kodu
Stwórz Dockerfile: obraz python:3.11-slim, WORKDIR /app, skopiuj i zainstaluj requirements.txt, skopiuj kod, uruchom uvicorn main:app na 0.0.0.0:8000.
- Układanie w poziomie
Ułóż elementy definicji funkcji asynchronicznej:
- Układanie w poziomie
Ułóż elementy dekoratora FastAPI:
- Układanie w poziomie
Ułóż wywołanie asyncio.gather:
- Edytor kodu
Utwórz endpoint GET '/species/{species_id}' z parametrem ścieżki.
- Edytor kodu
Utwórz endpoint GET '/species' zwracający listę gatunków.
- Edytor kodu
Stwórz model Species z polami name (str) i habitat (str).
- Układanie w pionie
Uporządkuj kroki tworzenia aplikacji FastAPI:
- Edytor kodu
Napisz async def fetch_data() używającą await do pobrania danych.
- Edytor kodu
Zbuduj Safari Async API: CRUD gatunków z async bazą, JWT autentykację, testy i Dockerfile. Użyj wszystkiego czego się nauczyłeś!