如何在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是否存在,并仅在这种情况下执行它们。
- 在Elastic Beanstalk / Docker Nginx / PHP-FPM实例中访问客户端IP
- Elastic Beanstalk本地环境(与Docker)连接被拒绝
- 在AWS上监控和扩展基于Docker的Celery工作者群集
- 如何在单个容器Docker环境上的Amazon Elastic Beanstalk上部署Rails应用程序
- AWS BeansTalk公开Docker端口
- AWS Docker Golang。 'eb deploy'错误
- 在Elastic Beanstalk Docker容器上运行非www内容
- 在Elastic Beanstalk中暴露Docker的多个端口
- 如何将docker-compose.yml转换为Django的Dockerrun.aws.json