0% нашли этот документ полезным (0 голосов)
5 просмотров11 страниц

Docker Lab Assignment

Документ описывает практическую работу по контейнеризации веб-приложения с использованием Docker, Docker Compose и Git. Задача включает создание трех сервисов: фронтенда на Nginx, бэкенда на Python/Flask и базы данных PostgreSQL, с использованием Git для управления версиями. В конце работы ожидается наличие работающего приложения, размещенного на GitHub/GitLab, с полным описанием проекта в README.

Загружено:

nicepeopleproject
Авторское право
© All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате DOCX, PDF, TXT или читать онлайн в Scribd
0% нашли этот документ полезным (0 голосов)
5 просмотров11 страниц

Docker Lab Assignment

Документ описывает практическую работу по контейнеризации веб-приложения с использованием Docker, Docker Compose и Git. Задача включает создание трех сервисов: фронтенда на Nginx, бэкенда на Python/Flask и базы данных PostgreSQL, с использованием Git для управления версиями. В конце работы ожидается наличие работающего приложения, размещенного на GitHub/GitLab, с полным описанием проекта в README.

Загружено:

nicepeopleproject
Авторское право
© All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате DOCX, PDF, TXT или читать онлайн в Scribd

ПРАКТИЧЕСКАЯ РАБОТА

Docker + Docker Compose + Git


Контейнеризация веб-приложения с базой данных и деплой через Git

Параметр Значение
Формат Индивидуальная работа
Результат Ссылка на GitHub/GitLab репозиторий с историей
коммитов
Необходимо Docker, Docker Compose, Git, GitHub/GitLab аккаунт,
текстовый редактор

Описание задачи
Вы создадите и контейнеризируете полноценное веб-приложение, состоящее из
трёх сервисов: фронтенд (Nginx), бэкенд (Python/Flask API) и база данных
(PostgreSQL). Весь процесс ведётся через Git с осмысленными коммитами, ветками
и пушем в удалённый репозиторий.
Задача моделирует реальный рабочий процесс: вы начинаете с пустого
репозитория, поэтапно добавляете сервисы, настраиваете Docker Compose,
организуете сеть и тома, а в конце демонстрируете работающий стек, запускаемый
одной командой.

Этап 1. Инициализация проекта и Git (30 мин)


1.1 Создание репозитория
Создайте новый репозиторий на GitHub или GitLab (публичный или приватный).
Клонируйте его локально и создайте базовую структуру проекта.
Команды:
git clone [Link]
cd docker-lab

mkdir -p backend frontend/html


touch backend/[Link] backend/[Link] backend/Dockerfile
touch frontend/Dockerfile frontend/[Link] frontend/html/[Link]
touch [Link] .gitignore .[Link] [Link]

1.2 Настройка .gitignore


Создайте .gitignore со следующим содержимым:
.env
__pycache__/
*.pyc
.venv/
postgres-data/

1.3 Файл .[Link]


Создайте шаблон переменных окружения (без реальных паролей):
POSTGRES_DB=taskdb
POSTGRES_USER=appuser
POSTGRES_PASSWORD=changeme

1.4 [Link]
Напишите краткое описание проекта: что это, как запустить, какие сервисы входят.

1.5 Первый коммит и пуш


git add .
git commit -m "init: project structure, .gitignore, README"
git push origin main

Чек-лист этапа:
• Репозиторий создан на GitHub/GitLab
• Структура директорий создана
• .gitignore настроен (пароли и кеш не попадают в Git)
• Первый коммит и пуш выполнены

Этап 2. Backend — Flask API + Dockerfile (30 мин)


2.1 Создание ветки
git checkout -b feature/backend

2.2 Flask-приложение (backend/[Link])


Создайте простой REST API для управления задачами (to-do list):
import os
from flask import Flask, jsonify, request
import psycopg2
from [Link] import RealDictCursor

app = Flask(__name__)

def get_db():
return [Link](
host=[Link]("DB_HOST", "postgres"),
database=[Link]("POSTGRES_DB", "taskdb"),
user=[Link]("POSTGRES_USER", "appuser"),
password=[Link]("POSTGRES_PASSWORD", "changeme")
)

def init_db():
conn = get_db()
cur = [Link]()
[Link]("""
CREATE TABLE IF NOT EXISTS tasks (
id SERIAL PRIMARY KEY,
title VARCHAR(200) NOT NULL,
done BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW()
)
""")
[Link]()
[Link]()
[Link]()

@[Link]("/api/health")
def health():
return jsonify({"status": "ok"})

@[Link]("/api/tasks", methods=["GET"])
def get_tasks():
conn = get_db()
cur = [Link](cursor_factory=RealDictCursor)
[Link]("SELECT * FROM tasks ORDER BY created_at DESC")
tasks = [Link]()
[Link]()
[Link]()
return jsonify(tasks)

@[Link]("/api/tasks", methods=["POST"])
def create_task():
data = request.get_json()
conn = get_db()
cur = [Link](cursor_factory=RealDictCursor)
[Link]("INSERT INTO tasks (title) VALUES (%s) RETURNING *",
(data["title"],))
task = [Link]()
[Link]()
[Link]()
[Link]()
return jsonify(task), 201

@[Link]("/api/tasks/<int:task_id>", methods=["PATCH"])
def toggle_task(task_id):
conn = get_db()
cur = [Link](cursor_factory=RealDictCursor)
[Link]("UPDATE tasks SET done = NOT done WHERE id = %s RETURNING *",
(task_id,))
task = [Link]()
[Link]()
[Link]()
[Link]()
if task is None:
return jsonify({"error": "not found"}), 404
return jsonify(task)

@[Link]("/api/tasks/<int:task_id>", methods=["DELETE"])
def delete_task(task_id):
conn = get_db()
cur = [Link]()
[Link]("DELETE FROM tasks WHERE id = %s", (task_id,))
[Link]()
[Link]()
[Link]()
return jsonify({"deleted": task_id})

if __name__ == "__main__":
init_db()
[Link](host="[Link]", port=5000)

2.3 [Link]
flask==3.1.0
psycopg2-binary==2.9.10
gunicorn==23.0.0

2.4 Dockerfile для бэкенда (backend/Dockerfile)


Задание: напишите Dockerfile самостоятельно, следуя требованиям:
• Базовый образ: python:3.12-slim
• Рабочая директория: /app
• Сначала копируйте [Link] и устанавливайте зависимости
(кеширование слоёв!)
• Затем копируйте код приложения
• EXPOSE 5000
• Запуск через gunicorn: gunicorn --bind [Link]:5000 app:app
Подсказка: порядок COPY влияет на кеш слоёв. Если менять только код, а
зависимости те же — Docker не будет переустанавливать пакеты.

2.5 Коммит
git add .
git commit -m "feat(backend): Flask API with CRUD for tasks"
git push origin feature/backend

Чек-лист этапа:
• Ветка feature/backend создана
• Flask-приложение написано с 5 эндпоинтами
• Dockerfile написан с правильным порядком слоёв
• Коммит сделан в ветку, запушен

Этап 3. Frontend — Nginx + статика (30 мин)


3.1 Merge backend и новая ветка
git checkout main
git merge feature/backend
git push origin main
git checkout -b feature/frontend

3.2 HTML-страница (frontend/html/[Link])


Создайте простой интерфейс для списка задач. Страница должна:
• Отображать список задач (GET /api/tasks)
• Иметь форму добавления новой задачи (POST /api/tasks)
• Позволять отмечать задачу выполненной (PATCH /api/tasks/:id)
• Позволять удалять задачу (DELETE /api/tasks/:id)
Используйте Vanilla JS (fetch API). Фреймворки не нужны — цель практики в
Docker, а не в вёрстке. Достаточно минимального рабочего интерфейса.

3.3 Конфигурация Nginx (frontend/[Link])


Nginx должен выполнять две задачи: отдавать статику и проксировать API-запросы
на бэкенд.
server {
listen 80;

# Статические файлы
location / {
root /usr/share/nginx/html;
index [Link];
}

# Проксирование API на бэкенд


location /api/ {
proxy_pass [Link]
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Обратите внимание: backend:5000 — это имя сервиса из [Link].


Контейнеры в одной user-defined bridge сети обращаются друг к другу по имени
сервиса.

3.4 Dockerfile для фронтенда (frontend/Dockerfile)


Задание: напишите Dockerfile:
• Базовый образ: nginx:1.27-alpine
• Скопируйте [Link] в /etc/nginx/conf.d/[Link]
• Скопируйте html/ в /usr/share/nginx/html
• EXPOSE 80

3.5 Коммит
git add .
git commit -m "feat(frontend): Nginx with static HTML and API proxy"
git push origin feature/frontend

Чек-лист этапа:
• Backend влит в main
• Ветка feature/frontend создана
• HTML-страница с CRUD-операциями через fetch
• Nginx конфиг с proxy_pass на backend
• Dockerfile написан

Этап 4. Docker Compose — собираем всё вместе (30


мин)
4.1 Merge и новая ветка
git checkout main
git merge feature/frontend
git push origin main
git checkout -b feature/compose

4.2 Создание .env файла


Скопируйте .[Link] в .env и задайте реальные значения (этот файл НЕ
попадает в Git благодаря .gitignore):
cp .[Link] .env
# Отредактируйте .env — задайте свой пароль

4.3 [Link]
Задание: напишите [Link], который определяет три сервиса.
Следуйте спецификации:

Сервис Image / Build Порты Зависимости Особенности


postgres postgres:16- Не — Volume для
alpine пробрасывать /var/lib/postgresql/data,
наружу! env из .env
backend build: ./backend Не postgres env:
пробрасывать DB_HOST=postgres +
наружу! из .env, restart: unless-
stopped
frontend build: ./frontend 80:80 backend restart: unless-stopped

Важные требования:
• PostgreSQL и Backend НЕ должны быть доступны снаружи (без ports:). Только
Frontend пробрасывает порт 80.
• Все три сервиса в одной сети (Compose создаёт её автоматически).
• Переменные окружения PostgreSQL (POSTGRES_DB, POSTGRES_USER,
POSTGRES_PASSWORD) берутся из .env файла.
• Backend получает DB_HOST=postgres (имя сервиса!) плюс те же переменные
из .env.
• Volume для PostgreSQL — именованный (объявлен в секции volumes:).
• depends_on обеспечивает порядок запуска.
Подсказка по env_file и environment:
services:
backend:
build: ./backend
env_file: .env # все переменные из .env
environment:
- DB_HOST=postgres # дополнительная переменная
depends_on:
- postgres

4.4 Запуск и проверка


docker compose up -d --build
docker compose ps # все 3 сервиса running?
docker compose logs backend # нет ошибок?

# Проверка API:
curl [Link]
curl -X POST [Link] -H "Content-Type: application/json" \
-d '{"title": "Finish Docker lab"}'
curl [Link]

# Откройте [Link] в браузере

4.5 Коммит
git add .
git commit -m "feat(compose): full stack with postgres, backend, frontend"
git push origin feature/compose

Чек-лист этапа:
• [Link] с 3 сервисами, volume, env_file
• PostgreSQL и backend НЕ доступны снаружи
• Приложение открывается по [Link]
• Данные сохраняются в PostgreSQL через API

Этап 5. Проверка персистентности и отладка (30


мин)
5.1 Тест персистентности данных
Убедитесь, что данные переживают перезапуск контейнеров:
1. Добавьте 2-3 задачи через интерфейс или curl
2. Остановите все контейнеры: docker compose down
3. Запустите заново: docker compose up -d
4. Проверьте, что задачи на месте: curl [Link]
Вопрос: Что произойдёт, если выполнить docker compose down -v? Почему?
Проверьте и объясните в README.

5.2 Полезные команды отладки


Попрактикуйтесь с отладочными командами:
# Логи конкретного сервиса
docker compose logs -f backend

# Войти внутрь контейнера


docker compose exec backend sh
docker compose exec postgres psql -U appuser -d taskdb

# Просмотреть сети
docker network ls
docker network inspect docker-lab_default

# Просмотреть тома
docker volume ls

5.3 Самостоятельное задание: добавьте Redis


Усложнение (по желанию): добавьте Redis как четвёртый сервис. Backend должен
кешировать список задач в Redis (TTL 30 секунд). Это потребует:
• Нового сервиса redis: в [Link] (образ redis:7-alpine)
• Новой зависимости redis в [Link]
• Модификации [Link] для работы с кешем
• Backend обращается к Redis по имени сервиса: redis:6379

5.4 Коммит
git add .
git commit -m "docs: persistence test results, debug notes"
git push origin feature/compose

Этап 6. Финализация, merge, документация (30 мин)


6.1 Final merge
git checkout main
git merge feature/compose
git push origin main

6.2 Обновите [Link]


Финальная версия README должна содержать:
1. Описание проекта и его архитектуры
2. Схему сервисов (текстовая или Mermaid-диаграмма)
3. Инструкцию по запуску (от клонирования до работающего приложения)
4. Описание переменных окружения
5. Список полезных команд (запуск, остановка, логи, вход в контейнер)
6. Ответ на вопрос про docker compose down -v

6.3 Финальный коммит и тег


git add .
git commit -m "docs: final README with architecture and instructions"
git tag v1.0.0
git push origin main --tags

6.4 Проверка: свежий клон


Смоделируйте ситуацию, когда другой разработчик получает ваш проект:
cd /tmp
git clone [Link] test-clone
cd test-clone
cp .[Link] .env
# отредактируйте .env
docker compose up -d --build
# Откройте [Link] — всё работает?

Чек-лист этапа:
• Все ветки влиты в main
• README полный и понятный
• Тег v1.0.0 создан
• Проект запускается из свежего клона одной командой

Ожидаемая история Git


К концу работы ваш git log --oneline --graph должен выглядеть примерно так:
* a1b2c3d (HEAD -> main, tag: v1.0.0) docs: final README
* d4e5f6g docs: persistence test results, debug notes
* h7i8j9k feat(compose): full stack with postgres, backend, frontend
|\
| * l0m1n2o feat(frontend): Nginx with static HTML and API proxy
|/
* p3q4r5s feat(backend): Flask API with CRUD for tasks
* t6u7v8w init: project structure, .gitignore, README

Минимум 5 коммитов, 2 ветки (feature/backend, feature/frontend или


feature/compose), теги.

Финальная структура проекта


docker-lab/
├── [Link]
├── .[Link]
├── .env # НЕ в Git!
├── .gitignore
├── [Link]
├── backend/
│ ├── Dockerfile
│ ├── [Link]
│ └── [Link]
└── frontend/
├── Dockerfile
├── [Link]
└── html/
└── [Link]
Критерии оценки

Критерий Макс. Что проверяется


балл
Git workflow 20 Осмысленные коммиты, ветки, merge,
push, .gitignore
Dockerfiles 20 Корректный синтаксис, оптимизация слоёв,
gunicorn
[Link] 25 3 сервиса, volumes, env_file, depends_on,
безопасность портов
Работоспособность 20 Приложение запускается из свежего клона одной
командой
[Link] 10 Архитектура, инструкция, ответ на вопрос о -v
Бонус: Redis 5 Четвёртый сервис с кешированием

Шпаргалка по командам
Git
git checkout -b <branch> # создать и переключиться на ветку
git add . # добавить всё в staging
git commit -m "message" # зафиксировать изменения
git push origin <branch> # отправить в удалённый репо
git checkout main # переключиться на main
git merge <branch> # влить ветку
git tag v1.0.0 # создать тег
git log --oneline --graph # красивая история

Docker
docker build -t myapp . # собрать образ
docker run -d -p 8080:80 myapp # запустить контейнер
docker images # список образов
docker ps # запущенные контейнеры
docker logs <container> # логи
docker exec -it <container> sh # войти внутрь

Docker Compose
docker compose up -d --build # собрать и запустить
docker compose down # остановить и удалить
docker compose down -v # + удалить тома (данные!)
docker compose logs -f <svc> # логи сервиса
docker compose exec <svc> sh # войти в контейнер
docker compose ps # статус сервисов
docker network ls # список сетей
docker volume ls # список томов
Удачи! Если возникают ошибки — начинайте с docker compose logs.

Вам также может понравиться