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

我正在使用Docker将Rails应用程序部署到Elastic Beanstalk,到目前为止,所有工作都已经完成。 我正处于应用程序需要运行数据库迁移和播种的阶段,而且我很难弄清楚我需要如何继续。 看起来,/. /.ebextensions文件夹中的任何命令都在主机上下文中运行,而不是在Docker容器中运行。 那是对的吗?

我很好,在启动后运行一个命令来执行docker容器内的迁移,但是如何确保迁移只能在单个实例上运行? 是否有一个环境variables或其他方式,我可以告诉什么机器是docker集装箱内的领导者?


更新:我在Amazon Elastic Beanstalk论坛上发布了一个问题,询问如何在6/8/15'上运行“来自容器上的Docker主机的命令 ”。 你可以跟随那里的谈话,以及他们是有用的。

我不确定你提出的解决scheme是否可行。 看起来EB Docker部署的当前进程在新的docker容器运行之前运行容器命令,这意味着你不能在其上使用docker exec 。 我怀疑你的命令将针对尚未停用的旧容器执行。

经过多次试验和错误,我通过使用shell脚本使用容器命令得到了这个工作。

 container_commands: 01_migrate_db: command: ".ebextensions/scripts/migrate_db.sh" leader_only: true 

和脚本:

 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 

我在检查中包装整个脚本以确保迁移不会在后台工作人员上运行。

然后,我使用完全相同的方式构buildENV,以便在启动新容器时进行迁移,以便为迁移创build正确的环境。

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

更新:这个解决scheme虽然看起来是正确的,但是并没有像预期的那样工作(尽pipe起初它似乎是如此)。 出于最好的解释,在下面的nmott的答案 。 将留在这里为后代。


我能够通过.ebextensions目录configuration文件使用container_commands得到这个工作。 在这里了解更多关于容器命令 。 我引用…

container_commands中的命令按字母顺序按名称处理。 它们在应用程序和Web服务器已经build立并且应用程序版本文件已经被提取之后,但是在应用程序版本被部署之前运行。 他们还可以访问诸如AWS安全证书等环境variables。 另外,你可以使用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 

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

使用.ebextensions / 01-environment.config

 container_commands: 01_write_leader_marker: command: touch /tmp/is_leader leader_only: true 

现在将目录/ tmp添加到Dockerfile / Dockerrun.aws.json中的卷。

然后检查在sh脚本中设置所有初始化命令,如db迁移,首先检查文件/ tmp / is_leader是否存在,并仅在这种情况下执行它们。