Rails 在 ECS 上迁移

Rails migration on ECS

我正在尝试弄清楚如何在我的 ECS 服务上 运行 rake db:migrate,但部署后仅在一台机器上。

有人有这方面的经验吗?

谢谢

您可以通过 Amazon ECS 一次性任务完成。

  1. 在您的 docker 文件中使用 rake db migrate as "CMD" 构建一个 docker 图像。
  2. 创建任务定义。您可以在创建任务定义和所需任务编号时为每个主机选择一个任务。
  3. 运行 集群内的一次性 ECS 任务。确保将其设为外部服务。一旦它完成任务,容器将自动停止。

您可以在部署之前编写脚本来执行此操作。之后,您可以像往常一样定义其他任务。

您还可以在此处参考 Amazon ECS 中的容器生命周期:http://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_life_cycle.html。但是,这是 docker.

的默认行为

让我知道它是否适合你。

我在 docker 容器启动时为 运行 构建了自定义 shell 脚本(docker 中的 CMD 命令):

#!/bin/sh

web_env=${WEB_ENV:-1}
rails_env=${RAILS_ENV:-staging}
rails_host=${HOST:-'https://www.example.com'}

echo "*****************RAILS_ENV is $RAILS_ENV default to $rails_env"
echo "***************** WEB_ENV is $WEB_ENV default to $web_env"

######## Rails migration ################################################
echo "Start rails migration"
echo "cd /home/app/example && bundle exec rake db:migrate RAILS_ENV=$rails_env"

cd /home/app/example
bundle exec rake db:migrate RAILS_ENV=$rails_env
echo "Complete migration"


if [ "$web_env" = "1" ]; then

  ######## Generate webapp.conf##########################################
  web_app=/etc/nginx/sites-enabled/webapp.conf

  replace_rails_env="s~{{rails_env}}~${rails_env}~g"
  replace_rails_host="s~{{rails_host}}~${rails_host}~g"

  # sed: -i may not be used with stdin in MacOsX
  # Edit files in-place, saving backups with the specified extension.
  # If a zero-length extension is given, no backup will be saved.
  # we use -i.back as backup file for linux and
  # In Macosx require the backup to be specified.
  sed -i.back  -e $replace_rails_env -e $replace_rails_host $web_app
  rm "${web_app}.back" # remove webapp.conf.back cause nginx to fail.
  # sed -i.back  $replace_rails_host $web_app
  # sed -i.back  $replace_rails_server_name $web_app

  ######## Enable Web app ################################################
  echo "Web app: enable nginx + passenger: rm -f /etc/service/nginx/down"
  rm -f /etc/service/nginx/down

else
  ######## Create Daemon for background process ##########################
  echo "Sidekiq service enable: /etc/service/sidekiq/run "
  mkdir /etc/service/sidekiq
  touch /etc/service/sidekiq/run
  chmod +x /etc/service/sidekiq/run

  echo "#!/bin/sh" > /etc/service/sidekiq/run
  echo "cd /home/app/example && bundle exec sidekiq -e ${rails_env}" >> /etc/service/sidekiq/run
fi

echo ######## Custom Service setup properly"

我所做的是构建一个 docker 图像作为 Web 服务器(Nginx + passenger)或 Sidekiq 后台进程。该脚本将通过 ENV 变量 WEB_ENV 决定它是 Web 还是 Sidekiq,并且 rails 迁移将始终执行。

这样我就可以确保迁移始终是最新的。我认为这对于单个任务非常有效。

我使用的是 Passenger docker,它的设计非常易于定制,但如果您使用另一个 rails 应用服务器,您可以学习 Passenger 的 docker 设计以应用于您自己的 docker 设计。

例如,您可以尝试这样的操作:

在您的 Dockerfile 中:

CMD ["/start.sh"]

然后创建一个 start.sh 并在其中放置要执行的命令:

start.sh

#! /usr/bin/env bash

echo "Migrating the database..."
rake db:migrate