Невозможно запустить приложение JavaFX в докере более нескольких минут


9

Я разработал приложение, используемое в качестве службы связи для отдельного веб-приложения. У меня было 0 проблем с «докеризацией» веб-приложения, но сервис оказался кошмаром. Он основан на JavaFX и есть свойство, которое может быть установлено пользователем в файле конфигурации, что делает его таким, чтобы приложение не инициализировало окна, меню, контейнеры и т. Д. Этот режим "без головы" (не уверен, что это действительно без головы ...) эффективно превращает сервисное приложение в фоновый сервис. Позвольте мне также предвосхитить это, сказав, что приложение работает абсолютно безупречно при запуске на моем компьютере с Windows 10 и что я развернул его на нескольких других машинах (все без док-станции) без проблем.

Вот докер-файл, который я придумал:

FROM openjdk:13.0.1-slim
RUN apt-get update && apt-get install libgtk-3-0 libglu1-mesa -y && apt-get update
VOLUME /tmp
ADD Some_Service-0.0.1-SNAPSHOT.jar Some_Service-0.0.1-SNAPSHOT.jar
ADD lib lib
ADD config.properties config.properties
ENTRYPOINT ["java", "--module-path", "lib/javafx-sdk-13", "-jar", "Some_Service-0.0.1-SNAPSHOT.jar"]

Затем я использую эту команду для построения контейнера:

docker run -t --name Some_Service -e DISPLAY=192.168.1.71:0.0 -e SERVICE_HOME= --link mySQLMD:mysql some_service

Предполагая, что VcXsrv работает на моем ПК, приложение запускается правильно, хотя оно выдает следующие предупреждения при первом запуске:

libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
Prism-ES2 Error : GL_VERSION (major.minor) = 1.4

Проблема в том, что он работает всего 2 минуты. В конце концов контейнер приходит с этой ошибкой и вылетает:

Gdk-Message: 15:28:54.770: java: Fatal IO error 11 (Resource temporarily unavailable) on X server 192.168.1.71:0.0.

Я понимаю, что первоначальные сообщения связаны с тем, что в контейнере нет драйвера NVidia, но откат к программному конвейеру, похоже, работает нормально. Честно говоря, я понятия не имею, чем может быть вызвана фатальная ошибка ввода-вывода. Я пробовал на разных хостах под управлением докера и такая же проблема случается.

Есть идеи как это исправить? Более того, есть идеи, как сделать приложение JavaFX TRULY безголовым и даже не требовать инициализации какого-либо из этих компонентов? Когда я работаю без головы, я использую Задачи и тому подобное, которые являются частью JavaFX, поэтому я не могу просто не использовать их ...


Пробовал монтировать хост-сервер Xserver во время выполнения контейнеров (т.е. -v /tmp/.X11-unix:/tmp/.X11-unix)? Приложение, пытающееся подключиться к серверу Xserver, предполагает, что оно не является «безголовым», и нужно будет пересмотреть реализацию.
Массиб

попробуйте запустить с поддержкой GPU. "docker run -t --name Some_Service --gpus all -e DISPLAY = 192.168.1.71: 0.0 -e SERVICE_HOME = --link mySQLMD: mysql some_service"
arshpreet

@arshpreet дает мне эту ошибку: Ошибка ответа от демона: не удалось выбрать драйвер устройства "" с возможностями: [[gpu]]
Martin

@masseyb Я работаю в докере на машине с Windows
Мартин,

Ответы:


2

Установите xvfb в свой контейнер, чтобы создать виртуальный экран. изменить на файл Docker:

FROM openjdk:13.0.1-slim
RUN apt-get update && apt-get install libgtk-3-0 libglu1-mesa xvfb -y && 
apt-get update
VOLUME /tmp
ADD Some_Service-0.0.1-SNAPSHOT.jar Some_Service-0.0.1-SNAPSHOT.jar
ADD lib lib
ADD config.properties config.properties
apt-get install xvfb
ENV DISPLAY=:99
ADD run.sh /run.sh
RUN chmod a+x /run.sh
CMD /run.sh 

Добавьте новый скрипт bash в папку вашего проекта и назовите его «run.sh»

run.sh:

#!/bin/bash
#remove old 
rm /tmp/.X99-lock #needed when docker container is restarted
Xvfb :99 -screen 0 640x480x8 -nolisten tcp &
java --module-path lib/javafx-sdk-13 -jar Some_Service-0.0.1-SNAPSHOT.jar

Не забудьте удалить -e DISPLAY=192.168.1.71:0.0из вашей команды запуска Docker


Можете ли вы показать мне, как изменить точку входа с команды java -jar на команду, содержащую как инструкцию java -jar, так и команду xvfb?
Мартин

Я попробовал метод, описанный здесь: success.docker.com/article/… . Это дает мне следующую ошибку: standard_init_linux.go: 211: пользовательский процесс exec вызвал «ошибку формата exec»
Martin

@Martin я отредактировал свой ответ, надеюсь, теперь все ясно.
leachim742

извините, я еще не очень хорошо разбираюсь с unix :( Я получаю эту ошибку при выполнении команды запуска docker сейчас: / bin / sh: 1: /run.sh: не найден
Martin

вам нужно создать файл 'run.sh', где будут храниться ваши другие файлы, такие как ваш
снимок.jar
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.