Cykl: Flask vs FastAPI: Porównanie frameworków webowych w Pythonie · Część 11/26

Wdrożenie aplikacji Django – Docker i CI/CD

Kacper Sieradziński
Kacper Sieradziński6 maja 2025 · 4 min czytania
Streszczenie
  • Dlaczego Docker?
  • Bez Dockera
  • Z Dockerem
  • Konfiguracja Docker dla Django
Wdrożenie aplikacji Django – Docker i CI/CD

Wdrożenie aplikacji Django do środowiska produkcyjnego to coś więcej niż samo uruchomienie python manage.py runserver. To proces, który wymaga odpowiedniego podejścia do konfiguracji serwera, bazy danych, cache'owania, plików statycznych i bezpieczeństwa. Na szczęście — Docker i CI/CD pozwalają zautomatyzować i uprościć cały ten proces.

Dlaczego Docker?

Docker pozwala uruchamiać aplikacje w lekkich, odizolowanych kontenerach. Dzięki temu masz identyczne środowisko w fazie developmentu, testów i produkcji.

Bez Dockera

Problemy, z którymi spotykasz się bez Dockera:

  • różne wersje bibliotek i Pythona między developerami,
  • błędy „u mnie działa",
  • problemy z zależnościami i konfiguracją systemu.

Z Dockerem

Korzyści z używania Dockera:

  • powtarzalne środowisko,
  • prosty deployment,
  • łatwe skalowanie i integracja z CI/CD.

Docker rozwiązuje problem „u mnie działa" poprzez enkapsulację całego środowiska aplikacji w kontenerze, który działa identycznie na każdym komputerze.

Konfiguracja Docker dla Django

Zacznij od stworzenia pliku Dockerfile w katalogu projektu:

Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 # Dockerfile FROM python:3.12-slim ENV PYTHONUNBUFFERED=1 WORKDIR /app COPY requirements.txt /app/ RUN pip install --no-cache-dir -r requirements.txt COPY . /app/ CMD ["gunicorn", "app.wsgi:application", "--bind", "0.0.0.0:8000"]

Ten obraz:

  • bazuje na oficjalnym Pythonie (obraz python:3.12-slim jest lekki i bezpieczny),
  • instaluje zależności z requirements.txt,
  • uruchamia aplikację przez Gunicorn — produkcyjny serwer WSGI (zamiast wbudowanego serwera deweloperskiego Django).

Flaga --no-cache-dir zmniejsza rozmiar obrazu, a PYTHONUNBUFFERED=1 zapewnia, że logi są wyświetlane w czasie rzeczywistym.

docker-compose – cały ekosystem

Większość projektów Django wymaga nie tylko aplikacji, ale też bazy danych, cache'a i serwera statycznych plików. docker-compose.yml pozwala uruchomić wszystkie te usługi jednym poleceniem:

YAML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 version: '3.9' services: web: build: . command: gunicorn app.wsgi:application --bind 0.0.0.0:8000 volumes: - .:/app ports: - "8000:8000" depends_on: - db - redis environment: - DEBUG=False - DATABASE_URL=postgres://django:secret@db:5432/django_db db: image: postgres:15 environment: POSTGRES_USER: django POSTGRES_PASSWORD: secret POSTGRES_DB: django_db volumes: - postgres_data:/var/lib/postgresql/data redis: image: redis:7 volumes: postgres_data:

Uruchom wszystko komendą:

Bash
1 docker-compose up --build

I gotowe — masz lokalne środowisko z PostgreSQL, Redisem i Django. Flag --build wymusza przebudowę obrazów, co jest przydatne po zmianach w Dockerfile.

Zmienna konfiguracja (dotenv i secrets)

Nie trzymaj haseł w kodzie. Zamiast tego używaj pliku .env:

INI
1 2 3 4 DEBUG=False SECRET_KEY=your-secret-key-here DATABASE_URL=postgres://django:secret@db:5432/django_db REDIS_URL=redis://redis:6379/0

I załaduj je w settings.py np. przez bibliotekę python-decouple:

Bash
1 pip install python-decouple

W settings.py:

Python
1 2 3 4 5 6 7 8 9 10 11 from decouple import config SECRET_KEY = config('SECRET_KEY') DEBUG = config('DEBUG', cast=bool, default=False) DATABASE_URL = config('DATABASE_URL') # Parsowanie DATABASE_URL dla Django import dj_database_url DATABASES = { 'default': dj_database_url.config(default=DATABASE_URL) }

Pamiętaj, aby dodać .env do .gitignore, aby nie commitować wrażliwych danych do repozytorium. W środowisku produkcyjnym używaj zmiennych środowiskowych serwera lub zarządzanych sekretów (np. AWS Secrets Manager, HashiCorp Vault).

Wdrożenie produkcyjne (Gunicorn + Nginx)

Newsletter · co środę

Python co tydzień — newsletter dla programistów

Otrzymuj codzienne ćwiczenia, ciekawostki z ekosystemu Pythona i wskazówki do rozmów rekrutacyjnych.

2 312 czytelników · ⭐ 4,8

W środowisku produkcyjnym Django powinno być uruchamiane za pomocą Gunicorn (aplikacja) i Nginx (reverse proxy). Gunicorn obsługuje wiele workerów równolegle, co zapewnia lepszą wydajność niż serwer deweloperski Django.

Konfiguracja Nginx

Przykładowa konfiguracja Nginx (nginx.conf):

NGINX
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server { listen 80; server_name example.com; location /static/ { alias /app/static/; } location /media/ { alias /app/media/; } location / { proxy_pass http://web:8000; 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; } }

Docker Compose z Nginx

Dodaj nowy serwis do docker-compose.yml:

YAML
1 2 3 4 5 6 7 8 9 10 11 nginx: image: nginx:latest ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf - ./static:/app/static - ./media:/app/media depends_on: - web

W produkcji użyj HTTPS — skonfiguruj certyfikaty SSL (np. przez Let's Encrypt i Certbot). Nginx obsługuje również kompresję, cache'owanie i ochronę przed podstawowymi atakami.

CI/CD – automatyzacja wdrażania

Ręczne wdrażanie to przeszłość. Z pomocą GitHub Actions, GitLab CI lub Jenkins możesz w pełni zautomatyzować proces wdrożeniowy. CI/CD pipeline automatycznie uruchamia testy, sprawdza jakość kodu i wdraża aplikację po każdym pushu do repozytorium.

Przykład GitHub Actions

Przykład .github/workflows/deploy.yml:

YAML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 name: Django CI/CD on: push: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: 3.12 - name: Install dependencies run: | pip install -r requirements.txt - name: Run tests run: | python manage.py test - name: Run linting run: | pip install flake8 black flake8 . black --check . deploy: needs: test runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - name: Checkout uses: actions/checkout@v4 - name: Deploy with Docker run: | docker-compose -f docker-compose.prod.yml build docker-compose -f docker-compose.prod.yml up -d

Ten pipeline:

  • pobiera kod z repozytorium,
  • instaluje zależności,
  • uruchamia testy jednostkowe,
  • sprawdza jakość kodu (linting),
  • automatycznie wdraża aplikację (tylko jeśli testy przeszły).

W prawdziwym projekcie dodaj też etapy dla staging environment, rollback w przypadku błędów oraz powiadomienia o statusie wdrożenia.

Dobre praktyki przy wdrażaniu Django

Przy wdrażaniu aplikacji Django warto pamiętać o kilku kluczowych zasadach:

  1. Oddziel środowiska — osobne konfiguracje dla dev, staging, prod. Używaj osobnych plików .envdocker-compose dla każdego środowiska.

  2. Używaj .env — nigdy nie trzymaj haseł, kluczy API i tokenów w repozytorium. Wszystkie wrażliwe dane powinny być w zmiennych środowiskowych.

  3. Kompresuj i serwuj statyczne pliki przez CDN — użyj collectstatic i skonfiguruj CDN (CloudFront, Cloudflare) dla lepszej wydajności. Django oferuje WhiteNoise jako prostszą alternatywę.

  4. Monitoruj błędy — np. przez Sentry, który automatycznie zbiera i raportuje błędy z aplikacji. To pozwala szybko reagować na problemy w produkcji.

  5. Automatyzuj testy i linting przed każdym merge'em — blokuj merge, jeśli testy nie przechodzą lub kod nie spełnia standardów jakości.

  6. Twórz backupy bazy danych automatycznie — użyj cron + pg_dump (dla PostgreSQL) lub narzędzi cloud (AWS RDS automatyczne backupy). Testuj również proces przywracania z backupu.

  7. Używaj migracji bazodanowych — zawsze stosuj migracje w procesie wdrożenia (python manage.py migrate). Rozważ rollback plan na wypadek problemów.

Skalowanie i dalsza automatyzacja

Kurs · 24 lekcje8h 14m
Kurs

Kurs Python dla początkujących — PyStart

Zacznij programować w Pythonie! Idealne dla osób bez doświadczenia. Praktyczne zadania, projekty i wsparcie społeczności.

  • 24 lekcje wideo + 80 ćwiczeń
  • Realne bazy z e-commerce
  • Społeczność i code-review
499 zł799 zł−38%
Rozpocznij naukę

Kiedy aplikacja rośnie, potrzebujesz bardziej zaawansowanych narzędzi:

  1. Docker Swarm lub Kubernetes — do zarządzania kontenerami w klastrze. Umożliwiają automatyczne skalowanie, load balancing i wysoką dostępność.

  2. GitOps — np. ArgoCD do zarządzania infrastrukturą jako kod. Zmiany w repozytorium automatycznie synchronizują się z środowiskiem produkcyjnym.

  3. Monitoring i alerty — Prometheus + Grafana do monitorowania metryk aplikacji i infrastruktury. Ustaw alerty dla krytycznych metryk (CPU, pamięć, błędy).

  4. Load balancer — NGINX lub Traefik jako load balancer przed wieloma instancjami aplikacji. Zapewnia równomierne obciążenie i odporność na awarie.

  5. Auto-scaling — automatyczne dodawanie nowych instancji aplikacji w zależności od obciążenia (np. Kubernetes HPA lub AWS Auto Scaling).

Podsumowanie

Docker i CI/CD to standard w nowoczesnym wdrażaniu aplikacji Django. Pozwalają zachować spójność środowisk, automatyzować testy i deployment, minimalizować błędy oraz wdrażać nowe wersje aplikacji szybciej i bezpieczniej. Zacznij od prostego Dockerfile i pipeline'u CI, a z czasem rozbuduj go o staging, testy integracyjne i automatyczne release'y. Pamiętaj, że wdrożenie to proces iteracyjny — zaczynaj od prostych rozwiązań i ulepszaj je w miarę rozwoju projektu.

Część 12 z 26

Wprowadzenie do Django – pierwsze kroki z frameworkiem

druga lekcja cyklu „Flask vs FastAPI: Porównanie frameworków webowych w Pythonie"

Czytaj kolejny →