Rails 在 ECS 上迁移
Rails migration on ECS
我正在尝试弄清楚如何在我的 ECS 服务上 运行 rake db:migrate
,但部署后仅在一台机器上。
有人有这方面的经验吗?
谢谢
您可以通过 Amazon ECS 一次性任务完成。
- 在您的 docker 文件中使用 rake db migrate as "CMD" 构建一个 docker 图像。
- 创建任务定义。您可以在创建任务定义和所需任务编号时为每个主机选择一个任务。
- 运行 集群内的一次性 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
我正在尝试弄清楚如何在我的 ECS 服务上 运行 rake db:migrate
,但部署后仅在一台机器上。
有人有这方面的经验吗?
谢谢
您可以通过 Amazon ECS 一次性任务完成。
- 在您的 docker 文件中使用 rake db migrate as "CMD" 构建一个 docker 图像。
- 创建任务定义。您可以在创建任务定义和所需任务编号时为每个主机选择一个任务。
- 运行 集群内的一次性 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