mina 一键部署到底做了什么

mina 部署操作十分简单,但对于初学者却不太容易理解,本文简单介绍 mina 的部署过程,方便初学者学习和理解。

Posted by Rina on 2017-12-27

打赏支持

写这篇文章的目的是为了让初学都更清楚的明白,一条命令就完成了部署,这其中到底做了什么。因为我一开始学习 Rails 的时候,配置完配置文件后只要能成功部署,就不会再去关心这个过程到底是怎么完成的。所以我相信有很多朋友可能和我一样没有过多了解这个发布的过程。

如果你还不知道使用 mina 如何部署,你可以先看一下我的上一篇关于 Rails布署最佳实践 , 再来看这篇文章。这样有利于你对文章内容的理解

当我执行

$ mina deploy

会输出以下内容:

-----> Creating a temporary build path
-----> Server: liuzhen.me
-----> Path: /home/ruby/RBlog
-----> Branch: master
-----> Using RVM environment "2.3.1"
       Using /home/ruby/.rvm/gems/ruby-2.3.1
-----> Using RVM environment "2.3.1"
       Using /home/ruby/.rvm/gems/ruby-2.3.1
-----> Quiet sidekiq (stop accepting new work)
       /home/ruby/RBlog/tmp/build-151495418728871
-----> Fetching new git commits
-----> Using git branch 'master'
       Cloning into '.'...
       done.
       perl: warning: Setting locale failed.
       perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LC_CTYPE = "zh_CN.UTF-8",
        LANG = "zh_CN.UTF-8"
           are supported and installed on your system.
       perl: warning: Falling back to the standard locale ("C").
       perl: warning: Setting locale failed.
       perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LC_CTYPE = "zh_CN.UTF-8",
        LANG = "zh_CN.UTF-8"
           are supported and installed on your system.
       perl: warning: Falling back to the standard locale ("C").
-----> Using this git commit
       liuzhenangel (19af0e0):
       > update css
-----> Symlinking shared paths
-----> Installing gem dependencies using Bundler
       Your Gemfile lists the gem byebug (>= 0) more than once.
       You should probably keep only one of them.
       While it's not a problem now, it could cause errors if you change the version of just one of them later.
       Warning: the running version of Bundler is older than the version that created the lockfile. We suggest you upgrade to the latest version of Bundler by running `gem install bundler`.
       Using rake 12.3.0
       ...
       Using browser_warrior 0.7.0
       Bundle complete! 43 Gemfile dependencies, 91 gems now installed.
       Gems in the groups development and test were not installed.
       Bundled gems are installed into ./vendor/bundle.
-----> DB migrations unchanged; skipping DB migration
-----> Skipping asset precompilation
-----> Cleaning up old releases (keeping 5)
       /home/ruby/RBlog/tmp/build-151495418728871
-----> Deploy finished
-----> Building
-----> Moving build to /home/ruby/RBlog/releases/49
-----> Build finished
-----> Launching
-----> Updating the /home/ruby/RBlog/current symlink
-----> Using RVM environment "2.3.1"
       Using /home/ruby/.rvm/gems/ruby-2.3.1
-----> Restart Puma -- hard...
-----> Stopping Puma...
       Command stop sent success
-----> Starting Puma...
       [18303] Puma starting in cluster mode...
       [18303] * Version 3.11.0 (ruby 2.3.1-p112), codename: Love Song
       [18303] * Min threads: 8, max threads: 16
       [18303] * Environment: production
       [18303] * Process workers: 2
       [18303] * Preloading application
       [18303] * Listening on unix:///home/ruby/RBlog/shared/tmp/sockets/puma.sock
       [18303] * Daemonizing...
-----> Stop sidekiq
       Sidekiq shut down gracefully.
       /home/ruby/RBlog/current
-----> Start sidekiq
       /home/ruby/RBlog/current
-----> Done. Deployed version 49
       Connection to liuzhen.me closed.

       Elapsed time: 17.12 seconds

过程解读:

* 根据配置用户及域名信息,执行 ssh 连接到服务器
* 创建一个零时构建目录   
* 告诉现在操作的服务器及目录信息 
* 发布对应的github代码分支是哪个
* 使用的 Ruby 版本
* 关闭 sidekiq
* 获取 github 最近一次的提交
* clone 代码
* 创建 shared 目录文件对应的软链接,这里还会将.git目录删除。
* 安装gem包
* 检查数据库表有无更新,如果有更新就执行rake db:migrate, 没有就忽略
* 检查图片, js, css有无更新,有更新就重新编译,css, js重新压缩。
* 清除老的发布版本,保留最新的 6 个
* 完成发布
* 创建 current 软链接至最新发布版本
* 重新加载 Ruby 环境
* 重启 Puam
* 重启 sidekiq
* 关闭 ssh 连接

看完过程解读,可能你会有疑问:

  1. 为什么一开始要创建一个零时构建目录?
  2. 为什么需要保留多个发布版本
  3. 为什么需要创建一个 current 软链接
  4. 为什么要删除.git目录

我们先来看看服务器上的目录结构:

这里有几个目录:

  • releases: 存放最新的 6 个发布版本
  • scm: 发布时会进入这个目录下拉取代码并安装gem,如果一切操作成功就会进入releases, 如果失败,就会删除之前的所有操作。
  • shared: 里面包含: config 配置文件, 日志, 公共的上传图片和css,js,图片。tmp: 存放当前的 pid 进程,cached, sockets.
  • tmp: 空

现在来回答上面提到的几个问题:

  1. 创建零时的构建目录是为了防止发布失败不会影响正式环境的使用。
  2. 保留多个版本如果发布成功,想要回到上个版本,可以快速回滚
  3. 使用 current 软链接,也有 (2) 里的原因,也是为了方便知道目前使用的哪个版本。
  4. 记得在生产环境中一定要删除 .git 目录,像php项目,如果发布后不删除.git, 用户通过访问你的域名可直接下载此文件, .git 文件一旦泄漏,相当于代码泄漏。

其他

如果你想对这个过程有更多的研究和了解可以通过 mina deploy -v 来查看具体的操作信息。

如果你对文章有什么问题或者想认识我,可以通过页面下方的二维码图标加我微信。