Команды
docker build . -t my_account_name/awesome-image
Используется для сборки образа. Флаг -t позволяет указать имя образа
docker images
Показывает все собранные образы
docker run -it -p 80:8080 my_account_name/awesome-image
Запускает контейнер. Флаг -p используется для проброса портов: <порт доступный снаружи>:<порт внутри контейнера>
docker push my_account_name/awesome-image
Отправляет образ на dockerhub
docker run -it -p 80:8080 my_account_name/awesome-image bash
А так мы можем запустить образ и подключиться к нему с помощью bash
Dockerfile
# Указываем образ, от которого наследуемся
FROM php:7.4-cli
# Устанавливаем рабочую директорию
WORKDIR /project
# Копируем директорию из основной файловой системы внутрь образа
COPY ./project .
# Определяет действие, которое будет выполнено при старте контейнера (docker run)
# Используется только в случае, если контейнер был запущен без указания команды
# [команда, аргумент]
CMD ["echo", "Hello Hexlet!"]
# Сообщаем, что контейнер использует 8000 порт
EXPOSE 8000
Самостоятельная работа
В этом задании мы познакомимся с Docker и упакуем простое приложение на Spring boot в контейнер.
Установка Docker
- Установите Docker, следуя инструкции для своей операционной системы
Знакомство с приложением
В репозитории находится очень простое Spring boot приложение. Все, что оно делает – это выводит приветствие при запросе к корневой странице. Приложение стартует на порту 8080
- Сделайте форк репозитория и склонируйте его на свой компьютер.
- Изучите код этого приложения, его мы будем упаковывать в контейнер.
Упаковываем приложение в образ
- Создайте Dockerfile, в него добавим команды для упаковки приложения в образ.
При создании своего образа унаследуйтесть от образа eclipse-temurin:24-jdk
. Внутри уже есть установленные jdk24, но нет Gradle. Так как для сборки приложения мы используем Gradle, нужно будет его установить вручную. Как это делается, можно посмотреть в документации. Или просто добавьте код из примера ниже:
Пример команд Dockerfile
# Установим необходимые утилиты и Gradle напрямую
ARG GRADLE_VERSION=8.14
ENV GRADLE_HOME=/opt/gradle
ENV GRADLE_USER_HOME=/gradle-cache
ENV PATH=${GRADLE_HOME}/bin:${PATH}
RUN apt-get update && apt-get install -y curl unzip make && \
curl -fsSL https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip -o gradle.zip && \
unzip gradle.zip -d /opt && \
mv /opt/gradle-${GRADLE_VERSION} ${GRADLE_HOME} && \
rm gradle.zip && \
gradle --version
WORKDIR /app
# Копируем только файлы, связанные с зависимостями, чтобы кэшировать Gradle
COPY build.gradle* settings.gradle* gradle.properties* Makefile ./
# Создаём пустую структуру src для предварительного запуска
RUN mkdir -p src/main/java
# Прогреваем зависимости (без сборки)
RUN gradle build -x test --dry-run || true
# Копируем остальной проект
COPY . .
# Сборка проекта
RUN make build
EXPOSE 8080
CMD ["make", "run"]
Теперь соберите образ при помощи команды:
docker build -t <image_name> .
С помощью флага -t передается имя образа, включая имя аккаунта и тег.
После сборки образа вы сможете увидеть его в списке образов. Выполните команду docker images
и найдите там свой образ.
Итоговый Dockerfile
FROM eclipse-temurin:24-jdk
# Установим необходимые утилиты и Gradle напрямую
ARG GRADLE_VERSION=8.14
ENV GRADLE_HOME=/opt/gradle
ENV GRADLE_USER_HOME=/gradle-cache
ENV PATH=${GRADLE_HOME}/bin:${PATH}
RUN apt-get update && apt-get install -y curl unzip make && \
curl -fsSL https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip -o gradle.zip && \
unzip gradle.zip -d /opt && \
mv /opt/gradle-${GRADLE_VERSION} ${GRADLE_HOME} && \
rm gradle.zip && \
gradle --version
WORKDIR /app
# Копируем только файлы, связанные с зависимостями, чтобы кэшировать Gradle
COPY build.gradle* settings.gradle* gradle.properties* Makefile ./
# Создаём пустую структуру src для предварительного запуска
RUN mkdir -p src/main/java
# Прогреваем зависимости (без сборки)
RUN gradle build -x test --dry-run || true
# Копируем остальной проект
COPY . .
# Сборка проекта
RUN make build
EXPOSE 8080
CMD ["make", "run"]
Запуск контейнера с приложением
Так как порт 8080 может быть занят то, а снаружи контейнера приложение будет доступно на порту 3000, нам нужно. Флаг -p
сопоставит порт 8080 внутри контейнера с портом 3000 на вашем компьютере. Запустите контейнер при помощи команды:
docker run -p 3000:8080 --name hello-world-app <image>
Откройте браузер и загрузите страницу http://localhost:3000. Убедитесь, что все работает. Если все сделано верно, вы увидите приветствие.
Остановите образ при помощи комбинации клавиш Ctrl + C. После этого приложение станет недоступно.
После остановки контейнера, он все еще остается. Так как у него есть фиксированное имя, которое задано флагом --name
, то Docker не даст запустить контейнер под тем же именем.
Удалите контейнер командой
docker rm hello-world-app
Выполнение команд внутри контейнера
Мы также можем запустить образ и подключиться к нему при помощи команды:
docker run -it -p 3000:8080 <image> bash
Запустится bash сессия внутри контейнера. Изучите файловую систему внутри контейнера. Протестируйте наше приложение, запустите тесты при помощи команды make test
. Выйти из контейнера можно при помощи комбинации клавиш
Make-команды
Добавьте в Makefile команды для работы с контейнером. Вам могут пригодиться следующие команды:
- Сборка образа
- Запуск приложения
- Запуск тестов в контейнере
- Запуск сессии bash внутри контейнера
- Остановка и удаление образа
Примеры команд для Makefile
docker-build:
docker build -t java-spring-boot-hello-world .
docker-run:
docker run -p 3000:8080 --name hello-world-app java-spring-boot-hello-world
docker-bash:
docker run --rm -it -p 3000:8080 java-spring-boot-hello-world bash
Дополнительное задание
Соберите минимальный Docker-образ для приложения, которое будет выполняться в Production. Он может состоять из нескольких этапов сборки. Для первого этапа вам потребуется базовый образ gradle
, а для второго - . Первый образ будет выполнять сборку, а во втором запустится jar.
Пример Dockerfile, который может получиться
# Этап сборки
FROM gradle:8.14-jdk24 AS build
WORKDIR /app
COPY --chown=gradle:gradle . .
RUN gradle build -x test --info --console=plain
# Этап выполнения
FROM eclipse-temurin:24-jre
WORKDIR /app
COPY --from=build /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Подсказки
- Пример приложения работающего в Docker
- Не забывайте, что внутри контейнера теперь доступен gradle, который поможет вам собрать и запустить приложение
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.