HTML Diff
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 &amp;&amp; java -jar target/spring-docker-simple-0.0.1-SNAPSHOT.jar<p>Она упакует приложение в jar-файл и запустит его. Чтобы убедиться в корректности работы приложения - перейдём на http://localhost:8080/ в браузере и увидим заветное сообщение.</p>
27 ./mvnw package &amp;&amp; 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>