17 maja 2023
Docker: Jak użyć Dockera do konteneryzacji naszej aplikacji?
17 maja 2023
Docker to platforma open-source, która upraszcza proces budowania, uruchamiania i zarządzania aplikacjami w kontenerach. Kontenery to lekkie, przenośne i izolowane środowiska, które pozwalają programistom pakować aplikacje wraz z ich zależnościami, gwarantując, że aplikacja działa konsekwentnie w różnych środowiskach. Ta technologia zyskała ogromną popularność w ostatnich latach dzięki swojej zdolności do usprawniania procesu tworzenia i wdrażania, redukcji niespójności między środowiskami deweloperskimi i produkcyjnymi oraz poprawy ogólnej efektywności dostarczania oprogramowania.
W tym wpisie na blogu przyjrzymy się, jak używać Dockera do skonteneryzowania aplikacji internetowej Django, zapewniając spójne środowisko zarówno dla tworzenia, jak i produkcji. Będzie to obejmowało konfigurowanie Dockera dla twojej aplikacji Django, tworzenie plików Dockerfiles i Docker Compose, budowanie i uruchamianie twojej aplikacji w kontenerach Docker, oraz omówienie kilku wskazówek i najlepszych praktyk dotyczących używania Django z Dockerem.
Dlaczego warto używać Dockera dla aplikacji Django?
Docker dostarcza kilka korzyści, gdy jest używany z aplikacjami Django, co czyni go atrakcyjnym wyborem dla deweloperów. Oto kilka kluczowych zalet korzystania z Dockera dla twoich projektów Django:
1. Spójne środowisko: Kontenery Dockera gwarantują, że twoja aplikacja działa w tym samym środowisku, niezależnie od miejsca, w którym jest wdrażana. To eliminuje problem "u mnie działa" i zmniejsza szanse na napotkanie problemów podczas przechodzenia z rozwoju do produkcji.
2. Łatwiejsze zarządzanie zależnościami: Dzięki Dockerowi, możesz pakować swoją aplikację Django wraz z jej zależnościami, upraszczając proces zarządzania i aktualizacji bibliotek i usług, od których zależy twoja aplikacja.
3. Uproszczone wdrożenie: Użycie Dockera upraszcza proces wdrożenia, ponieważ musisz wdrażać tylko jeden kontener zamiast zarządzać wieloma komponentami osobno. Może to zaoszczędzić czas i zmniejszyć ryzyko błędów podczas wdrożenia.
4. Skalowalność: Docker ułatwia skalowanie twojej aplikacji Django poziomowo poprzez uruchamianie wielu instancji twojej aplikacji za pomocą balansera obciążeń. Może to pomóc w obsłudze zwiększonego ruchu i poprawić wydajność twojej aplikacji.
5. Izolacja: Kontenery Docker zapewniają izolowane środowisko, pozwalając na uruchamianie wielu aplikacji o różnych zależnościach na tym samym hoście bez konfliktów. Może to być szczególnie przydatne przy pracy nad wieloma projektami lub udostępnianiu zasobów innym programistom.
6. Poprawiona współpraca: Korzystając z Dockera, możesz zapewnić, że wszyscy członkowie zespołu pracują w tym samym środowisku i zależnościach, co zmniejsza szanse na napotkanie problemów spowodowanych różnicami w środowiskach deweloperskich.
Poprzez skonteneryzowanie twojej aplikacji Django za pomocą Dockera, możesz skorzystać z tych korzyści, aby usprawnić swój proces deweloperski, uprościć wdrożenie i zapewnić konsekwentną wydajność w różnych środowiskach.
Konfiguracja Dockera dla twojej aplikacji Django
W tej sekcji omówimy kroki niezbędne do skonfigurowania Dockera dla twojej aplikacji Django, w tym instalację Dockera i Docker Compose, tworzenie Dockerfile i tworzenie plików Docker Compose dla środowisk deweloperskich i produkcyjnych.
1. Instalacja Dockera i Docker Compose
Na początku musisz zainstalować Docker Desktop
na swoim komputerze do deweloperki. Postępuj zgodnie z oficjalnymi instrukcjami instalacji Docker Desktop (https://docs.docker.com/desktop/install/windows-install/
) w zależności od systemu operacyjnego.
2. Tworzenie Dockerfile dla twojej aplikacji Django
Dockerfile to skrypt zawierający instrukcje do budowania obrazu Dockera dla twojej aplikacji. Stwórz plik o nazwie "Dockerfile
" w katalogu głównym twojego projektu Django z następującą zawartością:
# Use an official Python runtime as a parent image
FROM python:3.10
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Create and set the working directory
RUN mkdir /app
WORKDIR /app
# Install any needed packages specified in requirements.txt
COPY requirements.txt /app/
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Copy the rest of the application code
COPY . /app/
Ten Dockerfile określa, że używamy oficjalnego obrazu Python 3.10
jako naszego obrazu bazowego, ustawia niektóre zmienne środowiskowe, tworzy katalog roboczy, instaluje zależności z pliku requirements.txt i kopiuje resztę kodu aplikacji.
3. Tworzenie pliku Docker Compose do deweloperki
Docker Compose pozwala definiować i uruchamiać aplikacje wielokontenerowe za pomocą prostego pliku YAML. Utwórz plik o nazwie "docker-compose.yml
" w katalogu głównym twojego projektu Django z następującą zawartością:
version: '3.9'
services:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
ports:
- "8000:8000"
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypassword
Ten plik definiuje dwie usługi: web dla twojej aplikacji Django i db dla bazy danych PostgreSQL. Usługa web korzysta z Dockerfile, który stworzyliśmy wcześniej, do budowy aplikacji, uruchamia serwer deweloperski Django i mapuje port 8000 na maszynę hosta. Usługa db korzysta z oficjalnego obrazu PostgreSQL 15 i ustawia niektóre zmienne środowiskowe do konfiguracji bazy danych.
4. Tworzenie pliku Docker Compose dla produkcji
Dla produkcji utworzymy oddzielny plik Docker Compose o nazwie "docker-compose.prod.yml
" z kilkoma zmianami w stosunku do wersji deweloperskiej:
version: '3.9'
services:
web:
build: .
command: gunicorn myproject.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/app/static
ports:
- "8000:8000"
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypassword
nginx:
build: ./nginx
ports:
- "80:80"
depends_on:
- web
volumes:
- static_volume:/app/static
volumes:
static_volume:
W tym pliku zastąpiliśmy serwer deweloperski Django Gunicorn
, dodaliśmy wolumin dla plików statycznych i wprowadziliśmy usługę Nginx
, która będzie pełnić funkcję reverse proxy dla naszej aplikacji Django. Pamiętaj, aby zastąpić "myproject" nazwą swojego projektu Django.
Dodatkowo, utwórz katalog "nginx
" w głównym katalogu swojego projektu i utwórz w nim "Dockerfile
" z następującą zawartością:
FROM nginx:1.25
COPY nginx.conf /etc/nginx/nginx.conf
Utwórz plik "nginx.conf
" w katalogu "nginx
" z następującą zawartością:
# first we declare our upstream server, which is our Gunicorn application
upstream web {
# docker will automatically resolve this to the correct address
# because we use the same name as the service: "web"
server web:80;
}
server {
listen 80;
server_name localhost;
location / {
# everything is passed to Gunicorn
proxy_pass http://hello_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
autoindex on;
alias /opt/services/djangoapp/static/;
}
location /media/ {
autoindex on;
alias /opt/services/djangoapp/media/;
}
}
Ten plik konfiguracyjny konfiguruje Nginx jako reverse proxy, aby przekazywać żądania do serwera Gunicorn i służy do bezpośredniego obsługiwania plików statycznych.
Budowanie i uruchamianie aplikacji Django za pomocą Dockera
Teraz, gdy mamy już gotowe pliki Docker i Docker Compose, przyjrzyjmy się, jak zbudować i uruchomić naszą aplikację Django w kontenerach Docker.
1. Budowanie obrazu Docker
Aby zbudować obraz Docker dla twojej aplikacji Django, otwórz terminal, przejdź do głównego katalogu twojego projektu i wykonaj następujące polecenie:
docker-compose build
To polecenie zbuduje obraz Docker dla twojej aplikacji, korzystając z Dockerfile i pliku docker-compose.yml
. Może to zająć kilka minut, zwłaszcza jeśli robisz to po raz pierwszy.
2. Uruchamianie kontenera Docker
Po zbudowaniu obrazu Docker możesz uruchomić swoją aplikację Django i jej powiązane usługi (np. bazę danych) za pomocą następującego polecenia:
#For development:
docker-compose up
#For production:
docker-compose -f docker-compose.prod.yml up
To polecenie uruchomi kontenery określone w odpowiednim pliku Docker Compose, a twoja aplikacja Django powinna być teraz dostępna w przeglądarce pod adresem http://localhost:8000
(do deweloperki) lub http://localhost
(do produkcji).
3. Wykonywanie poleceń Django w kontenerze Docker
Może zdarzyć się, że będziesz musiał uruchomić polecenia zarządzania Django w kontenerze Docker, takie jak migracje bazy danych lub tworzenie superużytkownika. Aby to zrobić, użyj polecenia docker-compose exec:
#For development:
docker-compose exec web python manage.py migrate
docker-compose exec web python manage.py createsuperuser
#For production:
docker-compose -f docker-compose.prod.yml exec web python manage.py migrate
docker-compose -f docker-compose.prod.yml exec web python manage.py createsuperuser
Te polecenia wykonają określone polecenia zarządzania Django w kontenerze usługi web.
Porady i dobre praktyki do Django i Docker
Kiedy zaczynasz pracować z Dockerem i Django, ważne jest, abyś znał kilka najlepszych praktyk i wskazówek, które pomogą Ci zoptymalizować proces tworzenia i wdrażania:
1. Użyj .dockerignore: Utwórz plik .dockerignore w głównym katalogu swojego projektu, aby wykluczyć pliki i katalogi, które nie są potrzebne do budowania obrazu Docker. Może to pomóc zredukować rozmiar twojego obrazu i przyspieszyć proces budowania. Na przykład:
*.pyc
*.pyo
*.mo
*.db
*.css.map
*.egg-info
*.sql.gz
.cache
.project
.idea
.pydevproject
.idea/workspace.xml
.DS_Store
.git/
.sass-cache
.vagrant/
__pycache__
dist
docs
env
logs
src/{{ project_name }}/settings/local.py
src/node_modules
web/media
web/static/CACHE
stats
Dockerfile
2. Używaj zmiennych środowiskowych: Używaj zmiennych środowiskowych dla poufnych informacji, takich jak dane uwierzytelniające bazy danych czy klucze API, zamiast zakodowywać je na stałe w plikach Docker Compose czy kodzie aplikacji. Poprawia to bezpieczeństwo i ułatwia zarządzanie zmianami konfiguracji.
3. Oddziel konfiguracje dla deweloperki i produkcji: Jak pokazano w tym wpisie, używaj oddzielnych plików Docker Compose dla środowisk deweloperskich i produkcyjnych. Pozwala to łatwo przełączać się między konfiguracjami i zapewnia, że ustawienia specyficzne dla deweloperki nie trafią przypadkiem do produkcji.
4. Używaj oficjalnych obrazów: Kiedykolwiek to możliwe, używaj oficjalnych obrazów dla swoich usług, takich jak Python
, PostgreSQL
czy Nginx
, ponieważ są one utrzymywane przez odpowiednie organizacje i są bardziej prawdopodobne, że będą aktualne i bezpieczne.
5. Utrzymuj swoje obrazy w szczupłej formie: Zminimalizuj liczbę warstw w swoim Dockerfile i staraj się łączyć powiązane polecenia w jedną warstwę. Może to pomóc zredukować rozmiar twoich obrazów i poprawić czasy budowy.
6. Testuj swoją aplikację w kontenerach: Aby upewnić się, że twoja aplikacja zachowuje się zgodnie z oczekiwaniami podczas działania w środowisku skonteneryzowanym, rozważ testowanie swojej aplikacji w kontenerach Docker jako część procesu ciągłej integracji.
Przestrzegając tych najlepszych praktyk, możesz poprawić efektywność, utrzymanie i bezpieczeństwo swoich aplikacji Django przy pracy z Dockerem.
Podsumowanie
W tym wpisie na blogu omówiliśmy, jak używać Dockera do konteneryzacji aplikacji webowej Django, zapewniając spójne środowisko zarówno dla deweloperki, jak i produkcji. Omówiliśmy instalację Dockera i Docker Compose, tworzenie Dockerfile, oraz tworzenie plików Docker Compose dla środowisk deweloperskich i produkcyjnych. Omówiliśmy również budowanie i uruchamianie twojej aplikacji Django z Dockerem i udzieliliśmy kilku porad i najlepszych praktyk dotyczących pracy z Django i Dockerem.
Przestrzegając kroków opisanych w tym wpisie, możesz wykorzystać moc konteneryzacji do usprawnienia procesu tworzenia, uproszczenia wdrażania i zapewnienia spójnej wydajności w różnych środowiskach. Kiedy będziesz kontynuować pracę z Dockerem i Django, pamiętaj o utrzymaniu aktualności z najlepszymi praktykami i poszukiwaniu dodatkowych optymalizacji, aby w pełni wykorzystać te potężne technologie.