Итоговый проект — приложение, база и прокси в Compose

Сервис, который не стыдно отдать администратору: запускается одной командой и переживает обновления

Прогресс курса Модуль 9 из 9

Что покажет проект

01

Постановка

Нужен сервис заметок с HTTP API. Снаружи доступен только обратный прокси, он передаёт запросы приложению, приложение хранит заметки в PostgreSQL:

 клиент ──▶ :8080 proxy (nginx) ──сеть front──▶ app (Python) ──сеть back──▶ db (PostgreSQL)
                                                                         том db-data

API приложения:

$ curl -s -X POST -H 'Content-Type: application/json' -d '{"text":"первая заметка"}' http://127.0.0.1:8080/api/notes
{"id":1,"text":"первая заметка"}
$ curl -s http://127.0.0.1:8080/api/notes
[{"created":"2026-10-23T16:56:23+00:00","id":1,"text":"первая заметка"}]
$ curl -s http://127.0.0.1:8080/health
{"status":"ok","version":"1.0.0"}

Пустой или слишком длинный текст — ответ 400. /health проверяет и подключение к базе: база недоступна — 503. Язык приложения — любой; в примерах курса это Python, Flask и gunicorn (модули 03 и 07). Приложение — небольшое, главное в проекте не код, а упаковка и запуск.

02

Что должно получиться

ТребованиеМодуль
Dockerfile приложения: зависимости до кода, .dockerignore, не root, сервер приложений, HEALTHCHECK, CMD в exec-форме03, 07
Схема базы создаётся при первом запуске на пустом томе — скрипт в /docker-entrypoint-initdb.d/04
Данные базы в именованном томе; down и up их не теряют04, 06
Сети front и back, back — internal: true; прокси не видит базу; опубликован только порт прокси05
Конфигурация nginx с хоста только для чтения; заголовок Server без версии; всё, кроме /api/ и /health, — 40404, 05
Проверки готовности у всех трёх сервисов, запуск по condition: service_healthy06
Пароль базы — secrets: из файла, которого нет в репозитории; в docker inspect пароля нет06, 08
restart, лимиты памяти и процессора, ротация журналов; read_only и cap_drop: [ALL] у приложения и прокси (вернуть только нужные возможности)07
Версия образа приложения — тег из переменной, не latest03, 07
Скрипт резервной копии базы и проверенное восстановление04
Сканирование образа приложения, разбор критичных находок08

Порядок работы

  • Сначала приложение и база без прокси: docker compose up, запросы на порт приложения.
  • Затем прокси и сети: убрать публикацию порта приложения, проверить, что прокси не видит db (docker compose exec proxy ping db).
  • Затем секрет, проверки готовности, лимиты и права — по одному, после каждого шага up -d и проверка, что всё работает. Если сервис не стартует — docker compose logs и docker inspect.
  • В конце — сбои: остановить базу и посмотреть на /health; удалить заметки и восстановить из копии; пересоздать проект через down и up.
Секрет из файла монтируется в контейнер с правами файла на хосте. Приложение работает не от root — значит, файл должен быть ему доступен для чтения. Закрывайте доступ каталогом, в котором лежит файл, а не самим файлом.

Подробные требования, что сдаётся и критерии оценивания — в задании на портале.

Практические задания — на учебном портале. Задания, критерии оценивания, сдача работ и оценки преподавателя — в курсе на portal.nevabit.ru. Учётную запись выдаёт преподаватель.

Курс пройден

Вы прошли курс «Основы Docker». Дальше — «Основы CI/CD» (собирать и выкладывать образы автоматически), «Kubernetes» (запускать контейнеры на нескольких серверах) и «Кибербезопасность».

Модуль 08: Реестры и безопасность Все модули Все курсы