Перезапуск приложения Play Приложение Docker: "Это приложение уже запущено" - RUNNING_PID не удаляется
Изменить: Существует связанная с этим проблема обсуждаемая в Github, но в другом режиме развертывания (интерфейс API-интерфейсов SafeApp, а не Docker).
Я пытался смоделировать перезагрузку системы, чтобы проверить политику перезагрузки Docker, которая заявляет, что сможет повторно запускать контейнеры в правильном порядке.
У меня есть приложение для платформы Play, написанное на Java.
Файл 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 для изменить местоположение файла в /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).
Итак: Почему файл, содержащий RUNNING_PID, не удаляется, когда демон docker останавливается, перезагружается и перезапускает ранее запускаемые контейнеры?
Когда я $ 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 на остановку $docker
Чтобы убить запущенный сервер воспроизведения, достаточно отправить SIGTERM на для правильного завершения работы приложения.
из документации Play Framework по остановке приложения для воспроизведения
Ответы
Ответ 1
Я разобрался в рабочем обходном пути, основанном на ответах и моей дальнейшей работе над этим вопросом. Если я запускаю контейнеры следующим образом, они появятся после (un) ожидаемой остановки/перезапуска. Конфликтный файл 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"
Что он делает - это удаление файла, содержащего идентификатор процесса, который помещается в определенное место с использованием опции каждый раз перед запуском двоичного файла.
Ответ 2
Я только что запустил игру! приложение и также столкнулось с этой проблемой - перезапуск хоста вызвал игру! приложение не запускается в своем контейнере, потому что 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).
Ответ 3
Я не знаю много о Docker, но Play не удаляет RUNNING_PID
при остановке сервера, насколько я тестировал. Когда я развернул свое приложение в режиме prod
и попытался остановить его с помощью Ctrl+D
и Ctrl+C
оно не удалило файл RUNNING_PID из каталога проекта, поэтому мне пришлось удалить его вручную. Из Play Docs
Обычно этот (RUNNING_PID) файл помещается в корневой каталог вашего игрового проекта, однако рекомендуется поместить его в то место, где он будет автоматически очищен при перезапуске, например /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
Может быть, это могло бы помочь
Источник1 Источник2 Источник3
Ответ 4
У меня была точно такая же проблема, и я обошел ее, вручную удаляя файл при каждом запуске контейнера.
Для этого я добавил в сопутствующий файл start.bash
, который я использую для запуска процесса воспроизведения по результатам задачи dist SBT, следующую строку:
find . -type f -name RUNNING_PID -exec rm -f {} \;
Надеюсь, это поможет.
Ответ 5
Я столкнулся с той же проблемой после сбоя 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>'