Модуль 38

Docker та деплой Django-проєкту

Чудовий вибір теми! Це одна з тих навичок, яка розділяє новачків і професіоналів. Вмикаємо режим CS50, запалюємо енергію і погнали розбиратися з контейнерами!


🐳 Урок: Docker та деплой Django-проєкту

(або як перестати молитися, щоб воно запустилося на сервері)


1. 🔥 Вступ: "У мене на комп’ютері все працює!"

Уявіть ситуацію: ви тиждень писали крутий бекенд на Django. У вас стоїть Python 3.11, спеціальна версія бібліотеки для обробки зображень і налаштована база даних PostgreSQL. Ви з гордістю відправляєте код замовнику або колезі.

Вони запускають і... БАМ! 💥 Помилка. "Module not found", "Version mismatch", "Database connection failed".

Чому? Бо у них Python 3.9, інша операційна система, або вони забули встановити якусь системну бібліотеку.

Риторичне питання: Хіба ваша робота як програміста — це писати інструкції на 10 сторінок "Як налаштувати Windows, щоб мій код запрацював"? Ні. Ваша робота — створювати продукт.

Аналогія: Переїзд і меблі 🚛

Уявіть, що ви переїжджаєте в новий дім. * Без Docker: Ви розбираєте меблі на дощечки, складаєте їх у купу, везете, а в новому домі намагаєтесь зібрати. А раптом гвинтик загубився? А раптом стеля в новій кімнаті нижча? * З Docker: Ви берете цілу кімнату, "заморожуєте" її разом з меблями, повітрям і навіть розетками, кладете в контейнер і везете. У новому місці ви просто відкриваєте контейнер — і там все ідентично.

Навіщо нам це: Docker дозволяє запакувати ваш Django-код, базу даних і всі залежності в одну "коробку", яка гарантовано працюватиме однаково і на вашому MacBook, і на сервері Linux, і на комп'ютері бабусі.


2. 🧠 Теоретична база (без нудних лекцій)

Давайте розберемося, як ця магія працює під капотом. Не лякайтеся термінів, зараз все стане ясно.

Ключові поняття (Це треба запам’ятати 📌):

  1. Dockerfile (Рецепт 📜): Це текстовий файл, де ви пишете інструкцію. Наприклад: "Візьми Python, додай мій код, встанови бібліотеки, відкрий порт 8000".
  2. Image (Образ / Страва 🥘): Це результат виконання рецепта. Це "зліпок" вашої програми. Він незмінний. Якщо Image — це клас в ООП, то...
  3. Container (Контейнер / Об'єкт 📦): Це запущена версія Образу. Це живий процес, який працює прямо зараз. Ви можете запустити 10 контейнерів з одного образу.

Як це працює "під капотом"? (Для інтуїтивного розуміння 💡)

Багато хто плутає Docker з Віртуальною Машиною (VM). * VM — це як окремий будинок. Їй треба свій фундамент, стіни, дах (своя повноцінна ОС). Це важко і довго вантажиться. * Docker — це як квартира у багатоповерхівці. Усі квартири використовують спільний фундамент і комунікації будинку (ядро Linux хост-системи), але стіни ізольовані. Сусід не бачить, що ви робите на кухні. Це легко і дуже швидко.

Головне: Docker ізолює процеси. Вашому Django здається, що він один у всій системі.


3. 🧪 Приклади: Від Hello World до Django

Крок 1: Мінімальний Dockerfile

Як пояснити Docker комп'ютеру? Ми пишемо файл з назвою Dockerfile (без розширення).

Як ви думаєте, з чого ми маємо почати? Правильно, з основи. Нам потрібен Python.

# 1. Базовий образ (Base Image)
FROM python:3.11-slim

# 2. Робоча директорія (куди кладемо код всередині контейнера)
WORKDIR /app

# 3. Копіюємо файл із залежностями
COPY requirements.txt .

# 4. Встановлюємо їх
RUN pip install -r requirements.txt

# 5. Копіюємо весь наш код всередину
COPY . .

# 6. Команда запуску
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Стоп! ✋ Чому 0.0.0.0:8000, а не просто 127.0.0.1? Усередині контейнера localhost — це сам контейнер. Якщо ви запустите на localhost, ви не достукаєтесь до нього "ззовні" (з вашого браузера). 0.0.0.0 каже: "Слухай усіх, хто стукає".

Крок 2: Оркестр з Docker Compose

Одного Django мало. У реальному житті йому потрібна база даних (PostgreSQL). Запускати два контейнери вручну і з'єднувати їх — це біль.

Тут на сцену виходить Docker Compose. Це диригент 🎼. Ми описуємо всі сервіси у файлі docker-compose.yml.

version: '3.8'

services:
  # Наш веб-додаток
  web:
    build: .  # Будуємо з Dockerfile у цій папці
    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: myproject
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password

Що тут відбувається? Ми кажемо: "Docker, підніми мені Django і Postgres, з'єднай їх в одну мережу".


4. 🛠 Практична частина

Тепер ваша черга! Відкривайте термінал. 💻

Завдання 1: "Перший дотик"

Створіть файл Dockerfile у порожній папці. Напишіть інструкцію, яка просто виводить "Hello, Docker!" за допомогою Python. (Підказка: CMD ["python", "-c", "print('Hello, Docker!')"])

Завдання 2: "Django упаковка"

Візьміть будь-який свій старий Django-проєкт (або створіть новий). 1. Створіть requirements.txt (pip freeze > requirements.txt). 2. Напишіть Dockerfile (як у прикладі вище). 3. Зберіть образ командою: docker build -t my-django-app . 4. Запустіть його!

Завдання 3: "Виправ помилку" 🐛

Студент запустив контейнер, але сайт не відкривається у браузері за адресою localhost:8000. У логах пише, що сервер працює. Питання: Що він забув зробити при запуску контейнера? (Підказка: згадайте про порти).

Завдання 4: Міні-кейс "Дані зникають!" 😱

Ви запустили Postgres у контейнері, додали туди користувачів, а потім видалили контейнер. Створили новий — база порожня. Завдання: Додайте в docker-compose.yml для сервісу db налаштування volumes, щоб дані зберігалися на вашому комп'ютері, а не вмирали разом із контейнером.


5. 💡 Мислення як у розробника

Як відрізнити новачка від профі, дивлячись на Dockerfile?

  1. Порядок шарів (Layer Caching):

    • Новачок: Спочатку копіює весь код (COPY . .), а потім встановлює залежності (RUN pip install...).
    • Профі: Розуміє, що код змінюється часто, а залежності — рідко. Тому спочатку копіюємо requirements.txt і ставимо ліби. Docker закешує цей крок. Якщо ви зміните одну кому в коді, Docker не буде перевстановлювати всі бібліотеки заново. Це економить хвилини (і нерви) при білді!
  2. Безпека та .dockerignore:

    • Новачок: Копіює все підряд, включаючи .env файл з паролями, віртуальне оточення venv і базу даних .sqlite3.
    • Профі: Створює .dockerignore (працює як .gitignore), щоб сміття і секрети не потрапили в образ.
  3. Розмір має значення:

    • Використовуйте python:3.11-slim або alpine замість повного образу. Це зменшує розмір вашого контейнера з 1 ГБ до 100-200 МБ.

6. 🧩 Підсумок

Отже, що ми сьогодні зробили? 1. Зрозуміли, що Docker — це надійний спосіб доставки коду, як морський контейнер. 2. Навчилися писати Dockerfile (рецепт). 3. Опанували Docker Compose (диригента для Django + DB). 4. Зрозуміли, як не втратити дані бази.

Що ви тепер вмієте? Ви можете взяти свій проект, запакувати його і запустити на будь-якому сервері (AWS, DigitalOcean, Azure) однією командою docker-compose up -d. Більше ніяких "It works on my machine"!

🚀 Тизер наступного уроку: Окей, ми запакували код. Але як зробити так, щоб при кожному git push наш код автоматично тестувався і сам оновлювався на сервері? Наступного разу говоримо про CI/CD (Continuous Integration / Continuous Deployment). Це буде легендарно!

А поки — спробуйте "контейнеризувати" свій пет-проєкт. Успіхів!