Профессиональная оптимизация Docker image с приложением на JAVA
Как ещё оптимизировать размер образа?
Есть вариант, он более сложный, но однозначно стоит его рассмотреть.
Вообще во всём виновата JDK/JRE - Виртуальная машина Java.
Именно она прибавляет значительную часть веса нашему образу с приложением...
Мы можем собрать JRE специально под наше приложение, чтобы урезать её, заточить специально под определенное приложение.
Тем самым уменьшим её размер.
Такую махинацию можно провернуть благодаря утилиты jlink
и ещё одну оптимизацию проведём, распакуем jar архив на слои:
Получим 4 папки:
Для чего мы распаковали JAR?
Чаше всего, от версии к версии приложения меняется только бизнес-логика..
Версии библиотек меняются редко.
Мы можем разбить jar и тот слой, что не поменялся, будет от версии к версии браться из кеша. Вот для этого мы и разбиваем jar.
Есть принцип оптимизации docker image:
И перейдем к итоговому файлу:
Такой вариант уменьшил размер образа на 38 МБ.
Итого image = 174 МБ
Но тут ещё, мы улучшили секьюрность , так как создали специального пользователя для запуска приложения, а не под root работаем...
Все эти файлы с примерами кода есть в репе https://github.com/TwoZeros/simple-todo
Пробуйте, экспериментируйте и ещё можете почитать вот эту статью
Как ещё оптимизировать размер образа?
Есть вариант, он более сложный, но однозначно стоит его рассмотреть.
Вообще во всём виновата JDK/JRE - Виртуальная машина Java.
Именно она прибавляет значительную часть веса нашему образу с приложением...
Мы можем собрать JRE специально под наше приложение, чтобы урезать её, заточить специально под определенное приложение.
Тем самым уменьшим её размер.
Такую махинацию можно провернуть благодаря утилиты jlink
$JAVA_HOME/bin/jlink \
--add-modules `jdeps --ignore-missing-deps -q -recursive --multi-release ${RELEASE} --print-module-deps -cp 'dependencies/BOOT-INF/lib/*':'snapshot-dependencies/BOOT-INF/lib/*' application.jar` \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=2 \
--output jdk
и ещё одну оптимизацию проведём, распакуем jar архив на слои:
java -Djarmode=layertools -jar ../target/*.jar extract
Получим 4 папки:
application. Здесь лежит код (бизнес-логика).
snapshot-dependencies. Здесь лежат snapshot зависимости.
spring-boot-loader. Здесь лежат запускаторы спринга.
dependencies. Здесь лежат релизные зависимости.
Для чего мы распаковали JAR?
Чаше всего, от версии к версии приложения меняется только бизнес-логика..
Версии библиотек меняются редко.
Мы можем разбить jar и тот слой, что не поменялся, будет от версии к версии браться из кеша. Вот для этого мы и разбиваем jar.
Есть принцип оптимизации docker image:
Всё что меняется наиболее часто должно идти в самом конце
И перейдем к итоговому файлу:
FROM maven:3.9.4-eclipse-temurin-17 AS maven
# Собирать проект будем в /build
WORKDIR /build
COPY ./repository ./repository
COPY ./service ./service
COPY ./views ./views
COPY pom.xml pom.xml
RUN --mount=type=cache,target=/root/.m2 mvn clean package
FROM eclipse-temurin:17 AS app-build
ENV RELEASE=17
WORKDIR /opt/build
COPY --from=maven /build/views/target/*.jar ./application.jar
RUN java -Djarmode=layertools -jar application.jar extract
RUN $JAVA_HOME/bin/jlink \
--add-modules `jdeps --ignore-missing-deps -q -recursive --multi-release ${RELEASE} --print-module-deps -cp 'dependencies/BOOT-INF/lib/*':'snapshot-dependencies/BOOT-INF/lib/*' application.jar` \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=2 \
--output jdk
FROM debian:buster-slim
ARG BUILD_PATH=/opt/build
ENV JAVA_HOME=/opt/jdk
ENV PATH="${JAVA_HOME}/bin:${PATH}"
RUN groupadd --gid 1000 spring-app \
&& useradd --uid 1000 --gid spring-app --shell /bin/bash --create-home spring-app
USER spring-app:spring-app
WORKDIR /opt/workspace
COPY --from=app-build $BUILD_PATH/jdk $JAVA_HOME
COPY --from=app-build $BUILD_PATH/spring-boot-loader/ ./
COPY --from=app-build $BUILD_PATH/dependencies/ ./
COPY --from=app-build $BUILD_PATH/snapshot-dependencies/ ./
COPY --from=app-build $BUILD_PATH/application/ ./
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
Такой вариант уменьшил размер образа на 38 МБ.
Итого image = 174 МБ
Но тут ещё, мы улучшили секьюрность , так как создали специального пользователя для запуска приложения, а не под root работаем...
Все эти файлы с примерами кода есть в репе https://github.com/TwoZeros/simple-todo
Пробуйте, экспериментируйте и ещё можете почитать вот эту статью
GitHub
GitHub - TwoZeros/simple-todo
Contribute to TwoZeros/simple-todo development by creating an account on GitHub.
👍3❤2
Не будь лузером - используй USER в Dockerfile
Команда USER в Dockerfile – это основополагающий инструмент, определяющий, под каким пользователем будут выполняться команды как в процессе сборки образа, так и при запуске контейнера. По умолчанию, если USER не указан, Docker будет выполнять команды от имени пользователя root, что может представлять серьезную угрозу безопасности.
Практика
Cоздадим Dockerfile со следующим содержимым:
Далее соберём контейнер:
И запустим его:
Попробуем выполнить следующее внутри контейнера:
И закономерно получим ошибку "Доступ запрещён", так как созданный нами пользователь не имеет root доступа.
Как собирать образ без root?
Eсли вам нужно установить какой-то доп софт в контейнере, сделать что-то, где нужны привилегии супер пользователя, то конечно нужен root, но как всё необходимое под root сделаете - переключайтесь на другого обычного пользака
P.s будет просто идеально если такого пользака нет на вашей основной ОС, где запущен docker
Почему это важно?
По умолчанию контейнеры Docker работают с UID 0 или root.
Процессы докера запускаются и работают в хостовой ОС.
Если Docker-контейнер будет скомпрометирован, в лучшем случае злоумышленник получит полный доступ к ресурсам хоста, выделенным для этого контейнера и запустит какие-то команды, свои скрипты в этом контейнере... В самом плохом случае, сможет получить доступ к ресурсам хостовой ОС, то есть выйти за пределы контейнера, хотя этот кейс проблематичен так как есть механизм управления привилегиями, который это запрещает по умолчанию.. Нам остаётся только наедятся, что он идеален и в нём нет никаких дыр..
Но можно запустить контейнер с флагом --privileged и контейнер получит полный доступ к ресурсу хоста, тут и хакером быть не нужно, чтоб натворить всяких дел, поэтому старайтесь не запускать контейнеры с этим флагом...
Вообще, это только 30% инфы на тему тему,продолжение в моём платном телеграмм канале, где вся база как стать успешным.
Рекомендую почитать эту статью чтобы узнать больше:
https://www.docker.com/blog/understanding-the-docker-user-instruction/
Мой факап на тему безопасности Docker
Когда я только начал изучать докер и мне попалась на глаза зарубежная статья, где контейнер запускался с флагом --privileged, я подумал ВАУ, это определенно что-то не обычное...
Я побежал запускать контейнер с этим флагом, я думал это способ респектнуть запускаемый контейнер, сообщить докеру, что он важен для меня...docker demon будет всячески оберегать его и не будет допускать reload..😂
Я очень расстроился, когда не увидел никакой разницы...Docker не написал, что как-то особо позаботится о нём..
Я пошел разбираться, что значит --privileged и был шокирован, что это вообще про другое..
Надо читать документацию, а не включать интуицию😁
Команда USER в Dockerfile – это основополагающий инструмент, определяющий, под каким пользователем будут выполняться команды как в процессе сборки образа, так и при запуске контейнера. По умолчанию, если USER не указан, Docker будет выполнять команды от имени пользователя root, что может представлять серьезную угрозу безопасности.
Практика
Cоздадим Dockerfile со следующим содержимым:
FROM ubuntu:20.04
#Задаём переменные для сборки образа
ARG USER_NAME=noob \
USER_GROUP=noob
# Создаём пользователя
RUN groupadd -g 1234 ${USER_GROUP} && \
useradd -m -u 1234 -g ${USER_GROUP} ${USER_NAME}
#Переключаемся на созданного пользователя
USER ${USER_NAME}
# Устанавливаем рабочую директорию
WORKDIR /home/${USER_NAME}
CMD sh -c "echo 'Внутри контейнера:' && echo 'Пользователь: $(whoami) UID: $(id -u) GID: $(id -g)'"
Далее соберём контейнер:
docker build -t ubuntu-t .
И запустим его:
docker run --rm -it ubuntu-t /bin/bash
Попробуем выполнить следующее внутри контейнера:
apt-get update
И закономерно получим ошибку "Доступ запрещён", так как созданный нами пользователь не имеет root доступа.
Как собирать образ без root?
Eсли вам нужно установить какой-то доп софт в контейнере, сделать что-то, где нужны привилегии супер пользователя, то конечно нужен root, но как всё необходимое под root сделаете - переключайтесь на другого обычного пользака
#Переключаемся на созданного пользователя
USER ${USER_NAME}
P.s будет просто идеально если такого пользака нет на вашей основной ОС, где запущен docker
Почему это важно?
По умолчанию контейнеры Docker работают с UID 0 или root.
Процессы докера запускаются и работают в хостовой ОС.
Если Docker-контейнер будет скомпрометирован, в лучшем случае злоумышленник получит полный доступ к ресурсам хоста, выделенным для этого контейнера и запустит какие-то команды, свои скрипты в этом контейнере... В самом плохом случае, сможет получить доступ к ресурсам хостовой ОС, то есть выйти за пределы контейнера, хотя этот кейс проблематичен так как есть механизм управления привилегиями, который это запрещает по умолчанию.. Нам остаётся только наедятся, что он идеален и в нём нет никаких дыр..
Но можно запустить контейнер с флагом --privileged и контейнер получит полный доступ к ресурсу хоста, тут и хакером быть не нужно, чтоб натворить всяких дел, поэтому старайтесь не запускать контейнеры с этим флагом...
Вообще, это только 30% инфы на тему тему,
Рекомендую почитать эту статью чтобы узнать больше:
https://www.docker.com/blog/understanding-the-docker-user-instruction/
Мой факап на тему безопасности Docker
Когда я только начал изучать докер и мне попалась на глаза зарубежная статья, где контейнер запускался с флагом --privileged, я подумал ВАУ, это определенно что-то не обычное...
Я побежал запускать контейнер с этим флагом, я думал это способ респектнуть запускаемый контейнер, сообщить докеру, что он важен для меня...docker demon будет всячески оберегать его и не будет допускать reload..😂
Я очень расстроился, когда не увидел никакой разницы...Docker не написал, что как-то особо позаботится о нём..
Я пошел разбираться, что значит --privileged и был шокирован, что это вообще про другое..
Надо читать документацию, а не включать интуицию😁
Docker Documentation
Running containers
Running and configuring containers with the Docker CLI
❤4👍4👌2
Быстрая установка Docker и немного про Rootless
Установить Docker можно запустив bash скрипт.
Установка максимально простая и мне лично этот способ уже успел понравится.
1.Скачиваем скрипт
2. Выводим содержимое скрипта на экран, смотрим на то, что мы собственно скачали
3. Запускаем скрпит с --dry-run чтобы проверить шаги которые будут выполнены
4. Запускаем скрипт уставки под root или с sudo
Автоматом получим последнюю свежую версию,
С документацией и самим скриптом можно ознакомится перейдя по ссылке https://get.docker.com
Про Docker Rootless слышали?
Docker можно использовать в режиме Rootless - это когда вам не нужен root (sudo) для работы с Docker.
Установка отличается от обычной, но не сказал бы что это сложно.
Это появилось в Docker 4 года назад, но узнал я об этом способе работы совсем недавно, когда основательно начал изучать возможности Docker. Кажется, что это не сильно распространено, об этом не рассказывают в видео "Docker за 20 минут"
Плюсы Docker в Rootless:
1) Перове и самое главное - безопасность. Вы можете случайно или преднамеренно запустить контейнер в привилегированном режиме , но из контейнера никак не сможете навредить основной ОС, так как процесс запущен от обычного user без root, а этот user без root мало на что способен...
2) Если у вас VDS/VPS и вы хотите кому-то из друзей, стажеров, студентов, итд итп дать возможность использовать ресурсы вашего сервера, чтоб он смог поднимать контейнеры в Docker... настраиваем Docker c Rootless и спим спокойно, так как такому пользаку root доступ к серверу можно уже не давать.
3) удобство не нужно постоянно переключатся между root и обычным пользователем...
Ссылка на доку: https://docs.docker.com/engine/security/rootless/
А вы работали с Docker в режиме Rootless?
Установить Docker можно запустив bash скрипт.
Установка максимально простая и мне лично этот способ уже успел понравится.
1.Скачиваем скрипт
curl -fsSL https://get.docker.com -o install-docker.sh
2. Выводим содержимое скрипта на экран, смотрим на то, что мы собственно скачали
cat install-docker.sh
3. Запускаем скрпит с --dry-run чтобы проверить шаги которые будут выполнены
sh install-docker.sh --dry-run
4. Запускаем скрипт уставки под root или с sudo
sudo sh install-docker.sh
Автоматом получим последнюю свежую версию,
С документацией и самим скриптом можно ознакомится перейдя по ссылке https://get.docker.com
Про Docker Rootless слышали?
Docker можно использовать в режиме Rootless - это когда вам не нужен root (sudo) для работы с Docker.
Установка отличается от обычной, но не сказал бы что это сложно.
Это появилось в Docker 4 года назад, но узнал я об этом способе работы совсем недавно, когда основательно начал изучать возможности Docker. Кажется, что это не сильно распространено, об этом не рассказывают в видео "Docker за 20 минут"
Плюсы Docker в Rootless:
1) Перове и самое главное - безопасность. Вы можете случайно или преднамеренно запустить контейнер в привилегированном режиме , но из контейнера никак не сможете навредить основной ОС, так как процесс запущен от обычного user без root, а этот user без root мало на что способен...
2) Если у вас VDS/VPS и вы хотите кому-то из друзей, стажеров, студентов, итд итп дать возможность использовать ресурсы вашего сервера, чтоб он смог поднимать контейнеры в Docker... настраиваем Docker c Rootless и спим спокойно, так как такому пользаку root доступ к серверу можно уже не давать.
3) удобство не нужно постоянно переключатся между root и обычным пользователем...
Ссылка на доку: https://docs.docker.com/engine/security/rootless/
А вы работали с Docker в режиме Rootless?
Docker Documentation
Rootless mode
Run the Docker daemon as a non-root user (Rootless mode)
👍3
Attation мидлы, сеньоры и сеньориты!
Начинает холодать, уже и в Сочи чувствуется наступление осени.
Летом легко корректировать поддерживать свой вес, что не скажешь про осень и зиму..
Мы айтишники не медведи, сейчас этап, когда нужно поднять приоритет задачи по поддержанию собственной физухи.
Может запустим челендж на спортивную тематику или вы меня пригласите в какой-то? Я открыт к идеям, пишите их в комменты🙏
Пока, у меня план такой: поставить цель по SMART насчёт физухи и вести дневник тренировок. Может сделаю это прям тут, просто какой-то отдельный топик создам или спец приложение найду...
Развитие в разработке и в IT - невозможно без поддержки веса и здорового образа жизни 🤝
Начинает холодать, уже и в Сочи чувствуется наступление осени.
Летом легко корректировать поддерживать свой вес, что не скажешь про осень и зиму..
Мы айтишники не медведи, сейчас этап, когда нужно поднять приоритет задачи по поддержанию собственной физухи.
Может запустим челендж на спортивную тематику или вы меня пригласите в какой-то? Я открыт к идеям, пишите их в комменты🙏
Пока, у меня план такой: поставить цель по SMART насчёт физухи и вести дневник тренировок. Может сделаю это прям тут, просто какой-то отдельный топик создам или спец приложение найду...
Развитие в разработке и в IT - невозможно без поддержки веса и здорового образа жизни 🤝
🔥5⚡3🫡2👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Сеньоры разбирают 10 летний монолит
😁11
Forwarded from СБЕР IT Сочи
Приложение за один вечер: обзор фреймворка Jmix
Привет, меня зовут Кирилл Пахтусов, я backend-разработчик в IT-офисе Сбера. Недавно я столкнулся с вызовом: разработать приложение для коллег в сжатые сроки.
🔘 Предыстория
В нашем офисе есть программа лояльности, которая позволяет сотрудникам получать повышенные скидки и бонусы в различных заведениях города. Однако не хватает платформы, где были бы собраны все заведения-партнеры. Когда я начал работать над созданием этой платформы, мой товарищ порекомендовал Jmix. Я решил попробовать и остался доволен результатом, поэтому хочу поделиться своим обзором на фреймворк. Возможно, это облегчит жизнь кому-то из вас или замотивирует попробовать новый инструмент.
🔘 Что это за зверь такой – Jmix?
Jmix — это фреймворк для быстрой разработки веб-приложений. В его основе лежит Spring Boot, который считается стандартом для создания корпоративных веб-приложений на Java. Это дополняет функциональность фреймворка и позволяет разработчикам легко использовать множество сторонних библиотек и фреймворков с минимальной настройкой.
📑 Основные преимущества Jmix, которые я для себя выделил:
🔘 Full-Stack решение
С Jmix один разработчик может создать полноценное веб-приложение, включая бэкенд и фронтенд, без необходимости использовать JavaScript. То есть можно создать как серверную часть, так и пользовательский интерфейс.
🔘 Быстрая разработка
Фреймворк предлагает множество готовых компонентов и инструментов, которые ускоряют процесс разработки. Например, есть встроенные визуальные компоненты для фильтрации данных, с помощью которых можно быстро реализовать функциональность. При этом писать код с нуля не нужно. Благодаря этому время, затрачиваемое на рутинные задачи, значительно сокращается.
🔘 Удобный UI-фреймворк
Jmix использует Vaadin для создания веб-интерфейсов, что позволяет разрабатывать современные и интерактивные пользовательские интерфейсы. Декларативная верстка упрощает проектирование интерфейсов, а богатая библиотека компонентов обеспечивает необходимую функциональность.
🔘 Интуитивно понятный интерфейс и туториалы
Инструменты Jmix Studio интегрированы в IDE IntelliJ IDEA, что делает процесс разработки более удобным благодаря визуальным подсказкам и возможностям отладки кода. Также на сайте Jmix есть туториалы, которые помогают изучить фреймворк.
🔘 Открытый исходный код
Jmix является open-source проектом, что делает его доступным решением для стартапов, малых бизнесов и фрилансеров. Есть и платная подписка, но она нужна только если вам необходим расширенный функционал. Об этом я расскажу далее.
🔘 Подводные камни
При разработке приложения с программой лояльности мне нужно было внедрить модуль карты с геолокацией. Он доступен только в платной версии за 8 тысяч рублей. В итоге я решил использовать Jmix как админку и API для бэкенда, а фронтенд реализовать на React.
🔘 Итоги
Если вы ищете фреймворк, который ускорит процесс разработки и упрощает работу с данными, Jmix — это подходящее решение. И если к вам вдруг обратился знакомый и попросил сделать приложение быстро и недорого, вам однозначно стоит обратить внимание на Jmix.
Привет, меня зовут Кирилл Пахтусов, я backend-разработчик в IT-офисе Сбера. Недавно я столкнулся с вызовом: разработать приложение для коллег в сжатые сроки.
🔘 Предыстория
В нашем офисе есть программа лояльности, которая позволяет сотрудникам получать повышенные скидки и бонусы в различных заведениях города. Однако не хватает платформы, где были бы собраны все заведения-партнеры. Когда я начал работать над созданием этой платформы, мой товарищ порекомендовал Jmix. Я решил попробовать и остался доволен результатом, поэтому хочу поделиться своим обзором на фреймворк. Возможно, это облегчит жизнь кому-то из вас или замотивирует попробовать новый инструмент.
🔘 Что это за зверь такой – Jmix?
Jmix — это фреймворк для быстрой разработки веб-приложений. В его основе лежит Spring Boot, который считается стандартом для создания корпоративных веб-приложений на Java. Это дополняет функциональность фреймворка и позволяет разработчикам легко использовать множество сторонних библиотек и фреймворков с минимальной настройкой.
📑 Основные преимущества Jmix, которые я для себя выделил:
С Jmix один разработчик может создать полноценное веб-приложение, включая бэкенд и фронтенд, без необходимости использовать JavaScript. То есть можно создать как серверную часть, так и пользовательский интерфейс.
Фреймворк предлагает множество готовых компонентов и инструментов, которые ускоряют процесс разработки. Например, есть встроенные визуальные компоненты для фильтрации данных, с помощью которых можно быстро реализовать функциональность. При этом писать код с нуля не нужно. Благодаря этому время, затрачиваемое на рутинные задачи, значительно сокращается.
Jmix использует Vaadin для создания веб-интерфейсов, что позволяет разрабатывать современные и интерактивные пользовательские интерфейсы. Декларативная верстка упрощает проектирование интерфейсов, а богатая библиотека компонентов обеспечивает необходимую функциональность.
Инструменты Jmix Studio интегрированы в IDE IntelliJ IDEA, что делает процесс разработки более удобным благодаря визуальным подсказкам и возможностям отладки кода. Также на сайте Jmix есть туториалы, которые помогают изучить фреймворк.
Jmix является open-source проектом, что делает его доступным решением для стартапов, малых бизнесов и фрилансеров. Есть и платная подписка, но она нужна только если вам необходим расширенный функционал. Об этом я расскажу далее.
🔘 Подводные камни
При разработке приложения с программой лояльности мне нужно было внедрить модуль карты с геолокацией. Он доступен только в платной версии за 8 тысяч рублей. В итоге я решил использовать Jmix как админку и API для бэкенда, а фронтенд реализовать на React.
🔘 Итоги
Если вы ищете фреймворк, который ускорит процесс разработки и упрощает работу с данными, Jmix — это подходящее решение. И если к вам вдруг обратился знакомый и попросил сделать приложение быстро и недорого, вам однозначно стоит обратить внимание на Jmix.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍3
Что по спорту?
По-прежнему хожу на Sber Street Workout ( Внутреннее название "Тренировки с Олегом") 😁
Уже очень сильно к этой активности, отношусь к этому как к обычному утрениму дейлику, приятно удивлен, что они стали более массовыми.🔥
Ещё на работу стал ездить на лонгборде, это возможно благодаря душу в офисе, если у вас нет душа в офисе и до работы вам 5км, то не рекомендую повторять это😂
По-прежнему хожу на Sber Street Workout ( Внутреннее название "Тренировки с Олегом") 😁
Уже очень сильно к этой активности, отношусь к этому как к обычному утрениму дейлику, приятно удивлен, что они стали более массовыми.🔥
Ещё на работу стал ездить на лонгборде, это возможно благодаря душу в офисе, если у вас нет душа в офисе и до работы вам 5км, то не рекомендую повторять это😂
🔥7
Люблю фильмы ужасов, поэтому очень понравился пост, захотелось поделиться😁
Forwarded from СБЕР IT Сочи
Злодеи с экранов: как бы сложилась их карьера в IT? 👻
В преддверии Хеллоуина мы решили пересмотреть культовые хорроры и представить, кем могли бы работать антагонисты этих фильмов, а также какие их навыки могли бы пригодиться в IT💡
В карточках рассуждаем, почему Джон Крамер мог бы стать классным комьюнити-менеджером и какие скиллы пригодились бы Фредди Крюгеру на позиции дата-сайентиста 🎃
В преддверии Хеллоуина мы решили пересмотреть культовые хорроры и представить, кем могли бы работать антагонисты этих фильмов, а также какие их навыки могли бы пригодиться в IT
В карточках рассуждаем, почему Джон Крамер мог бы стать классным комьюнити-менеджером и какие скиллы пригодились бы Фредди Крюгеру на позиции дата-сайентиста 🎃
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4❤🔥2👻2