重新启动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+D
和Ctrl+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