Подтвердить что ты не робот

Перезапуск приложения 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 по остановке приложения для воспроизведения

4b9b3361

Ответ 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>'