Чудовий вибір теми! Це одна з тих навичок, яка розділяє новачків і професіоналів. Вмикаємо режим 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. 🧠 Теоретична база (без нудних лекцій)
Давайте розберемося, як ця магія працює під капотом. Не лякайтеся термінів, зараз все стане ясно.
Ключові поняття (Це треба запам’ятати 📌):
- Dockerfile (Рецепт 📜): Це текстовий файл, де ви пишете інструкцію. Наприклад: "Візьми Python, додай мій код, встанови бібліотеки, відкрий порт 8000".
- Image (Образ / Страва 🥘): Це результат виконання рецепта. Це "зліпок" вашої програми. Він незмінний. Якщо Image — це клас в ООП, то...
- 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?
-
Порядок шарів (Layer Caching):
- Новачок: Спочатку копіює весь код (
COPY . .), а потім встановлює залежності (RUN pip install...). - Профі: Розуміє, що код змінюється часто, а залежності — рідко. Тому спочатку копіюємо
requirements.txtі ставимо ліби. Docker закешує цей крок. Якщо ви зміните одну кому в коді, Docker не буде перевстановлювати всі бібліотеки заново. Це економить хвилини (і нерви) при білді!
- Новачок: Спочатку копіює весь код (
-
Безпека та
.dockerignore:- Новачок: Копіює все підряд, включаючи
.envфайл з паролями, віртуальне оточенняvenvі базу даних.sqlite3. - Профі: Створює
.dockerignore(працює як.gitignore), щоб сміття і секрети не потрапили в образ.
- Новачок: Копіює все підряд, включаючи
-
Розмір має значення:
- Використовуйте
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). Це буде легендарно!
А поки — спробуйте "контейнеризувати" свій пет-проєкт. Успіхів!