kamal 的部署流程中好像也没有单独提到 db:migrate 这种操作的执行时机,特别是在多台机器分布式部署的时候,官方文档里找了一圈也没看到有什么最佳实践。
通常本地环境开发调试完毕之后,大家会在什么地方对线上环境做 migrate 呢?
在 Rails 默认生成的项目中在,在 bin/docker-entrypoint 文件中,容器启动时,自动执行 migrate 的:
# If running the rails server then create or migrate existing database
if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then
./bin/rails db:prepare
fi
改了一下描述,不是说这个时间,而是说部署的时候,rails 默认是启动容器的时候运行 migrate,分布式部署多台机器就会运行多次,如果凑巧同时运行了是不是存在风险的
rails/activerecord/lib/active_record/migration.rb
看源码这里如果强锁失败会报错的,不会影响容器启动吗?
默认 entrypoint 是带 -e 的,所以除了执行迁移的容器其他容器会启动失败。然后 kamal 会隔几秒重试启动,直到超过重试次数。容器启动后健康检查通过才会替换旧容器。
如果有超长时间的迁移,可以关注维护模式这个新功能(未发布) https://github.com/basecamp/kamal/pull/1497