Перезапуск докера застрял в цикле для приложения rails

#ruby-on-rails #docker #deployment #vps #production

Вопрос:

У меня есть контейнерное приложение rails, работающее в VPS.

После создания образа мой сценарий развертывания выполняет что-то вроде следующего для запуска контейнера:

 docker run 
    -v /home/user/my-app/public:/home/rails/my-app/public 
    -v /home/user/my-app/log:/home/rails/my-app/log 
    -p 1337:1337 
    --restart=always 
    -d 
    my-image
 

Он просто монтирует некоторые тома и устанавливает политику перезапуска на всегда. До сих пор все работало нормально.

Однако иногда в моем приложении rails заканчивается память (в краткосрочной перспективе это невозможно исправить), и в результате докер убивает контейнер. Когда это произойдет, я ожидаю, что приложение rails будет автоматически перезапущено.

Однако иногда docker застревает в цикле перезапуска контейнера, потому что, как только он перезапускается, rails сообщает, что сервер уже запущен, и завершает работу. Это результат выполнения docker logs

 => Booting Puma
=> Rails 6.1.3.1 application starting in production 
=> Run `bin/rails server --help` for more startup options
A server is already running. Check /home/rails/my-app/tmp/pids/server.pid.
Exiting
 

Я не совсем понимаю, почему этот файл остается там после остановки и перезапуска контейнера. Разве этот файл не должен быть эфемерным? Кроме того, я не знаю, как это исправить. Документация по политике перезапуска docker не содержит подробных сведений о том, что на самом деле делает перезапуск. Может быть, мне придется добавить docker-entrypoint.sh и вручную удалить файл там? И если да, то, может быть, есть рекомендуемая настройка для производственного приложения rails, работающего на VPS?

Комментарии:

1. Нашел кого-то в reddit с той же проблемой: https://www.reddit.com/r/rails/comments/aphq08/rails_docker_and_tmppidsserverpid/

2. вы можете обойти проблему , удалив предыдущий pid сервера rails (любой идентификатор) перед повторным запуском rails: command: bash -c "rm -f tmp/pids/server.pid amp;amp; bundle exec rails s -p 3000 -b '0.0.0.0'" , ссылка: github.com/docker/compose/issues/1393

Ответ №1:

Оказывается, перезапуск не восстанавливает контейнер, и поэтому данные, записанные в контейнере, сохраняются при перезапуске, включая tmp/pids/server.pid.

В поисках дополнительной информации я нашел эти два варианта:

  • Удалите файл server.pid в docker-entrypoint.sh файл. Возможно, использовать rake tmp:pids:clear в соответствии с документацией rails.
  • Подключите tmp/pid к tmpfs. --mount type=tmpfs,destination=/home/rails/my-app/tmp/pids

Также в документации docker есть образец приложения rails, и он подходит для первого варианта: https://docs.docker.com/samples/rails/