重新启动 Play 应用程序 Docker 容器导致 'This application is already running' - RUNNING_PID 未被删除
Restarting Play application Docker container results in 'This application is already running' - RUNNING_PID is not deleted
编辑: 有一个相关问题 discussed on Github 但在另一种部署模式下(Typesafe Activator UI 而不是 Docker) .
我试图模拟系统重启以验证 Docker 重启策略,该策略声明能够以正确的顺序重新 运行 容器。
我有一个用 Java 编写的 Play 框架应用程序。
Docker文件如下所示:
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 文档的建议 change the location of the file 到 /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"
},
虽然:
The main process inside the container will receive SIGTERM, and after
a grace period, SIGKILL.
来自 Docker reference on $ docker stop
To kill a running Play server, it is enough to send a SIGTERM to the
process to properly shutdown the application.
来自 Play Framework documentation on stopping a Play application
我不太了解 docker,但据我测试,Play 不会在停止服务器时删除 RUNNING_PID
。当我以 prod
模式部署我的应用程序并尝试通过 Ctrl+D
和 Ctrl+C
停止它时,它没有从项目目录中删除 RUNNING_PID 文件,所以我不得不手动删除它。来自 Play docs
Normally this(RUNNING_PID) file is placed in the root directory of your play
project, however it is advised that you put it somewhere where it will
be automatically cleared on restart, such as /var/run
:
所以 - 除了手动删除 - 解决方法是更改 RUNNING_PID 的路径并在每次服务器启动时通过一些脚本删除它。
$ /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
也许这会有所帮助
我遇到了完全相同的问题,我通过在每次容器 运行 时手动删除文件来解决这个问题。
为了做到这一点,我在配套文件中添加了 start.bash
我用来从 SBT dist 任务的结果开始播放过程,以下行:
find . -type f -name RUNNING_PID -exec rm -f {} \;
希望对您有所帮助。
我根据答案和我对这个问题的进一步工作整理出一个可行的解决方法。如果我按如下方式启动容器,它们将在(未)预期 stop/restart 后启动。冲突的 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 的文件。
我刚刚对 Play 进行了 docker 化!应用程序,也 运行 陷入此问题 - 重新启动主机导致播放!应用程序无法在其容器中启动,因为 RUNNING_PID
尚未删除。
我突然想到,作为 Play!应用程序是其容器中的唯一进程,始终具有相同的 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)。
我运行在ctrl+c失败后遇到了同样的问题。我通过 运行 docker-compose down -v
解决了这个问题,当然 运行 docker-compose up
也解决了这个问题。 -v
选项表示您要删除与您的容器关联的卷。也许 docker-compose down
就足够了。
以下是一些 down
选项的概要:
`
仅停止服务
docker-compose stop
停止并删除容器、网络..
docker-compose down
关闭并删除卷
docker-compose down --volumes
向下并删除图像
docker-compose down --rmi <all|local>`
编辑: 有一个相关问题 discussed on Github 但在另一种部署模式下(Typesafe Activator UI 而不是 Docker) .
我试图模拟系统重启以验证 Docker 重启策略,该策略声明能够以正确的顺序重新 运行 容器。
我有一个用 Java 编写的 Play 框架应用程序。
Docker文件如下所示:
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 文档的建议 change the location of the file 到 /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"
},
虽然:
The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL.
来自 Docker reference on $ docker stop
To kill a running Play server, it is enough to send a SIGTERM to the process to properly shutdown the application.
来自 Play Framework documentation on stopping a Play application
我不太了解 docker,但据我测试,Play 不会在停止服务器时删除 RUNNING_PID
。当我以 prod
模式部署我的应用程序并尝试通过 Ctrl+D
和 Ctrl+C
停止它时,它没有从项目目录中删除 RUNNING_PID 文件,所以我不得不手动删除它。来自 Play docs
Normally this(RUNNING_PID) file is placed in the root directory of your play project, however it is advised that you put it somewhere where it will be automatically cleared on restart, such as
/var/run
:
所以 - 除了手动删除 - 解决方法是更改 RUNNING_PID 的路径并在每次服务器启动时通过一些脚本删除它。
$ /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
也许这会有所帮助
我遇到了完全相同的问题,我通过在每次容器 运行 时手动删除文件来解决这个问题。
为了做到这一点,我在配套文件中添加了 start.bash
我用来从 SBT dist 任务的结果开始播放过程,以下行:
find . -type f -name RUNNING_PID -exec rm -f {} \;
希望对您有所帮助。
我根据答案和我对这个问题的进一步工作整理出一个可行的解决方法。如果我按如下方式启动容器,它们将在(未)预期 stop/restart 后启动。冲突的 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 的文件。
我刚刚对 Play 进行了 docker 化!应用程序,也 运行 陷入此问题 - 重新启动主机导致播放!应用程序无法在其容器中启动,因为 RUNNING_PID
尚未删除。
我突然想到,作为 Play!应用程序是其容器中的唯一进程,始终具有相同的 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)。
我运行在ctrl+c失败后遇到了同样的问题。我通过 运行 docker-compose down -v
解决了这个问题,当然 运行 docker-compose up
也解决了这个问题。 -v
选项表示您要删除与您的容器关联的卷。也许 docker-compose down
就足够了。
以下是一些 down
选项的概要:
`
仅停止服务
docker-compose stop
停止并删除容器、网络..
docker-compose down
关闭并删除卷
docker-compose down --volumes
向下并删除图像
docker-compose down --rmi <all|local>`