Kurs Python · Moduł 6: Async i FastAPI

Production Deployment - Docker & Cloud

4 min czytania
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.txt

FROM 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      - db

build: . 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 -d

W 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:

  1. Push to GitHub
  2. Connect repo na Render
  3. Dodaj environment variables
  4. Auto-deploy!

Railway:

  1. railway init
  2. railway up
  3. 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. 1. Dlaczego Docker jest ważny dla aplikacji FastAPI?

  2. 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ś!

Przydatne artykuły