如何在Amazon Elastic Beanstalk上部署rails项目时自动重启delayed_job?

我正在Amazon Elastic Beanstalk上托管一个rails项目,我尝试配置一个容器命令,以便在每次部署后自动重启服务器上的delayed_job worker。

我试过这个:

container_commands: restartdelayedjob: command: "RAILS_ENV=production script/delayed_job --pid-dir=/home/ec2-user/pids start" cwd: /var/app/current 

但是,似乎在重新启动worker之后部署了推送版本,因此作业无法处理作业。

当我通过ssh连接我的实例时,杀死工作进程并从已部署的版本文件夹重新启动一个新进程,一切正常。

你对我如何处理这个有什么想法吗?

谢谢

根据container_commands的Amazon文档 :

它们在应用程序和Web服务器已设置并且已提取应用程序版本文件之后但在部署应用程序版本之前运行

(强调我的)

这意味着在您设置的/var/app/current ,您的命令的cwd仍然指向先前的版本。 但是默认情况下,再次从文档中, cwd

是解压缩的应用程序的目录。

这意味着如果您想从刚刚解压缩但尚未部署的应用程序目录中运行delayed_job ,请不要覆盖cwd ,它应该为即将部署的应用程序启动delayed_job。

参考: http : //docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#customize-containers-format-container_commands

更新:

我现在自己设置了这个,并发现通过标准的container_commands来实现这一点 – 基本上,delayed_job将在它仍在/var/app/ondeck目录中时启动。 通常情况下这没关系,但是我在某些工作中遇到了一些问题,因为当应用程序现在位于/var/app/current ,该路径已经停留在它周围会导致错误。

我找到了一个未记录的(如此警告!)方法,您可以添加脚本,以便在重新启动应用服务器后运行(并且您的新部署位于/var/app/current )。

基本上,Elastic Beanstalk将在重新启动Web服务器后执行/opt/elasticbeanstalk/hooks/appdeploy/post任何脚本。 这意味着如果您将shell脚本放在此目录中,它们将被运行。

我创建了一个这样的shell脚本:

 #!/usr/bin/env bash . /opt/elasticbeanstalk/support/envvars cd $EB_CONFIG_APP_CURRENT su -c "RAILS_ENV=production script/delayed_job --pid-dir=$EB_CONFIG_APP_SUPPORT/pids restart" $EB_CONFIG_APP_USER 

我将此脚本上传到S3存储桶,并确保它是“公共”的。 然后,您可以使用.ebextensions目录中的选项脚本(例如99delayed_job.config )将此脚本部署为应用程序部署的一部分,请注意post目录可能不存在:

 commands: create_post_dir: command: "mkdir /opt/elasticbeanstalk/hooks/appdeploy/post" ignoreErrors: true files: "/opt/elasticbeanstalk/hooks/appdeploy/post/99_restart_delayed_job.sh": mode: "000755" owner: root group: root source: http://YOUR_BUCKET.s3.amazonaws.com/99_restart_delayed_job.sh 

部署时,您应该在/var/log/eb-tools.log看到类似的内容:

 2013-05-16 01:20:53,759 [INFO] (6467 MainThread) [directoryHooksExecutor.py-29] [root directoryHooksExecutor info] Executing directory: /opt/elasticbeanstalk/hooks/appdeploy/post/ 2013-05-16 01:20:53,760 [INFO] (6467 MainThread) [directoryHooksExecutor.py-29] [root directoryHooksExecutor info] Executing script: /opt/elasticbeanstalk/hooks/appdeploy/post/99_restart_delayed_job.sh 2013-05-16 01:21:02,619 [INFO] (6467 MainThread) [directoryHooksExecutor.py-29] [root directoryHooksExecutor info] Output from script: delayed_job: trying to stop process with pid 6139... delayed_job: process with pid 6139 successfully stopped. 2013-05-16 01:21:02,620 [INFO] (6467 MainThread) [directoryHooksExecutor.py-29] [root directoryHooksExecutor info] Script succeeded. 

正如我所说的那样,把东西放在这个“post”目录中是没有记录的 – 但希望在某些时候亚马逊为.options脚本添加实际支持以在部署后运行命令,在这种情况下你可以将其移动到官方支持的方法。

运行Ruby 2.1(Passenger Standalone)的64位Amazon Linux 2014.09 v1.1.0上 ,感谢这篇文章让它运行起来。

请注意,此脚本以root身份运行,但您的worker应作为webapp用户运行。

 # Adds a post-deploy hook such that after a new version is deployed # successfully, restarts the delayed_job workers. # # http://stackoverflow.com/questions/14401204/how-to-automatically-restart-delayed-job-when-deploying-a-rails-project-on-amazo # http://www.dannemanne.com/posts/post-deployment_script_on_elastic_beanstalk_restart_delayed_job files: "/opt/elasticbeanstalk/hooks/appdeploy/post/50_restart_delayed_job.sh": mode: "000755" owner: root group: root encoding: plain content: | #!/usr/bin/env bash EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir) EB_APP_CURRENT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir) EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user) EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir) EB_APP_PIDS_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_pid_dir) . $EB_SUPPORT_DIR/envvars . $EB_SCRIPT_DIR/use-app-ruby.sh cd $EB_APP_CURRENT_DIR # Switch to the webapp user. Worker shouldn't be run as root. su -s /bin/bash -c "bundle exec bin/delayed_job --pid-dir=$EB_APP_PIDS_DIR restart" $EB_APP_USER 

如果有人想让delayed_job在最新的ElasticBeanstalk(运行Ruby 2.1(Puma)的64位Amazon Linux 2014.09 v1.0.9)中工作:我使用下面的代码让它工作(感谢damontorgerson )。 此文件位于.ebextensions文件夹中的ruby.config中。

 # Install git in order to be able to bundle gems from git packages: yum: git: [] files: "/opt/elasticbeanstalk/hooks/appdeploy/post/50_restart_delayed_job": mode: "000777" owner: root group: root content: | EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir) EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir) EB_CONFIG_APP_CURRENT=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir) EB_CONFIG_APP_LOGS=$(/opt/elasticbeanstalk/bin/get-config container -k app_log_dir) EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user) EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir) EB_CONFIG_APP_PIDS=$(/opt/elasticbeanstalk/bin/get-config container -k app_pid_dir) . $EB_SUPPORT_DIR/envvars . $EB_SCRIPT_DIR/use-app-ruby.sh cd $EB_CONFIG_APP_CURRENT . $EB_SUPPORT_DIR/envvars.d/sysenv bin/delayed_job --pid-dir=/var/tmp restart 

我使用“守护进程”gem让我的工作如此:

 commands: create_post_dir: command: "mkdir /opt/elasticbeanstalk/hooks/appdeploy/post" ignoreErrors: true webapp_pids: command: "mkdir /home/webapp/pids" ignoreErrors: true files: "/opt/elasticbeanstalk/hooks/appdeploy/post/99_restart_delayed_job.sh": mode: "000755" owner: root group: root content: | #!/usr/bin/env bash . /opt/elasticbeanstalk/support/envvars chown webapp:webapp /home/webapp/pids su -l -c "$EB_CONFIG_APP_CURRENT/bin/delayed_job --pid-dir=/home/webapp/pids restart" $EB_CONFIG_APP_USER echo "worker starting" >> /var/log/directory-hooks-executor.log