15

我在Amazon Elastic Beanstalk上托管了一个 rails 项目,我尝试配置一个容器命令以在每次部署后自动重新启动服务器上的延迟作业工作程序。

我试过这个:

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

但是,似乎推送版本是在重新启动工作人员后部署的,因此工作人员无法处理作业。

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

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

谢谢

4

4 回答 4

22

根据亚马逊文档container_commands

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

(强调我的)

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

是解压后的应用目录。

这意味着如果您想delayed_job从刚刚提取(但尚未部署)的应用程序的目录运行,请不要覆盖cwd,它应该为即将部署的应用程序启动延迟作业。

参考: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 将/opt/elasticbeanstalk/hooks/appdeploy/post在 Web 服务器重新启动后执行任何脚本。这意味着如果您将 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脚本添加实际支持以在部署后运行命令,在这种情况下,您可以将其移至官方支持的方法。

于 2013-04-29T09:58:59.520 回答
6

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

请注意,此脚本以 root 身份运行,但您的工作人员应以 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
于 2015-02-13T19:08:00.427 回答
4

如果有人希望在最新的 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
于 2015-01-28T13:29:36.750 回答
1

我让我的“守护进程”宝石像这样工作:

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
于 2014-10-08T20:49:08.923 回答