如何在Amazon Elastic Beanstalk单容器Docker环境中运行Rails迁移和种子设定

Kin*_*ina 9 ruby-on-rails docker amazon-elastic-beanstalk

我正在使用docker将Rails应用程序部署到Elastic Beanstalk,到目前为止一切都已成功.我正处于应用程序需要运行数据库的迁移和种子的位置,而我无法确定我需要如何继续进行.看来该/.ebextensions文件夹中的任何命令都在主机的上下文中运行,而不是在docker容器中运行.那是对的吗?

我可以在启动后运行命令在docker容器内执行迁移,但是如何确保迁移仅在单个实例上运行?是否有环境变量或其他方式我可以在docker容器中告诉哪个机器是领导者?


更新:在Amazon Elastic Beanstalk论坛上发布了一个问题,询问如何在6月8日/ 8月15日运行"来自容器上的Docker主机的命令 ".你可以在那里关注对话,但它们很有用.

nmo*_*ott 7

我不确定你提出的解决方案是否有效.似乎EB Docker部署的当前进程在新的docker容器运行之前运行容器命令,这意味着您无法docker exec在其上使用它.我怀疑你的命令将针对尚未停止服务的旧容器执行.

经过多次试验和错误后,我通过使用带有shell脚本的容器命令来完成这项工作.

container_commands:
  01_migrate_db:
    command: ".ebextensions/scripts/migrate_db.sh"
    leader_only: true
Run Code Online (Sandbox Code Playgroud)

和剧本:

if [ "${PROCESS}" = "WEB" ]; then

  . /opt/elasticbeanstalk/hooks/common.sh

  EB_SUPPORT_FILES=$(/opt/elasticbeanstalk/bin/get-config container -k support_files_dir)

  EB_CONFIG_DOCKER_ENV_ARGS=()

  while read -r ENV_VAR; do
    EB_CONFIG_DOCKER_ENV_ARGS+=(--env "$ENV_VAR")
  done < <($EB_SUPPORT_FILES/generate_env)

  echo "Running migrations for aws_beanstalk/staging-app"
  docker run --rm "${EB_CONFIG_DOCKER_ENV_ARGS[@]}" aws_beanstalk/staging-app bundle exec rake db:migrate || echo "The Migrations failed to run."
fi
true
Run Code Online (Sandbox Code Playgroud)

我将整个脚本包装在一个检查中,以确保迁移不会在后台工作程序上运行.

然后,我以与启动新容器时EB完全相同的方式构建ENV,以便为迁移提供正确的环境.

最后,我针对已经创建但尚未运行的新容器运行命令aws_beanstalk/staging-app.它在迁移结束时退出,并--rm自动删除容器.


Kin*_*ina 4

更新:这个解决方案虽然看起来是正确的,但并没有按预期工作(虽然一开始似乎是这样)。原因在nmott下面的回答中得到了最好的解释。将其留给后人。


我可以container_commands通过.ebextensions目录配置文件来完成此工作。在此处了解有关容器命令的更多信息。我引用...

中的命令container_commands按名称的字母顺序进行处理。它们在设置应用程序和 Web 服务器并且提取应用程序版本文件之后、部署应用程序版本之前运行。他们还可以访问环境变量,例如您的 AWS 安全凭证。此外,您可以使用leader_only。选择一个实例作为 Auto Scaling 组中的领导者。如果 Leader_only 值设置为 true,则该命令仅在标记为领导者的实例上运行。

所以,应用这些知识......container_commands.config将会......

# .ebextensions/container_commands.config
container_commands:
  01_migrate_db:
    command: docker exec `docker ps -l -q -f 'status=running'` rake db:migrate RAILS_ENV=production
    leader_only: true
    ignoreErrors: false
  02_seed_db:
    command: docker exec `docker ps -l -q -f 'status=running'` rake db:seed RAILS_ENV=production
    leader_only: true
    ignoreErrors: false
Run Code Online (Sandbox Code Playgroud)

首先运行迁移,然后为数据库播种。我们使用它在现有容器(而不是主机)的上下文中docker exec [OPTIONS] CONTAINER_ID COMMAND [ARG...]运行附加内容。COMMAND [ARG...]我们CONTAINER_ID通过跑步来获得docker ps -q