部署 有人使用 Docker 来简化部署 Rails 的吗?

tangmonk · 2016年04月11日 · 最后由 lvjian700 回复于 2016年04月21日 · 7637 次阅读

请问在使用过程中有没有遇到什么问题呢,比如说每次更新服务端的代码的时候,是不是还要重新 build 一个 image,再运行这个 container 呢? 如果使用 nginx container + rails container 的话,如何使用 nginx container 来处理 rails container 中的 assets 呢?

build 的话一般啊在远程仓库完成,文件共享的话用 volume

一个 volume 放代码,需要的时候创建一个 container,略繁琐。 image 只包含运行环境,不包含业务代码。

#1 楼 @embbnux 远程仓库完成 build? 是用类似 Travis CI 的服务吗?

#2 楼 @liwei78 源码还是放在主机上,然后源码映射到 nginx 和 rails container 上?

说实话 Rails 的 Devops 工具还挺完整的,我试过 Docker,感觉反而还不如 mina 来的方便

#5 楼 @numbcoder 酱紫啊。。那不折腾了。。

我的理解 Rails 项目用上 docker 不会带来太明显的优势,而且 Rails 本身就是 full stack,不太可能只更新单独的组件。 如果为了一致性,用 deb 包就够了,比 docker 更多功能。

docker-passenger

我是 docker 新手。好像 docker 的最佳实践就是每次重新 build

#7 楼 @huacnlee 就算简化成一个脚本,用 docker 做横向扩展的便捷性还是不能替代吧……

docker 一般建议 nginx+passenger/puma/... + 服务打包在一个 container 里面,作为一个随时可以工作的整体来发布。

我们目前的做法是:bundle 依赖包的 path 放在项目目录下,打包的过程可以放在 jenkins 上,jenkins 环境配成和 docker 内部一样,通过 jenkins 做 bundle,然后把项目文件 + 依赖直接 copy 入 container 打包。

日志文件需要通过日志归集服务统一做收集。

总的来说是有一定成本的,应用需要考虑成本和收益是否合算,我们因为微服务拆分的比较多,也有动态扩容的需求,所以在往这个方向走。如果只是做单一网站这种需求,并不建议这么做。

确实每次更新代码的时候要重新 build image。至于是 docker 好还是用 capistrano/mina,就看项目复杂度、需要的伸缩性能力了,项目复杂或者经常有加机器的需求的话,让你用 capistrano/mina 你都不会用的。。

#13 楼 @tony612 其实也可以直接把搭好的系统环境直接做成一个 image,需要加新机器的时候,直接用这个 image 就可以

#14 楼 @numbcoder 对,我也这样用过。对不怎么经常更新的项目到还好。要是一天更新 10 几次,有时候还需要和开发人员断点调试,那就麻烦了。。

我是在自己的工具项目上用到了 docker,所以没有访问压力,直接让 rails 服务 static files 就可以了。

不过在真实、复杂的线上产品中,可能让构建系统把静态文件输出到 CDN 上更合适。

我们还是没有找到方便的 zero downtime deploy 的办法。

对于不需要这个特性的项目,docker-compose 已经做的不错了。我们的 测试 和 QA 环境是用 docker-compose 部署的。GitHub 上代码一旦更新,会 trigger DockerHub 的 autobuild,然后 compose 就可以引用了。

我们还有一个 compose 文件,提供了完整的 development dependency。在 docker 里面开发 Rails 项目还是有点麻烦,但是我们的 development compose 包含了所有的依赖,比如 PG、redis、elasticsearch 和我们自己的 micro service 等。新人搭建开发环境非常快速。

Staging 和 production 是用 Ansible 来 provision 的,Ansible playbook 一跑,然后就可以直接 cap deploy 了。还挺好用的。

我们的做法是把 image 作为交付单位的,dev 开发完推上代码仓库,SCM 抓代码 build image,然后调度上 container。现在使用 docker 后,感觉最大的问题是以下几个命令

npm install
bower install
docker pull/push
git pull/push
bundle install
mvn install

谁用谁知道

现在用阿里云部署,构建过程各种网络问题,我也想用 docker 打包一个镜像然后发布了。

#19 楼 @rei 阿里云上有 Docker 了,可以先试试

#19 楼 @rei 如果 rei 也是在阿里云上机器做一堆 build,然后 image build 再在 container run 的话,这真的是炼狱模式。 我们曾经选过很多种方案来解决这个问题,首先我们的环境是下图这样的,LB 后接了 ECS 上跑 Docker Container。

美 (zuo) 丽 (si) 的计划 1.0

1.在开发环境上调度 jenkins 的 SCM 或者其他规则来触发 slave 机上的 build docker image; 2.然后用 docker push 然后推到一个私有的 register 上 3.使用集群工具调度部署的容器来更新与重启。 然后我们操作中纠结了……我们是不希望 ECS 有流出流量去外网访问 private 的……

更 (zuo) 美 (da) 丽 (si) 的计划 2.0

我们想,要不我们放一台有外网的机器负责调度所有的节点更新呗? 然后发现 docker 的 register 真的是挺深的坑,在整个部署环节我至少还需要考虑回滚,更新,版本控制等一些列问题,只是给我一个仓库啥的完全没用…… 正在我们欢乐地“浪费”几个工作日后,突然有个童鞋弱弱的说声,要不我们就导出 image ftp 过去更新呗……

docker export
docker import

经过以上一系列完 (zuo) 美 (si) 的尝试,得出以下一些不太成熟的认知: 1) 在 docker container 数量和类型不够多的时候,收益不大 2) 用了 docker 不进行持续集成和持续部署,就好比做了敏捷开发不去写测试用例一样变扭; 3) 如果整个流程跑通了,运维部署的同学每天就只要刷刷 B 站好了; 4) 数据库部分个人觉得还是不要 Docker 化了,找问题各种麻烦

昨天刚弄完一个 Java(基于 Spring)的 docker 部署,基于官方的 tomcat 镜像,十分方便

Rails 如果基于自定义的一个 ruby 镜像,多环境、多分支、扩展这些也都不是事了

非常看好 docker 这种模式

#21 楼 @akirapanda 1.0 版为什么不能允许 ECS 有流出流量去外网访问 private 仓库?难道要收费?

我们的流程: Codebase -> Git -> Rspec -> build docker -> push to docker registry(自建) -> deploy (AWS Cloud formation Stack)

在 AWS Cloud formation Stack 中的 launch configuration 中 setup 各种 docker image.

比如:

  • Nginx
  • Rails app
  • ... bala bala ....

一些比较重要的实践:

  • 持续集成 (CI) 和持续部署 (CD) 的 pipeline
  • 使用 docker-compose 运行 CI,比如 rails-app-image + db-image
  • 网络要好
需要 登录 后方可回复, 如果你还没有账号请 注册新账号