重新启动Play应用程序Docker容器导致“此应用程序已在运行” – RUNNING_PID不会被删除

编辑:有一个相关的问题在Github上讨论,但在另一种部署模式(Typesafe Activator UI而不是Docker)。

我试图模拟系统重新启动,以validationDocker重新启动策略,声明可以按正确的顺序重新运行容器。

我有一个用Java编写的Play框架应用程序。

Dockerfile看起来像这样:

FROM ubuntu:14.04 # # [Java8, ...] # RUN chmod +x /opt/bin/playapp CMD ["/bin/bash"] 

我开始使用$ docker run --restart=always -d --name playappcontainer "./opt/bin/playapp"

当我$ service docker stop && service docker restart ,然后$ docker attach playappcontainer控制台告诉我:

 Play server process ID is 7 This application is already running (Or delete /opt/RUNNING_PID file) 

编辑:当按照Play文档的build议,使用-Dpidfile.path=/var/run/play.pid 将文件的位置更改为/var/run/play.pid时, -Dpidfile.path=/var/run/play.pid

 Play server process ID is 7 This application is already running (Or delete /var/run/play.pid file). 

那么:为什么当docker守护进程停止时,包含RUNNING_PID的文件不会被删除,重新启动并重新启动之前运行的容器?


当我$ docker inspect playappcontainer ,它告诉我:

 "State": { "ExitCode": 255, "FinishedAt": "2015-02-05T17:52:39.150013995Z", "Paused": false, "Pid": 0, "Restarting": true, "Running": true, "StartedAt": "2015-02-05T17:52:38.479446993Z" }, 

虽然:

容器内的主要进程将收到SIGTERM,并在一个宽限期之后,SIGKILL。

来自$ docker stop的Docker引用

要杀死正在运行的Play服务器,发送一个SIGTERM到进程正确closures应用程序就足够了。

从Play Framework文档停止播放应用程序

我刚刚docker游戏! 应用程序,也遇到了这个问题 – 重新启动主机造成播放! 应用程序无法在其容器中启动,因为RUNNING_PID尚未被删除。

它发生在我身上,作为玩! 应用程序是其容器中唯一的进程,总是具有相同的PID,并由Docker负责, RUNNING_PID文件(据我所知)并非实际需要。

因此,我通过放置覆盖pidfile.path/dev/null

 javaOptions in Universal ++= Seq( "-Dpidfile.path=/dev/null" ) 

在我的项目的build.sbt。 它的工作原理 – 我可以重新启动主机(和容器)和我的玩! 应用程序启动正常。

这种方法对我的吸引力在于,它不需要改变图像本身由sbt-native-packager生成的方式,只是应用程序在其中运行的方式。

这适用于sbt-native-packager 1.0.0-RC2及更高版本(因为该版本包含https://github.com/sbt/sbt-native-packager/pull/510 )。

我根据答案和我在这个问题上的进一步工作,整理出了一个工作的解决方法。 如果我按照以下方式启动集装箱,在(不)预期的停止/重新启动后,它们将会启动。 冲突的RUNNING_PID文件不会阻止容器重新启动。

 $ sudo docker run --restart=on-failure:5 -d \ --name container my_/container:latest \ sh -c "rm -f /var/run/play.pid && ./opt/bin/start \ -Dpidfile.path=/var/run/play.pid" 

它所做的是在运行二进制文件之前,每次使用选项删除包含放置在特定位置的进程ID的文件。

我有完全相同的问题,并通过每次运行容器时手动删除文件来解决这个问题。 为了做到这一点,我添加了一个伴随文件“start.bash”,用于从SBT dist任务的结果开始播放过程,如下所示:

找 。 -type f -name RUNNING_PID -exec rm -f {} \;

希望能帮助到你。

我不太了解docker.But play不要删除RUNNING_PID停止服务器,据我testing。当我在prod模式部署我的应用程序,并尝试通过Ctrl+DCtrl+C停止它不会删除从项目目录的RUNNING_PID文件,所以我不得不手动删除它。从播放文档

通常情况下,这个(RUNNING_PID)文件被放置在你的播放项目的根目录中,但是build议你把它放在重启时自动清除的地方,比如/var/run

因此,除了手动取消解决方法将是

更改RUNNING_PID的path并在每次服务器启动时通过一些脚本删除它

 $ /path/to/bin/<project-name> -Dpidfile.path=/var/run/play.pid 

确保该目录存在,并且运行Play应用程序的用户具有写入权限。

使用这个文件,你可以使用kill命令来停止你的应用程序,例如:

 $ kill $(cat /var/run/play.pid) 

你也可以尝试docker命令$ sudo docker rm --force redis

也许这可能有帮助

Source1 Source2 Source3

    Interesting Posts