部署 使用 dokku 部署你的 Rails 应用

pynix · 2017年03月14日 · 最后由 pynix 回复于 2017年04月21日 · 3269 次阅读
本帖已被设为精华帖!

背景: 在读一些英文教程的时候时不时被安利heroku这个部署环境,于是在自己团队的项目也用上了,有人说很贵,用下来没感觉很贵,更致命的问题是慢,比如一些支付场景,api需要绕地球2圈才能回到用户终端,结果就是调起支付需要等待5秒甚至10秒。

在用户多次反馈后,终于下定决心搬回国内。于是在国内找heroku代替品。BAE,SAE各种AE都很鸡肋,XXPaSS也找了几个,很不给力。在国内还是只能买到IaSS,于是上社区找部署文章,大部分是手动安装rbenv,rvm什么的。太麻烦了,能不能有点自动化的? 最好还能git部署。

经过搜索发现了Dokku,一个基于容器的最小PaSS实现。

Dokku

安装

按照官方文档使用bootstrap脚本安装,发现走不下去,看错误信息是GFVV惹的祸。于是使用apt方式安装,安装完docker之后修改镜像,貌似国内有daocloud提供。

安装docker wget -nv -O - https://get.docker.com/ | sh

修改docker配置 vim /etc/default/docker

DOCKER_OPTS="--registry-mirror=http://xxxxxxxx.m.daocloud.io"

安装dokku

wget -nv -O - https://packagecloud.io/gpg.key | apt-key add -
export SOURCE="https://packagecloud.io/dokku/dokku/ubuntu/"
echo "deb $SOURCE trusty main" | tee /etc/apt/sources.list.d/dokku.list
apt-get update
apt-get install dokku
dokku plugin:install-dependencies --core

配置

安装完成后会启动一个http-server 提供web方式的配置,浏览器输入服务器ip打开页面,输入公钥和域名就OK。

使用

服务端使用除了全局命令外大部分需要指定app的名字才能运行。所以推荐使用客户端的方式。

dokku client

把脚本扔到PATH改名为dokku,另外在设置公钥的时候需要客户端的公钥哦。

在服务端创建好一个app,在客户端设置好git romote后就可以部署了。

服务端 dokku apps:create demo

客户端 git remote add dokku dokku@example.com:demo

部署 git push dokku master

buildpack

dokku使用的是heroku的buildpack,因为GFVV的问题,安装runtime的时候总是出现超时。我的解决方案是fork一个buildpack,然后修改其中的url为环境变量,再把环境变量设置为七牛的bucket。

数据库

有 postgresql的插件,应该也有mysql,mongodb,redis之类的。

创建数据库 dokku postgres:create demo-db

连接到app dokku postgres:link demo-db

link会在app设置 DATABASE_URL,所以database.yml里需要使用 url的方式配置。

维护模式

heroku 有 maintenance mode ,搜了一下dokku也有插件。

maintenance:on | off

HTTPS

有letsencrypt的插件,使用超级很方便。

dokku config:set --no-restart DOKKU_LETSENCRYPT_EMAIL=your@email.tld

dokku letsencrypt

常用命令

环境变量 dokku config

example : dokku config:set APP_ID=xxxxxxxx

运行 dokku run

example:

dokku run rails c

dokku run rake db:migrate

总结

如果你还在纠结到底使用rvm还是rbenv,还在手动配置nginx,不妨来试试这种部署方式,只需要在Gemfile中指定ruby版本,剩下的一切都交给工具。这才是正确的部署姿势。

update 1

dokku目前的优势是多app部署非常方便,像我们团队同时在弄几个小的项目,创建一个app,部署完成,就能通过子域名来访问应用。

update2

dokku 的限制:

  • 暂无集群支持计划。

  • 升级dokku需要停止所有app

dokku 适用场合:

  • 1-5人小团队
  • (多个)初期项目
  • 频繁部署
  • 开发很懒
共收到 22 条回复

补充一个:

自动migrate

我们在根目录下添加一个app.json文件。

{
  "name": "yourapp",
  "description": "App description",
  "keywords": [
    "dokku",
    "rails",
    "app-name"
  ],
  "scripts": {
    "dokku": {
      "postdeploy": "bundle exec rake db:migrate"
    }
  }
}

这样每次deploy完之后都会自动运行一下 bundle exec rake db:migrate文件。

jimmy0017 回复

也可以通过buildpack来完成,以前在heroku用过。。

pynix 回复

楼主,你好,谢谢你的教程。其中 buildpack 部分没有弄好,想请教下具体过程?

pinewong 回复

dokku 使用heroku官方buildpack,但是s3无法访问导致runtime安装失败。

这是我的buildpack相关的 config

BUILDPACK_URL:                      https://github.com/pynixwang/heroku-buildpack-ruby.git
BUILDPACK_VENDOR_URL:               http://oijrx1ifp.bkt.clouddn.com/heroku-buildpack-ruby

第一个修改了nodejs的镜像,具体可以看diff。 VENDOR使用七牛镜像了S3上的一些二进制,如ruby安装包。

pynix 回复

🙏非常感谢,正是需要这个,速度已经提上来了。对了,第二个是自己去 s3 中下载全部文件然后传到七牛的吗?

pinewong 回复

不用,七牛自动镜像。只需要在七牛创建一个桶,在镜像设置里面填写s3 域名,然后使用的时候把域名换成七牛即可。

噢噢,这样👌

现在是直接用容器部署了

alex_l_zhang 回复

dokku是自动化容器。。。

pynix 回复

PaaS的优势对比容器确实不明显

nouse 回复

没有实践过容器部署。dokku只是生态相对完善的容器吧,有一系列插件可用,不必每个组件都自己构建。

pynix 回复

“不需要每个组件自己构建”在我看来就是伪需求,难道帮你执行bundle install就是自动化了吗?而且docker有onbuild镜像做这个事情。

nouse 回复

好吧,真没有实践过。。。。。

这个 dokku 我之前有看过,似乎不太支持集群吧?当时我还特意问了他们的开发计划,也说没有这个方面的发展。

hosts 文件不能使用通配符,所以不能将一个域名的所有二级域名解析到本地,还有别的办法吗?(试过 dnsmasq,在 10.11 下一直无效)

huacnlee 将本帖设为了精华贴 04月09日 23:10
aisensiy 回复

买了一台高配机器,什么都往里面放了。反正项目初期不会爆炸。。。

pinewong 回复

我在服务端使用的,开发环境没有用容器。。。。

pynix 回复

主要手里没好点的服务器,想在开发机器上用 vagrant 试

pinewong 回复

。。

pynix 回复

恩,如果是这样确实是可行的。不过我去查了之前的 issue 作者确实回复了不支持多机模式哦。

Typo: redies -> redis

aristotll 回复

已修改。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册