0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#База знаний</a></p>
1
<p><a>#База знаний</a></p>
2
<ul><li>10 дек 2020</li>
2
<ul><li>10 дек 2020</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Немного разбираемся с теорией и проверяем на практике.</p>
4
</ul><p>Немного разбираемся с теорией и проверяем на практике.</p>
5
<p> vlada_maestro / shutterstock</p>
5
<p> vlada_maestro / shutterstock</p>
6
<p>Разрабатывает приложения на Java, воспитывает двух котов: Котлин и Монго.</p>
6
<p>Разрабатывает приложения на Java, воспитывает двух котов: Котлин и Монго.</p>
7
<p>Эта статья посвящена основам Docker и раскрывает азы работы с контейнерами. Мы изучим базовые определения и самые необходимые команды и даже разработаем и развернём простейшее Java-приложение.</p>
7
<p>Эта статья посвящена основам Docker и раскрывает азы работы с контейнерами. Мы изучим базовые определения и самые необходимые команды и даже разработаем и развернём простейшее Java-приложение.</p>
8
<p>Docker - инструмент, предназначенный для быстрой разработки, доставки и развёртывания приложений. Он позволяет упаковать приложение вместе со всеми его зависимостями в так называемый контейнер, а затем запустить его в любой среде.</p>
8
<p>Docker - инструмент, предназначенный для быстрой разработки, доставки и развёртывания приложений. Он позволяет упаковать приложение вместе со всеми его зависимостями в так называемый контейнер, а затем запустить его в любой среде.</p>
9
<p>Идея контейнеризации состоит в том, что на одной машине может разворачиваться множество таких контейнеров с приложениями. Для каждого из них в операционной системе выделяется изолированная область - осуществляется виртуализация на уровне ОС.</p>
9
<p>Идея контейнеризации состоит в том, что на одной машине может разворачиваться множество таких контейнеров с приложениями. Для каждого из них в операционной системе выделяется изолированная область - осуществляется виртуализация на уровне ОС.</p>
10
<p><strong>Важный момент:</strong>все контейнеры запускаются одинаковым способом вне зависимости от того, что находится внутри. Это напоминает контейнеры для морских перевозок - с виду они одинаковы, но внутри могут храниться совершенно разные грузы.</p>
10
<p><strong>Важный момент:</strong>все контейнеры запускаются одинаковым способом вне зависимости от того, что находится внутри. Это напоминает контейнеры для морских перевозок - с виду они одинаковы, но внутри могут храниться совершенно разные грузы.</p>
11
<p><strong>Преимущества контейнеров:</strong></p>
11
<p><strong>Преимущества контейнеров:</strong></p>
12
<ul><li>приложения получают единый механизм сборки;</li>
12
<ul><li>приложения получают единый механизм сборки;</li>
13
<li>не нужно конфигурировать среду для запуска - она поставляется вместе с приложением;</li>
13
<li>не нужно конфигурировать среду для запуска - она поставляется вместе с приложением;</li>
14
<li>приложения легче масштабировать;</li>
14
<li>приложения легче масштабировать;</li>
15
<li>есть система оркестрации контейнеров, позволяющая ими управлять.</li>
15
<li>есть система оркестрации контейнеров, позволяющая ими управлять.</li>
16
</ul><p><strong>Образ</strong> - некий шаблон, на основе которого создаются контейнеры. Содержит всё необходимое для запуска приложения. Сюда относятся код, системные утилиты, библиотеки, настройки и так далее. Образ можно представить в виде набора слоёв, которые накладываются друг на друга. Каждый последующий добавляет, изменяет или удаляет файлы предыдущего слоя.</p>
16
</ul><p><strong>Образ</strong> - некий шаблон, на основе которого создаются контейнеры. Содержит всё необходимое для запуска приложения. Сюда относятся код, системные утилиты, библиотеки, настройки и так далее. Образ можно представить в виде набора слоёв, которые накладываются друг на друга. Каждый последующий добавляет, изменяет или удаляет файлы предыдущего слоя.</p>
17
<p><strong>DockerfIle</strong> - текстовый файл с набором инструкций по созданию образа, каждая из которых добавляет к образу новый слой.</p>
17
<p><strong>DockerfIle</strong> - текстовый файл с набором инструкций по созданию образа, каждая из которых добавляет к образу новый слой.</p>
18
<p><strong>Контейнер</strong> - конкретный экземпляр приложения, созданный на основе образа. Причём из одного образа можно создать сколько угодно контейнеров. Технически контейнер создаётся путём добавления к образу нового слоя, содержащего результаты работы приложения.</p>
18
<p><strong>Контейнер</strong> - конкретный экземпляр приложения, созданный на основе образа. Причём из одного образа можно создать сколько угодно контейнеров. Технически контейнер создаётся путём добавления к образу нового слоя, содержащего результаты работы приложения.</p>
19
<p><strong>Реестр</strong> - хранилище образов (как GitHub для кода приложений). Образы можно скачивать из реестра и создавать на их основе контейнеры. Также в реестр можно загружать новые или изменённые образы для дальнейшего использования.</p>
19
<p><strong>Реестр</strong> - хранилище образов (как GitHub для кода приложений). Образы можно скачивать из реестра и создавать на их основе контейнеры. Также в реестр можно загружать новые или изменённые образы для дальнейшего использования.</p>
20
<p>Давайте разработаем простое Spring Boot приложение, создадим на его основе образ и развернём контейнер на локальной машине. Это делается в три простых шага:</p>
20
<p>Давайте разработаем простое Spring Boot приложение, создадим на его основе образ и развернём контейнер на локальной машине. Это делается в три простых шага:</p>
21
<ol><li>Устанавливаем Docker. Все инструкции можно найти на <a>официальном сайте</a>.</li>
21
<ol><li>Устанавливаем Docker. Все инструкции можно найти на <a>официальном сайте</a>.</li>
22
<li>Генерируем проект с помощью конструктора<a>Spring</a>. Задаём spring-docker-simple в полях Artifact и Name.</li>
22
<li>Генерируем проект с помощью конструктора<a>Spring</a>. Задаём spring-docker-simple в полях Artifact и Name.</li>
23
<li>Выбираем одну зависимость - Spring Web. Готово! Скачиваем и распаковываем архив, открываем его в среде разработки.</li>
23
<li>Выбираем одну зависимость - Spring Web. Готово! Скачиваем и распаковываем архив, открываем его в среде разработки.</li>
24
</ol><p>В открывшемся проекте рядом с главным классом, содержащим метод main, создаём ещё один класс - контроллер с методом hello ().</p>
24
</ol><p>В открывшемся проекте рядом с главным классом, содержащим метод main, создаём ещё один класс - контроллер с методом hello ().</p>
25
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloDockerController { @GetMapping("/") public String hello() { return "Hello Docker!"; } }<p>Класс помечен аннотацией @RestController, означающей, что он предназначен для обработки web-запросов. А метод помечен аннотацией @GetMapping c адресом "/" - перейдя по нему (выполнив get-запрос к http://localhost:8080/), мы получим сообщение "Hello Docker!"</p>
25
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloDockerController { @GetMapping("/") public String hello() { return "Hello Docker!"; } }<p>Класс помечен аннотацией @RestController, означающей, что он предназначен для обработки web-запросов. А метод помечен аннотацией @GetMapping c адресом "/" - перейдя по нему (выполнив get-запрос к http://localhost:8080/), мы получим сообщение "Hello Docker!"</p>
26
<p>Теперь открываем терминал и вводим команду:</p>
26
<p>Теперь открываем терминал и вводим команду:</p>
27
./mvnw package && java -jar target/spring-docker-simple-0.0.1-SNAPSHOT.jar<p>Она упакует приложение в jar-файл и запустит его. Чтобы убедиться в корректности работы приложения - перейдём на http://localhost:8080/ в браузере и увидим заветное сообщение.</p>
27
./mvnw package && java -jar target/spring-docker-simple-0.0.1-SNAPSHOT.jar<p>Она упакует приложение в jar-файл и запустит его. Чтобы убедиться в корректности работы приложения - перейдём на http://localhost:8080/ в браузере и увидим заветное сообщение.</p>
28
<p>Теперь создаём файл с именем Dockerfile в корне проекта, который содержит инструкции для сборки образа со следующим текстом:</p>
28
<p>Теперь создаём файл с именем Dockerfile в корне проекта, который содержит инструкции для сборки образа со следующим текстом:</p>
29
FROM adoptopenjdk/openjdk11:alpine-jre ARG JAR_FILE=target/spring-docker-simple-0.0.1-SNAPSHOT.jar WORKDIR /opt/app COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","app.jar"]<p>Вот что происходит, когда мы вводим этот код:</p>
29
FROM adoptopenjdk/openjdk11:alpine-jre ARG JAR_FILE=target/spring-docker-simple-0.0.1-SNAPSHOT.jar WORKDIR /opt/app COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","app.jar"]<p>Вот что происходит, когда мы вводим этот код:</p>
30
КомандаОписаниеFROM adoptopenjdk/openjdk11:alpine-jreOбраз создаётся на основе<a>alpine linux</a>с установленной openjdk11ARG JAR_FILE=target/spring-docker-simple-0.0.1-SNAPSHOT.jarПеременной JAR_FILE присваивается путь к jar- архивуWORKDIR /opt/appНазначаем рабочую директорию, в которой будут выполняться дальнейшие команды (перемещаемся в папку app)COPY ${JAR_FILE} app.jarНаш jar-файл, указанный в JAR_FILE, копируется в папку app, и копии задаётся имя app.jarENTRYPOINT [“java","-jar","app.jar"]jar-файл запускается, собирается команда java -jar app.jar из заданной рабочей директории<p>После этого в терминале вводим команду, с помощью которой собираем образ и запускаем контейнер.</p>
30
КомандаОписаниеFROM adoptopenjdk/openjdk11:alpine-jreOбраз создаётся на основе<a>alpine linux</a>с установленной openjdk11ARG JAR_FILE=target/spring-docker-simple-0.0.1-SNAPSHOT.jarПеременной JAR_FILE присваивается путь к jar- архивуWORKDIR /opt/appНазначаем рабочую директорию, в которой будут выполняться дальнейшие команды (перемещаемся в папку app)COPY ${JAR_FILE} app.jarНаш jar-файл, указанный в JAR_FILE, копируется в папку app, и копии задаётся имя app.jarENTRYPOINT [“java","-jar","app.jar"]jar-файл запускается, собирается команда java -jar app.jar из заданной рабочей директории<p>После этого в терминале вводим команду, с помощью которой собираем образ и запускаем контейнер.</p>
31
docker build -t spring-docker-simple:0.0.1 .<p>Точка в конце важна, она указывает на расположение Dockerfile (символ "точка" означает текущую директорию. Проверьте, что образ создан командой docker images. Вывод должен быть таким:</p>
31
docker build -t spring-docker-simple:0.0.1 .<p>Точка в конце важна, она указывает на расположение Dockerfile (символ "точка" означает текущую директорию. Проверьте, что образ создан командой docker images. Вывод должен быть таким:</p>
32
<p>Запускаем контейнер командой:</p>
32
<p>Запускаем контейнер командой:</p>
33
docker run -d -p 8080:8080 -t spring-docker-simple:0.0.1<p>Опция -d означает старт процесса в фоновом режиме. Опция -p тоже важна - дело в том, что контейнер собирается в полностью изолированном окружении. Тот факт, что приложение внутри контейнера запущено на порту 8080, не означает, что оно доступно вне контейнера на этом порту.</p>
33
docker run -d -p 8080:8080 -t spring-docker-simple:0.0.1<p>Опция -d означает старт процесса в фоновом режиме. Опция -p тоже важна - дело в том, что контейнер собирается в полностью изолированном окружении. Тот факт, что приложение внутри контейнера запущено на порту 8080, не означает, что оно доступно вне контейнера на этом порту.</p>
34
<p>Требуется явно указать, что порту 8080 в контейнере (здесь второе значение - это порт, на котором работает наше приложение в контейнере) соответствует порт 8080 на локальной машине, который будет использоваться при обращении к контейнеру. Поэтому пишем через двоеточие -p 8080:8080.</p>
34
<p>Требуется явно указать, что порту 8080 в контейнере (здесь второе значение - это порт, на котором работает наше приложение в контейнере) соответствует порт 8080 на локальной машине, который будет использоваться при обращении к контейнеру. Поэтому пишем через двоеточие -p 8080:8080.</p>
35
<p>Теперь введём в терминале команду:</p>
35
<p>Теперь введём в терминале команду:</p>
36
curl http://localhost:8080<p>Так проверяется работоспособность запущенного контейнера. Есть и альтернативный вариант: можно просто перейти по этому адресу в браузере. Если всё работает как надо, задача выполнена - нам удалось упаковать Spring Boot приложение в контейнер.</p>
36
curl http://localhost:8080<p>Так проверяется работоспособность запущенного контейнера. Есть и альтернативный вариант: можно просто перейти по этому адресу в браузере. Если всё работает как надо, задача выполнена - нам удалось упаковать Spring Boot приложение в контейнер.</p>
37
<p>docker ps - выводит список запущенных контейнеров. Также ей можно передать параметр -a, чтобы вывести все контейнеры, а не только запущенные.</p>
37
<p>docker ps - выводит список запущенных контейнеров. Также ей можно передать параметр -a, чтобы вывести все контейнеры, а не только запущенные.</p>
38
<p>docker build - собирает образ Docker из Dockerfile и набора файлов, расположенных по определённому пути.</p>
38
<p>docker build - собирает образ Docker из Dockerfile и набора файлов, расположенных по определённому пути.</p>
39
<p>Параметр -t используется, чтобы задать имя образа, последний параметр. - наименование каталога (в нашем случае текущий каталог).</p>
39
<p>Параметр -t используется, чтобы задать имя образа, последний параметр. - наименование каталога (в нашем случае текущий каталог).</p>
40
<p>docker images - выводит список образов в вашей системе.</p>
40
<p>docker images - выводит список образов в вашей системе.</p>
41
<p>docker logs - позволяет вывести на консоль логи указанного контейнера. Для этого необходимо указать имя или id контейнера. Можно использовать флаг --follow, чтобы следить за логами работающего контейнера: например, docker logs --follow c5ecc88de8f9.</p>
41
<p>docker logs - позволяет вывести на консоль логи указанного контейнера. Для этого необходимо указать имя или id контейнера. Можно использовать флаг --follow, чтобы следить за логами работающего контейнера: например, docker logs --follow c5ecc88de8f9.</p>
42
<p>docker run - запускает контейнер на основе указанного образа.</p>
42
<p>docker run - запускает контейнер на основе указанного образа.</p>
43
<p>docker stop - останавливает контейнер. Можно передать опцию $(docker ps -a -q) для остановки всех запущенных контейнеров.</p>
43
<p>docker stop - останавливает контейнер. Можно передать опцию $(docker ps -a -q) для остановки всех запущенных контейнеров.</p>
44
<p>docker rm и docker rmi - команды, удаляющие контейнер и образ соответственно.</p>
44
<p>docker rm и docker rmi - команды, удаляющие контейнер и образ соответственно.</p>
45
<p>Удалить все контейнеры:</p>
45
<p>Удалить все контейнеры:</p>
46
<p>В этом руководстве мы попробовали самостоятельно работать с Docker. Для этого создали простой Spring проект с одной конечной точкой REST и собрали для него образ Docker. В результате научились запускать образ Docker внутри контейнера и протестировали конечную точку REST внутри этого образа.</p>
46
<p>В этом руководстве мы попробовали самостоятельно работать с Docker. Для этого создали простой Spring проект с одной конечной точкой REST и собрали для него образ Docker. В результате научились запускать образ Docker внутри контейнера и протестировали конечную точку REST внутри этого образа.</p>
47
<p>Docker - удобный инструмент, который значительно ускоряет рабочий процесс. Чтобы узнать о нём больше и получить наиболее полное представление, рекомендую читать<a>официальную документацию</a>.</p>
47
<p>Docker - удобный инструмент, который значительно ускоряет рабочий процесс. Чтобы узнать о нём больше и получить наиболее полное представление, рекомендую читать<a>официальную документацию</a>.</p>
48
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
48
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>