无法在 docker 上 运行 JavaFX 应用超过几分钟
Cannot run JavaFX app on docker for more than a few minutes
我开发了一个应用程序,用作单独网络应用程序的通信服务。我有 0 个问题 "dockerizing" Web 应用程序,但事实证明该服务是一场噩梦。它基于 JavaFX,并且有一个 属性 可以由用户在配置文件中设置,这样应用程序就不会初始化任何 windows、菜单、容器等。这个 "headless" 模式(不确定是否真的无头...)有效地将服务应用程序转变为后台服务。让我先说一下当 运行 在我的 windows 10 机器上并且我已经将它部署在其他几台机器(所有非 dockerized)上时,该应用程序绝对完美地运行没问题。
这是我想出的docker文件:
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 在我的 PC 上 运行ning,该应用程序可以正确启动,尽管它在首次启动时会发出以下警告:
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 驱动程序,但回退到软件管道似乎工作正常。老实说,我不知道致命的 IO 错误可能是由什么引起的。我在不同的主机 运行ning docker 上试过,同样的问题发生了。
知道如何解决这个问题吗?更好的是,知道如何使 JavaFX 应用程序真正无头,甚至不需要初始化任何这些东西吗?当 运行ning 无头时,我使用 Tasks 等,它们是 JavaFX 的一部分,所以我不能不使用它...
在您的容器中安装 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
不要忘记从您的 docker 运行 命令中删除 -e DISPLAY=192.168.1.71:0.0
我开发了一个应用程序,用作单独网络应用程序的通信服务。我有 0 个问题 "dockerizing" Web 应用程序,但事实证明该服务是一场噩梦。它基于 JavaFX,并且有一个 属性 可以由用户在配置文件中设置,这样应用程序就不会初始化任何 windows、菜单、容器等。这个 "headless" 模式(不确定是否真的无头...)有效地将服务应用程序转变为后台服务。让我先说一下当 运行 在我的 windows 10 机器上并且我已经将它部署在其他几台机器(所有非 dockerized)上时,该应用程序绝对完美地运行没问题。
这是我想出的docker文件:
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 在我的 PC 上 运行ning,该应用程序可以正确启动,尽管它在首次启动时会发出以下警告:
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 驱动程序,但回退到软件管道似乎工作正常。老实说,我不知道致命的 IO 错误可能是由什么引起的。我在不同的主机 运行ning docker 上试过,同样的问题发生了。
知道如何解决这个问题吗?更好的是,知道如何使 JavaFX 应用程序真正无头,甚至不需要初始化任何这些东西吗?当 运行ning 无头时,我使用 Tasks 等,它们是 JavaFX 的一部分,所以我不能不使用它...
在您的容器中安装 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
不要忘记从您的 docker 运行 命令中删除 -e DISPLAY=192.168.1.71:0.0