JavaRush /Курсы /Docker for Spring /Единый проект на весь курс

Единый проект на весь курс

Docker for Spring
1 уровень , 4 лекция
Открыта

1. Весь курс держится за один starter repo

Есть два одинаково плохих способа учить инфраструктурную тему. Первый — жить в абстрактных примерах, которые никак не похожи на нормальный бэкенд. Второй — заставить студента сначала написать целый новый сервис, а уже потом, «где-нибудь ближе к концу», показать Docker. Оба варианта просто крадут внимание у главного.

Starter repo решает эту проблему очень честно. Он уже достаточно реален, чтобы на нём было видно поведение обычного Boot-сервиса: HTTP-слой, конфигурацию, профили, экспорт в файл, Actuator, технические сигналы. Но при этом он намеренно не превращается в отдельный курс по доменной модели, JPA, security или messaging. Нам здесь нужен сервис как носитель контейнерной темы, а не как новая большая предметная область.

Именно поэтому один репозиторий методически сильнее пяти «мини-демо». Вы не тратите силы на постоянное повторное знакомство с новым проектом, новым пакетом, новым контекстом и новой бизнес-логикой. Вместо этого вы видите, как одно и то же приложение постепенно взрослеет с точки зрения runtime и инфраструктуры.

2. Как читать репозиторий, не утонув в деталях

Первый взгляд на starter repo должен быть похож не на археологию, а на карту. Сначала важно понять верхний уровень: какие файлы отвечают за запуск, где лежат запросы для быстрых проверок, где живёт файловый сценарий, где сам код и какие артефакты появятся рядом по ходу курса.

Типовая верхнеуровневая структура выглядит так:

# Корень репозитория (папка проекта)
container-ready-catalog-service/
├── Dockerfile        # Инструкция сборки Docker image (понадобится позже по курсу)
├── compose.yaml      # Compose-описание окружения (например, app + БД)
├── requests/         # Быстрые HTTP-запросы для smoke-check и воспроизводимых проверок
├── scripts/          # Вспомогательные скрипты для повторяемых действий вокруг сервиса
├── data/exports/     # Директория, куда сервис может писать экспорт (файловый сценарий)
└── src/main/         # Исходный код Spring Boot приложения

На старте не нужно воспринимать это как сухой список файлов. У каждого элемента своя роль. src/main/ — там живёт само приложение. requests/ — это быстрые HTTP-проверки, чтобы baseline был воспроизводим не «по памяти», а руками. scripts/ — место для маленьких повторяемых операций вокруг сервиса. data/exports/ — напоминание о том, что у сервиса есть и файловая жизнь, а не только REST. Dockerfile и compose.yaml лежат рядом не для красоты: именно они потом станут контейнерной частью этого же проекта.

Здесь важен ещё один момент. Мы не читаем Docker-артефакты раньше времени, но уже видим, что они живут рядом с кодом. Это правильная проектная интуиция. Контейнеризация не должна быть «личной магией автора» где-то в отдельной папке с непонятными скриптами. Она должна быть частью того же репозитория, что и сервис. ⚙️

3. Сервис очень простой

Домен у проекта специально выбран очень спокойным. У нас есть каталог элементов и есть сценарий экспорта этого каталога в файл. Этого ровно достаточно, чтобы на одном сервисе увидеть сразу несколько важных для курса линий: обычный HTTP API, состояние данных, режимы запуска, файловую систему и операционные сигналы.

Если сказать проще, сервис делает не «всё на свете», а только то, что нужно для контейнерной темы. Он умеет отдавать список элементов каталога, выполнять базовые операции над ними и запускать экспорт. Здесь нет задачи поразить вас сложностью бизнес-логики. Наоборот, домен намеренно удерживается в простых границах, чтобы внимание не ушло в сторону. 🧪

Это важная часть понимания. Хороший курс не делает вид, что контейнеризацию надо объяснять через полбэкенда, security-матрицу, три микросервиса и восемь таблиц в базе. Достаточно одного нормального сервиса с понятным поведением. И Container-Ready Catalog Service устроен именно так.

4. standalone и postgres: два режима

У starter repo есть как минимум два базовых режима, и очень важно увидеть их уже в первый день. standalone нужен для быстрого запуска без внешней базы: данные живут в памяти, сервис можно поднять быстро и проверить его HTTP-поведение почти сразу. postgres — это уже более реалистичный режим, где у сервиса появляется внешняя зависимость и весь runtime становится немного взрослее.

Ключевой момент здесь в том, что это не два разных приложения. У нас не появляется отдельный «docker-сервис» и отдельный «локальный сервис». Контроллеры, логика и общий характер поведения остаются теми же. Меняются именно условия запуска. И это очень важная привычка: один сервис, разные предпосылки окружения.

Эта же идея потом будет тянуться через весь курс. Если вам нужно другое поведение среды, вы не должны клонировать проект или плодить второй кодовый путь. Вы должны уметь управлять runtime одного и того же сервиса. Именно здесь контейнерное мышление начинает выглядеть зрелым, а не косметическим.

5. Минимальный операционный baseline

Очень соблазнительно считать сервис «живым» по одному факту: процесс не упал, а в логах мелькнула строчка про старт. Но это слишком слабый критерий. Для нормального baseline нужны хотя бы два сигнала: бизнесовый и технический.

Бизнесовый сигнал отвечает на вопрос «сервис реально делает то, ради чего существует?». Для нашего starter repo таким сигналом отлично работает GET /api/catalog/items. Технический сигнал отвечает на вопрос «приложение вообще поднялось и может честно сообщить о своём состоянии?». Для этого нужен GET /actuator/health.

Именно эта пара даёт хороший smoke-check baseline. Если бизнесовый endpoint отвечает, значит web-слой и минимум логики живы. Если отвечает health, значит у сервиса есть хотя бы базовый операционный контракт. Вместе эти две проверки дают гораздо более честное чувство «сервис поднялся», чем просто факт, что Java-процесс ещё не завершился.

На первом уровне этого уже достаточно. Нам не нужны сложные шаблоны диагностики, не нужен и глубокий разбор Actuator. Пока полезно увидеть только одно: живой сервис — это не просто «не упал», а «отвечает по ключевым признакам жизни».

6. План на сегодня 🍹

Сейчас можно сделать очень маленькое действие, которое даёт первый осязаемый результат без перегрузки. Сначала поднимите starter repo локально тем способом, который для вас уже привычен в Spring Boot-проекте. Нам сейчас не нужен новый build workflow — важно лишь получить работающий локальный baseline.

После этого сделайте две быстрые проверки. Если у вас стандартный порт, они могут выглядеть так:

# Проверяем бизнесовый endpoint: сервис реально отдаёт данные каталога
curl http://localhost:8080/api/catalog/items

# Проверяем техническое состояние: Actuator сообщает, что приложение "живое"
curl http://localhost:8080/actuator/health

Если вы привыкли работать через Postman или .http-файлы, можно воспользоваться requests/ из репозитория — смысл тот же. Первая проверка отвечает на вопрос «жив ли бизнесовый маршрут», вторая — «видит ли сервис сам себя как живое приложение».

Вот это и есть первый значимый результат дня. Вы ещё не собирали image, не писали Dockerfile и не поднимали Compose, но уже умеете смотреть на starter repo как на операционный объект, а не как на папку с кодом. И это очень хороший старт для Docker-курса.

7. Карточка baseline перед контейнеризацией

Ниже — карточка, которую можно использовать не только на этом проекте, но и почти на любом будущем Boot-сервисе. Она помогает не прыгать в Docker раньше времени и быстро фиксировать, что именно вы потом будете контейнеризовать.

Что спросить у любого Boot-сервиса перед контейнеризацией Как это выглядит в Container-Ready Catalog Service
Что именно стартует? Spring Boot приложение с понятной точкой входа
Какой минимальный business smoke-check? GET /api/catalog/items
Какой минимальный technical smoke-check? GET /actuator/health
Какие режимы запуска важно различать? standalone и
postgres
Какие внешние предпосылки уже есть? Порт, при postgres — база, для export — директория
Где искать первое операционное подтверждение? Стартовые логи + ответы на оба endpoint

Это кажется простой таблицей, но на практике она очень сильно экономит силы. Как только вы умеете быстро отвечать на эти вопросы, контейнеризация перестаёт быть прыжком в туман. У вас уже есть baseline, а Docker дальше будет не заменять его, а стабилизировать.

8. Лестница эволюции проекта

Теперь самое приятное: можно увидеть курс как одну непрерывную линию, а не как набор тем. Ниже — короткая карта того, как будет взрослеть этот же самый Container-Ready Catalog Service:

Этап Что меняется в этом же сервисе Что вы получаете
Сейчас Локальный Spring Boot baseline + smoke-check Понятный объект контейнеризации
Дальше Первый image и первый container Воспроизводимый runtime одного сервиса
Потом Нормальный Dockerfile, cache, multi-stage, layers, buildpacks Профессиональную упаковку Java-сервиса
Затем Externalized config, файлы, логи, health, shutdown Контролируемое поведение одного image в разных режимах
После этого app + PostgreSQL через Compose Нормальный локальный бэкенд-стенд
Ещё дальше Добавление Redis и RabbitMQ Умение жить с инфраструктурными зависимостями без хаоса
Финал Переиспользуемый шаблон и навык системного разбора проблем Повторяемый baseline для собственных сервисов

Один и тот же сервис проходит всю дорогу — от локального запуска до контейнерно зрелого шаблона. И за счёт этого каждый следующий шаг ощущается не как новая тема с нуля, а как естественное продолжение уже знакомого контекста.

Если удержать в голове только одну вещь после первого дня, пусть это будет вот что: контейнеризуют не Docker ради Docker, а конкретный Spring Boot-сервис с понятным baseline. Завтра этот baseline уже начнёт превращаться в инженерный объект с собственным жизненным циклом, логами и наблюдаемым поведением в контейнерной среде.

9. Типичные ошибки 🚧

Ошибка №1: читать starter repo как набор случайных папок.
Сначала всегда нужна карта верхнего уровня: где код, где запросы, где файловый сценарий, где будущие контейнерные артефакты. Если начать сразу тонуть в классах и пакетах, очень легко потерять сам учебный смысл проекта.

Ошибка №2: воспринимать standalone и postgres как два разных приложения.
Это один сервис, а не две параллельные кодовые базы. Различаются условия его жизни, а не его природа. Эта мысль потом будет критически важна для контейнерной конфигурации и Compose.

Ошибка №3: считать сервис «живым» только по факту старта процесса.
Процесс может подняться, а полезного поведения не будет. Поэтому минимальный baseline всегда лучше фиксировать хотя бы парой запросов: business endpoint плюс health endpoint.

Ошибка №4: смотреть на Dockerfile и Compose раньше, чем понятен сам сервис.
Это очень частая ловушка. Хочется сразу перейти к «интересной контейнерной части», но без локального baseline она превращается в гадание. Сначала нужно понять, что именно вы контейнеризуете и по каким сигналам узнаете, что сервис жив.

1
Задача
Docker for Spring, 1 уровень, 4 лекция
Недоступна
Мини-репозиторий с operational baseline
Мини-репозиторий с operational baseline
1
Задача
Docker for Spring, 1 уровень, 4 лекция
Недоступна
Скрипт smoke-check для локального сервиса
Скрипт smoke-check для локального сервиса
1
Опрос
Docker Основы, 1 уровень, 4 лекция
Недоступен
Docker Основы
Контейнеризация Spring Boot сервисов
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ