Недавно, создавая приложение для своих статей, я столкнулся со времязатратной проблемой. Локальная среда работала идеально, но, стоило упаковать Java-приложение в контейнер и запустить его, как случился сбой аутентификации. Думаю, многим знакома такая ситуация.
Усугублялась она невозможностью воссоздать проблему в локальных сеансах отладки. Добавить случайные логгеры для отслеживания ошибки тоже было не вариант, так как из API возвращалась ошибка «401» и служба не вызывалась. Да и пытаться исправлять ошибки и постоянно пересобирать образы Docker — особенно большие — очень времязатратно. Это все равно что наблюдать за высыханием краски: настолько медленно пересобирались образы Docker. Поэтому требовался другой подход.
А что, если отладить запущенный Java-контейнер? С этим вопросом для меня обнаружились возможности удаленной отладки IntelliJ IDEA.
Приступаем
Создав приложение для удаленной отладки, открываем в IntelliJ IDEA меню Edit Configurations («Редактировать конфигурации»). Нажимаем значок +
и выбираем Remote JVM Debug («Удаленная отладка виртуальной машины Java»):

Видим такой экран:

Во вкладке Configuration меняем настройки под свои задачи:
- Name: содержательное название для конфигурации отладчика.
- Port: порт для отладчика, отличный от порта приложения.
- JDK Version: выбираем правильную версию JDK, которая соответствует приложению. Автоматически генерируемые аргументы командной строки для удаленной виртуальной машины Java отличаются в зависимости от версии JDK.
Выбрав корректные настройки для приложения, копируем сгенерированные аргументы командной строки.
Создание Dockerfile
Используя эти аргументы, создадим Dockerfile. Вот, например, сгенерированный для моего приложения:
FROM maven:3.9.9 AS maven
LABEL authors="Muratcan Yeldan"
WORKDIR /opt/reminder
COPY . /opt/reminder
RUN mvn clean install
FROM eclipse-temurin:21-jre-alpine
ARG JAR_FILE=PetVaccineReminder.jar
WORKDIR /opt/reminder
COPY --from=maven /opt/reminder/target/${JAR_FILE} /opt/reminder/
ENTRYPOINT ["java","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000","-jar","PetVaccineReminder.jar"]
В ENTRYPOINT
автосгенерированные аргументы командной строки добавляются после команды java
. Но перед командой -jar
, иначе удаленный отладчик не подключится.
Настройка docker-compose.yml
Теперь образ собирается и запускается напрямую или же для проекта создается docker-compose.yml
, например, такой:
services:
reminder_service:
build:
dockerfile: Dockerfile
container_name: reminder_service
restart: on-failure
ports:
- "8085:8085"
- "8000:8000"
environment:
SPRING_PROFILES_ACTIVE: docker
depends_on:
postgres-app:
condition: service_healthy
kafka:
condition: service_healthy
networks:
- backend-network
networks:
backend-network:
driver: bridge
Здесь указываются порт приложения 8085 и порт отладчика 8000. Запустив docker-compose.yml
, продолжаем выполнение созданной ранее конфигурации удаленной отладки.
Запуск отладчика

Нажав в IntelliJ IDEA кнопку отладки Debug, увидим в консоли такой лог:

Значит, отладчик подключился к указанному порту. Дальше отладка приложения продолжается, как в локальной машине.
Проект находится здесь, в него включены технологии вроде Kafka и Keycloak.
Читайте также:
- Всё, что вы хотели знать об отладке в IntelliJ IDEA
- 6 рекомендаций по устранению типичных проблем производительности Java
- Как Ktlint облегчает жизнь разработчикам
Читайте нас в Telegram, VK и Дзен
Перевод статьи Muratcan Yeldan: How to Remote Debug a Containerized Java Application with IntelliJ IDEA