最近看到很多文章,很多人在容器里跑 rails 的时候仍然使用开发模式。
我这里要提醒一下,在这样做的时候你是否想过为什么要三个模式(环境)?
区分模式的优势:
既然在用了容器,就应该发挥容器的优势,尽量用环境变量而不是模式来区分系统不同的行为,这里也想听听大家的意见。
同意
不过话说,环境和 docker 是两个不同的概念,用 docker 来区分环境还是有环境。
我不认为在业务代码中根据环境的不同来执行不同的逻辑是一个好的实践。这个只能偶尔用用,并且需要被当做技术债务在将来清理掉。
首先环境区分是有意义的,除了你上面提到的点还有更多,比如支付区分沙盒环境和生产环境等等,不区分会一团糟。
如果这些配置很多,全部通过环境变量传递和使用是一个很大的负担,麻烦而且容易出错,不如和代码放在一起,还可以有完整的版本控制。
不过,的确有一些敏感信息(如密码)基于安全考虑不适合放配置文件里,这种配置可以用环境变量。
没必要为了 docker 削足适履,这是我的看法。
我没搞过容器里面开发啊,环境变量能统一一次切换?
但我认为分环境是为了让某些非配置化的实现能让环境区分来处理,例如:
if Rails.env.development?
do_some_thing_just_only_need_in_development
end
以及统一配置化,所有的配置都写好了,在多人开发的时候谁来下来,配置都是相同的,要切换环境,仅需要一个点(RAILS_ENV=xxx) 就能搞定。
容器开发可以用 docker-compose 里面的 envfile 来切换,https://docs.docker.com/compose/environment-variables/#setting-environment-variables-in-containers 不过在 docker-compose 启动的时候不能指定 envfile
分环境容易带来的问题是环境承载了太多东西,比如开发模式下可能会指定不同的数据库,不同的支付网关,而这些原本用环境变量就可以解决。
正确的方法应该是 docker-compose 也做成三个环境,可以分别使用 git 分支管理,生产环境部署就切换到 docker 的生产环境配置
环境变量和模式是两个维度的东西。
模式解决的是开发、测试、生产行为模式不同的问题,自然包括环境变量的不同,也包括行为模式的不同,比如你提到的懒加载。
环境变量解决了 release
= code base
+ env
的问题。
其实 Rails 里也可以直接通过 env 来设置数据库链接了,两者不冲突。网关配置也可以用dotenv之类来管理。
Rails 包括其他框架的环境是起到 配置分组 的作用,从高层一点来理解,环境是按 使用场景 来分组的,毕竟每个场景所使用的配置项都差不多,指定一个环境名比设置多个环境变量更方便。
少数情况下会出现同类型的使用场景需要不同的配置项,最典型的是数据库等外部服务的配置。这个时候把少数配置抽成环境变量更加灵活。
你目的是尽量减少各环境的差别,但是它们还是有区别的
开发环境的基本需求就是改一点就马上能看到一点效果. 对于 Rails 来说,可以 eager load 然后通过监听文件系统事件来重载对应文件 (就和 webpack 一样), 这样开发环境和生产环境就都能统一到 eager load 了。
Docker 这一套在 Linux 上开发是最流畅的。但你如果换别的操作系统,在容器里文件系统事件往往比原生事件慢几百倍,甚至还不一定有文件系统事件 ... 在容器开发只能回到 lazy load... 这时不在容器开发反而可以更容易一致...
我觉得容器更适合做编译型语言的开发,尤其是做不了热重载的语言。而虚拟机语言其实和容器是有不少功能重复的地方的
好吧,我也发现了,我本地开发搞个 development 的 docker 一阵子了,但感觉真是没有卵用。不过 staging 容器要有的,我用的生产的数据的拷贝,而且,设置里面,将请求设为本地请求那个参数,设为 true,大家懂的。😜
补充,主要是本地 Linux 已经有环境了,觉得 APP 的 容器有点多余,要在环境隔离,一致性的角度说,开发容器也蛮有用的。不过,你得像我一样,搞个万能的 docker_bash 脚本了,不管容器挂了还是什么异常,你总能进去,毕竟,你不总是改 APP,也会改其他,哦,你还得 mount 一个编辑器进去,你不想吧编辑器放到容器里吧!
我感觉我不需要 Docker。。。在本地开发是我一直倾向于原生(Rails 直接跑在 Windows/MacOS 上),发布时我更倾向于选择可以快速发布的工具(Docker 发布比 Capistrano 慢),跑生产时我倾向于便宜(Docker 好像还是比 VPS 贵)。
虽然我这样说会很打击 Docker,但我觉得 Go 是一门好语言,因为平均工资高。。。
基本同意题主,个人和小型项目随意
另外附上本人一些想法:
当然并不是非容器不可,只是觉得这是个好东西