Сборка Java приложения в Docker
Last updated: 12 мая 2025 г.В этом уроке соберем простейшее Spring Boot приложение в Docker-образ (Docker image), запустим его и загрузим на Docker Hub.
Его структура приведена ниже. В ней ничего особенного за исключением того, что в корне проекта добавлен файл с именем Dockerfile
.

В контроллере один простой обработчик, который возвращает строку Hello World!!!.
1package com.SpringBootApps.simpleSpringBootApp.controller;
2
3import org.springframework.web.bind.annotation.GetMapping;
4
5@RestController
6public class MainController {
7 @GetMapping("/helloWorld")
8 public String helloWorld() {
9 return "Hello world!!!";
10 }
11}
Настройка сборки
Сборка Docker Image настраивается с помощью файла под названием Dockerfile
, который нужно создать в корне проекта — как показано в структуре выше.
Итак. В прошлых уроках было упомянуто, что всё, что нужно для запуска приложения докером должно уже быть в его Docker Image, чтобы не пришлось развертывать приложение и устанавливать кучу всего по отдельности.
Откуда же внутри образа (docker image), который получается в результате сборки, берётся всё необходимое ПО: то, что будет запускать наше приложение (например, JDK), то, что будет скачивать зависимости (например, Maven) и т.д.?
Всё просто. Оно есть в интернете и когда производиться команда сборки приложения происходит скачивание его из интернета и помещение скачанного ПО в результирующий Docker Image.
Также при сборке приложения Docker выполняет его настройку — например, загружает зависимости с помощью заранее скачанного для этого ПО (например, Maven). То есть Docker сначала скачивает Maven и сразу использует его для загрузки зависимостей в собираемый образ.
А при запуске уже собранного Docker-образа Docker использует то ПО, которое было включено в образ, для запуска самого приложения — например, берёт из скачанного JDK утилиту java
и с её помощью запускает Spring Boot-приложение.
То какое ПО будет скачиваться в результирующий Docker Image, то как им будет настраиваться или запускаться приложение внутри Docker Image как раз настраивается в Dockerfile.
ПО для сборки с сайта Docker Hub.
Итак, из всех программ, которые нам понадобятся для сборки и запуска приложения, в Dockerfile нужно указать Maven
— для загрузки зависимостей и сборки JAR-файла, а также JDK
— для запуска этого собранного файла.
Их можно найти на сайте Docker Hub
. Там можно найти мавен репозиторий

и в тегах выбрать подходящую версию для нашего приложения.

Таким же образом можем найти репозиторий jdk.

И в его тегах тоже можно поискать подходящую версию jdk.

Очевидно, что ПО скачиваемое в Docker Image нашего спринг приложения тоже является Docker Image.
Настройка Dockerfile.
Сборка Docker Image происходит посредством последовательного выполнения команд прописанных в Dockerfile
. Рассмотрим содержимое Dockerfile спринг приложения, которое мы будем собирать в Docker Image.
1#Решетка в Dockerfile это комментарий.
2
3#Коммандой FROM указывается программа из Docker Hub,
4#которая будет использоваться для сборки Image.
5#Maven – программа из Docker Hub,
6#после двоеточия – ее версия.
7FROM maven:3.8.5-openjdk-17 as maven_build
8
9#WORKDIR – устанавливаем рабочую директорию внутри
10#нашего будущего Image. То есть внутри image будет
11#папка application которая будет восприниматься всеми
12#дальнейшими командами ниже как рабочая директория.
13WORKDIR /application
14
15#COPY – производится копирование всего из директории
16#на компьютере(точка значит из директории в которой
17#находиться Dockerfile, а он находиться в корневой
18#папке спринг проекта) в /application директорию
19#внутри Docker Image
20COPY . /application
21
22#То есть данном этапе содержимое нашего
23#проекта simpleSpringBootApp находиться
24#в папке /application внутри Docker Image.
25
26
27# Командой mvn clean package запускаем сборку
28# приложения в jar. Результирующий jar будет
29# в папке /application/target внутри image.
30RUN mvn -f /application/pom.xml clean package
31# RUN mvn -f /application/pom.xml clean package
32# После run у нас создался первый Docker Image
33# co spring boot проектом внутри него и jar файлом
34# в папке target. Это промежуточный Docker Image,
35#он будет использован для создания результирующего
36#Docker Image, который будет запускаться командой
37#docker container … и загружаться на Docker Hub.
38
39#Указываем jdk из Docker Hub с помощью которого будет
40#запускаться созданный jar.
41FROM openjdk:17
42
43#Указываем порт на котором будет запускаться
44#результирующий Image в Docker Hub.
45#И да это порт докер контейнера, а не того что на компьютере.
46#Порт на нашем компьютере с помощью которого происходить
47#подключение к докер контейнеру по порту указанному
48#в команде ниже мы будем указывать в команде
49#запуска результирующего Docker Image.
50EXPOSE 8080
51
52#Первому Docker Image было дано имя maven build (сверху
53#можно увидеть as maven_build). Теперь мы можем
54#использовать первый Docker Image для создания
55#результирующего Docker Image. С помощью
56#–from=maven_build мы обращаемся к предыдущему
57#промежуточному Docker Image таким образом мы копируем
58#из него jar в папке /application/target
59#в результирующий Docker Image с новым именем app.jar
60COPY –from=maven_build /application/target/*.jar app.jar
61
62#Как уже было сказано знакомыми нам командами пакета jdk,
63#который будет скачан из интернета при сборке,
64#запускаеться итоговый app.jar внутри результирующего
65#Docker Image. То есть видим ниже команду
66#java -jar app.jar для запуска
67#нашего spring boot приложения.
68ENTRYPOINT ["java","-jar","app.jar"]
69#Данная команда будет выполняться внутри
70#сформированного результирующего Docker Image, а запуск
71#самого Docker Image извне будет выполняться одной
72#и той же ранее упомянутой командой docker container…
Сборка приложения в Docker Image
Для начала в консоли перейдем в корневую папку спринг проекта, который мы собираемся собирать в Docker Image и собственно соберем его в Docker Image с помощью комманды:
docker build -t michaelshadrin/simple-spring-boot-app:version1
Здесь michaelshadrin/simple-spring-boot-app это название репозитория, который будет создан на сайте Docker Hub если мы захотим загрузить туда получившийся в результате этой команды Docker образ. Важно уточнить, что перед слешем в названии репозитория всегда указывается username
аккаунта Docker Hub.
version1
это имя версии приложения собираемого в Docker Image и если загрузить получившийся Docker Image на Docker Hub, то в разделе Tags в репозитории michaelshadrin/simple-spring-boot-app можно будет увидеть Docker Image с названием version1
.

Процесс сборки может быть довольно долгим, так как в процессе сборки скачиваются jdk, maven, зависимости и другое.
Запуск Docker Image.
Давайте запустим получившийся Docker Image. Важно отметить, что перед этим необходимо включить на компьютере приложение Docker Desktop ссылка для скачивания которого давалась ранее.
Образ запускается уже знакомой нам командой — docker container run
, с помощью которой можно запустить любой Docker Image.
Выполним ее для запуска нашего Docker Image:

В команде указывается пара портов -p 8081:8080
. Первый порт – это порт компьютера на котором мы запускаем Docker Image, второй – это порт внутри контейнера, указанный в Dockerfile, на котором работает наше приложение.
Docker-контейнер
можно представить как лёгкую виртуальную машину. У него, как и у обычного компьютера, есть свои порты. Команда -p
пробрасывает порт с компьютера на нужный порт внутри контейнера, чтобы мы могли получить доступ к приложению извне. Подробнее о Docker-контейнере будет ниже.
-d
пишется в команде просто чтобы запущенный Docker Image не был привязан к консоли в которой он запускается. То есть, чтобы мы могли дальше использовать эту консоль после запуска Docker Image.
После указания портов очевидно указывается название репозитория и имя конкретного Docker Image в нем, то есть имя версии.
Итак, Docker Image запущен, а значит и Spring boot приложение в нем тоже. Давайте обратимся к обработчику helloWorld
этого приложения через порт компьютера 8081, который мы указывали в команде запуска Docker Image.

Как видим, обработчик успешно вернул Hello World!!!, что значит, что сборка приложения в Docker Image и запуск этого Docker Image прошли успешно.
Запуск Image. Контейнеры
Работающий, запущенный Docker Image называется контейнером. Запущенных, одновременно работающих докер контейнеров может быть много. Чтобы несколько Docker Image работали одновременно их нужно запускать на разных портах компьютера.
Давайте запустим три контейнера одного и того же Docker Image на порте 8081
, на порте 8082
и на порте 8083
.

И ко всем можно будет иметь доступ через localhost по соответствующему порту.

С помощью команды docker container list
можно просмотреть все работающие контейнеры.

В результате этой команды можно увидеть разную информацию о контейнере, в том числе id запущенного контейнера. С помощью команды docker container stop
можно остановить контейнер по этому id. Не обязательно писать id контейнера полностью, можно написать лишь его первые несколько символов.

Как видим, теперь работают только два контейнера, один мы остановили.
Загрузка Image на Docker Hub
Можно загрузить Docker Image, который мы собрали в Docker Hub. Сделать это можно через консоль посредством команды или через графический интерфейс приложения Docker Desktop. Сделаем это через Docker Desktop.
В приложении в разделе Images можно увидеть Image, который мы собирали. Чтобы загрузить его на Docker Hub достаточно лишь нажать на три точки и выбрать push
. Начнется загрузка.

После загрузки в аккаунте с именем michaelshadrin
(то что указывается до слеша в названии репозитория) должен появиться репозиторий michaelshadrin/simple-spring-boot-app, который будет содержать Image, который загружался.

В Tags этого репозитория видим image с названием version1
.

О пользе Docker
Еще раз о преимуществах докера.
Представим себе ситуацию когда, например, вебсайт создают два человека – фронтенд часть
один человек, а бэкенд часть
другой. Фронтендер написал свою фронтенд часть и хочет протестировать ее как часть полноценного вебсайта. Для этого ему нужна вторая часть вебсайта – бэкенд. Тогда фронтендер может попросить у бэкендера image бэкенда, чтобы запускать этот image у себя на компьютере командой docker container run
для тестирования взаимодействия разработанного фронта с беком. При этом фронтендер не занимаеться муторным развертыванием этого бэкенда у себя на компьютере, он может даже не знать на каком языке бэкендер его написал.
Как видим, докер очень удобен при разработке приложений в команде.
Вообще всё может быть намного круче, приложение может состоять не из двух частей, а из множества микросервисов и каждый из них можно упаковать в отдельный image и всех их запускать одинаковой командой docker container run
.