在具有多个容器实例的Docker容器中运行带有Rails的迁移 [英] Running migrations with Rails in a Docker container with multiple container instances

查看:94
本文介绍了在具有多个容器实例的Docker容器中运行带有Rails的迁移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到很多关于为Rails应用程序制作Docker容器的例子。通常,它们运行rails服务器,并且具有运行迁移/安装程序的CMD,然后启动Rails服务器。



如果我同时产生5个这些容器,Rails如何处理多个尝试启动迁移的进程?我可以看到Rails检查一般查询日志中的当前模式版本(它是一个MySQL数据库):

  SELECT`schema_migrations`。 `version` FROM`schema_migrations` 

但是,如果发生这种情况,我可以看到一个竞争条件时间在不同的Rails实例上。



考虑到DDL在MySQL中不是事务性的,并且在运行迁移时不会在常规查询日志中发生任何锁每个迁移交易),似乎并行踢他们将是一个坏主意。事实上,如果我在本地三次启动它,我可以看到两个rails实例崩溃时尝试创建一个表,因为它已经存在,而第三个rails实例快速完成迁移。如果这是将数据插入到数据库中的迁移,那将是非常不安全的。



那么运行一个运行迁移/安装程序的单个容器是一个更好的主意,然后产生(例如)一个独角兽实例,反过来又产生多个轨道工作者?



我应该生成N rails容器和运行迁移的一个迁移容器,然后退出?



有更好的选择吗?

解决方案

没有任何经验,但是从码头工程师和软件工程的角度来看,我们来看看。



Docker团队有时主动地主张集装箱关于运送应用程序。在这个很棒的说法,杰罗姆·佩塔佐尼(Jerome Petazzoni)说,这一切都是关注问题的分离。我觉得这正是您已经想到的一点了。



运行一个启动迁移或设置的rails容器可能对初始部署有好处,可能在开发过程中经常需要。但是,在开始生产时,您应该考虑分开这些问题。



因此,我会说有一个图像,用于运行N rails容器并添加一个工具/ migration / setup任何容器,用于执行管理任务。看看官方栏目图片的开发人员对此有何看法?


它被设计为既可用作丢弃容器(装载源代码并启动容器启动应用程序),也可用于构建其他映像


当您看到该图像时,没有设置或迁移命令。完全由用户使用它来使用。所以当你需要运行几个容器就可以了。



根据我对 mysql 的体验,这个工作正常。您可以运行一个仅数据的容器托管数据,运行与mysql服务器的容器,最后运行一个容器用于管理任务,如备份和恢复。对于所有三个容器,您可以使用相同的图像。现在,您可以从几个 Wordpress 容器访问数据库。这意味着明确的关切问题。当您使用 docker-compose 时,管理所有这些容器并不困难。当然,已经有很多第三方容器和工具来支持您设置一个由几个容器组成的复杂应用程序。



最后,您应该决定是否停靠码头和微服务架构适合您的问题。如这篇文章所述,有一些原因。其中一个核心问题是增加了一整套复杂性。然而,许多解决方案就是这种情况,我想你知道这一点,并愿意除此之外。


I've seen lots of examples of making Docker containers for Rails applications. Typically they run a rails server and have a CMD that runs migrations/setup then brings up the Rails server.

If I'm spawning 5 of these containers at the same time, how does Rails handle multiple processes trying to initiate the migrations? I can see Rails checking the current schema version in the general query log (it's a MySQL database):

 SELECT `schema_migrations`.`version` FROM `schema_migrations`

But I can see a race condition here if this happens at the same time on different Rails instances.

Considering that DDL is not transactional in MySQL and I don't see any locks happening in the general query log while running migrations (other than the per-migration transactions), it would seem that kicking them off in parallel would be a bad idea. In fact if I kick this off three times locally I can see two of the rails instances crashing when trying to create a table because it already exists while the third rails instance completes the migrations happily. If this was a migration that inserted something into the database it would be quite unsafe.

Is it then a better idea to run a single container that runs migrations/setup then spawns (for example) a Unicorn instance which in turn spawns multiple rails workers?

Should I be spawning N rails containers and one 'migration container' that runs the migration then exits?

Is there a better option?

解决方案

Especially with Rails I don't have any experience, but let's look from a docker and software engineering point of view.

The Docker team advocates, sometimes quite aggressively, that containers are about shipping applications. In this really great statement, Jerome Petazzoni says that it is all about separation of concerns. I feel that this is exactly the point you already figured out.

Running a rails container which starts a migration or setup might be good for initial deployment and probably often required during development. However, when going into production, you really should consider separating the concerns.

Thus I would say have one image, which you use to run N rails container and add a tools/migration/setup whatever container, which you use to do administrative tasks. Have a look what the developers from the official rails image say about this:

It is designed to be used both as a throw away container (mount your source code and start the container to start your app), as well as the base to build other images off of.

When you look at that image there is no setup or migration command. It is totally up to the user how to use it. So when you need to run several containers just go ahead.

From my experience with mysql this works fine. You can run a data-only container to host the data, run a container with the mysql server and finally run a container for administrative tasks like backup and restore. For all three containers you can use the same image. Now you are free to access your database from let's say several Wordpress containers. This means clear separation of concerns. When you use docker-compose it is not that difficult to manage all those containers. Certainly there are already many third party containers and tools to also support you with setting up a complex application consisting of several containers.

Finally, you should decide whether docker and the micro-service architecture is right for your problem. As outlined in this article there are some reasons against. One of the core problems being that it adds a whole new layer of complexity. However, that is the case with many solutions and I guess you are aware of this and willing to except it.

这篇关于在具有多个容器实例的Docker容器中运行带有Rails的迁移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆