#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/