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

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

背景: 在读一些英文教程的时候时不时被安利 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 人小团队
  • (多个) 初期项目
  • 频繁部署
  • 开发很懒

补充一个:

自动 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 回复

已修改。

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