Tomcat, Docker, Logging и STDOUT?

Я запускаю tomcat в докере, но не вижу журналов. Они записываются в различные файлы журналов в разделе tomcat / logs, но я не вижу их, когда tomcat работает в контейнере докеров.

Вот мой Dockerfile

FROM tomcat:7-jre8
COPY target/MYAPP.war /usr/local/tomcat/webapps/MYAPP.war
RUN ["/usr/local/tomcat/bin/catalina.sh", "start"]

Вот как я создаю образ и запускаю из него контейнер:

docker build -t MYAPP .
docker run -it --rm -p 8080:8080 --name MYAPP MYAPP

Мое приложение создает файл журнала: /var/log/MYAPP.log после того, как tomcat развертывает MYAPP.war

Как мне изменить Dockerfile и какую команду следует использовать для его запуска («docker run ...»), чтобы сразу после запуска контейнера MYAPP с помощью oneliner docker run -it --rm -p 8080: 8080 --name MYAPP MYAPP "содержимое /var/log/MYAPP.log будет выводиться на стандартный вывод?

Я попытался добавить в Dockerfile приведенную ниже команду, но это не помогло.

CMD tail -f /usr/local/MYAPP.log

person Oleg    schedule 08.12.2017    source источник


Ответы (6)


Кажется, вас смущает разница между RUN и CMD.

Директива RUN используется для выполнения команд в процессе сборки. Он никогда не выполняется в контейнере. Когда пишешь ...

RUN ["/usr/local/tomcat/bin/catalina.sh", "start"]

... это означает, что во время docker build процесса Docker запустит tomcat, но немедленно убьет его и продолжит сборку вашего образа.

Только директивы CMD и ENTRYPOINT определяют команды, которые будут запускаться при загрузке образа с docker run. Так что, возможно, вам нужно что-то вроде:

CMD /usr/local/tomcat/bin/catalina.sh start && tail -f /usr/local/MYAPP.log
person larsks    schedule 08.12.2017
comment
О, спасибо, теперь я вижу разницу между RUN и CMD, интересно! Я пробовал, но теперь он говорит: Успешно построено 3a1ccf47c08c Успешно помечено MYAPP: latest Использование CATALINA_BASE: / usr / local / tomcat Использование CATALINA_HOME: / usr / local / tomcat Использование CATALINA_TMPDIR: / usr / local / tomcat / temp Использование JRE_HOME: / docker- java-home / jre Использование CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Запущен Tomcat. хвост: невозможно открыть '/usr/local/MYAPP.log' для чтения: нет такого файла или каталога хвост: не осталось файлов - person Oleg; 08.12.2017
comment
Сообщение об ошибке «Нет такого файла или каталога» кажется довольно ясным. Возможно, файл не был создан к моменту запуска tail -f. Вместо этого рассмотрите возможность использования tail -F, который должен дождаться появления файла. - person larsks; 08.12.2017
comment
Спасибо, помогло! - person Oleg; 08.12.2017
comment
Это не рекомендуется. Если вы просто используете catalina.sh run, а не start, журналы будут перенаправлены на стандартный вывод, где вы сможете легко получить к ним доступ с помощью инструментов докера (docker logs ...). - person Software Engineer; 07.06.2018
comment
На самом деле суть этого ответа заключалась в разнице между RUN и CMD. - person larsks; 07.06.2018

Хорошо, ваш файл докеров должен содержать что-то вроде этого **:

from tomcat:7-jre8
copy target/myapp.war /usr/local/tomcat/webapps/myapp.war
entrypoint ["/bin/bash", "/usr/local/tomcat/bin/catalina.sh", "run"]

Затем вы можете запустить контейнер на основе этого изображения примерно так:

docker run -itd -p 8080:8080 --name aname animage

Итак, команда catalina 'run' предназначена для перенаправления всех журналов на стандартный вывод. Это полезно для нас, потому что так работает докер. Если вы запустите контейнер сейчас, вы сможете запустить:

docker logs aname

Результатом будет все, что было отправлено на стандартный вывод в контейнере. Вы можете делать с этим все, что хотите, но обычные стратегии - это перенос журналов в logstash, splunk или тысячу других мест, или вы можете записать их в файл (хотя последний в основном для разработчиков).

** Конечно, вам придется изменить точку входа в соответствии с особенностями вашей установки. И показанная здесь команда запуска предназначена для демона.

Исходная проблема: ваши исходные проблемы были основаны на типичной ошибке; вы пытались запустить сервер tomcat во время подготовки (создания образа). На самом деле вы хотите запустить сервер при запуске контейнера. Итак, я удалил run и заменил его точкой входа, что является правильным способом выполнения такой команды. Наконец, cmd предназначен для передачи параметров точке входа, которые нам в данном случае не нужны.

Наконец, я решил использовать cataline.sh run, а не start, потому что run предназначен для отправки журналов в стандартный вывод, а не в файл, как это делает start.

использованная литература

Просмотреть журналы: https://docs.docker.com/config/containers/logging/

Журналы конфигурации: https://docs.docker.com/config/containers/logging/configure/

person Software Engineer    schedule 06.06.2018

Чтобы направить все журналы на стандартный вывод, необходимо сделать следующее:

  1. Подобно ответу на Как запретить журналам приложений вход в catalina.out в Tomcat, вы можете передать переменную среды CATALINA_OUT значение как /dev/stdout. Это обеспечит отправку всех журналов tomcat на стандартный вывод.
  2. В logging.properties базы catalina сохраните java.util.logging .ConsoleHandler и удалите другие обработчики.
  3. Измените конфигурацию ведения журнала в вашем приложении (например, файл log4j2.xml, если вы используете log4j2), чтобы отправлять журналы на стандартный вывод. В log4j2 это можно сделать с помощью консольного приложения .
person Ritesh    schedule 10.03.2020

Нашел здесь хороший способ: https://github.com/Scout24/tomcat-stdout-accesslog/issues/2

Замените следующий Valve в своем файле server.xml.

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="/proc/self/fd"
       prefix="1" suffix="" rotatable="false"
       pattern="%h %l %u %t &quot;%r&quot; %s %b" />

Только Linux!

Этот хороший способ работает для меня, как и ожидалось.

person Lars    schedule 07.07.2020
comment
У меня это работает. Я не уверен, насколько это будет производительно в масштабе - я опубликую здесь, если обнаружу какие-либо проблемы с масштабированием. - person Jaron F; 03.06.2021

Может быть, лучше будет писать логи прямо в stdout, а не в файл в контейнере. Он будет утерян после перезапуска.

Для получения дополнительных сведений см. https://12factor.net/logs.

person Ardling    schedule 08.12.2017
comment
Как только все будет перенаправлено в stdout / stderr, журналы станут доступны через docker logs -f <container_name> - person HammerMeetNail; 09.12.2017
comment
@ DJO3, я просто монтирую логи в tmpfs в docker-compose. Он также будет потерян после перезапуска: tmpfs: - / var / log - person Oleg; 27.12.2017

Ниже сработало у меня в Tomcat 9.0.37:

Вместо ./statup.sh, используйте ./catalina.sh run для запуска сервера tomcat.

(Приветствия ????)

person Mayur Chavan    schedule 27.11.2020