文档章节

自动化部署工具 Capistrano 与 Mina

风起云飞fir_im
 风起云飞fir_im
发布于 2015/08/20 18:00
字数 2072
阅读 85
收藏 0

最近折腾了一下 Capistrano 和 Mina 两个自动化部署工具, 总结一些个人的观点和经验.


Capistrano Capistrano

Capistrano(下文简称 Cap) 特别适合于 Rails 应用的自动化部署, 特别是 Cap3, 整合了很多与 Rails 相关自动部署的命令(可用 cap -T 查看).


0. 服务器目录结构

首先来看看经过多次部署后, 服务器会生成一个这样的目录结构

├── current -> /var/www/your_app/releases/20141201042659
├── releases
│   ├── 20141201032351
│   ├── 20141201042256
│   ├── 20141201042659
├── repo
│   ├── branches
│   ├── hooks
│   ├── info
│   ├── objects
│   └── refs
└── shared
    ├── bin
    ├── bundle
    ├── config
    ├── log
    ├── public
    ├── tmp
    └── vendor
  • current 是指当前版本, link 到 release 下的指定版本目录(默认为最新的 releases)

  • releases 每次部署都会产成一个目录存放项目源码, 目录个数由 :keep_releases 变量来控制

  • repo 项目的 .git 目录

  • shared 是项目中共享的内容, 不会随部署而改变


1. 安装 Cap

# Gemfile gem 'capistrano', '~> 3.2.0' gem 'capistrano-rails', '~> 1.1.0' gem 'capistrano-bundler', '~> 1.1.0' gem 'capistrano-rvm', '~> 0.1.0' gem 'capistrano3-unicorn', '~> 0.2.0' # Add this if you're using rbenv # gem 'capistrano-rbenv', '~> 2.0.0'

2. Cap install 生成相关部署文件

$ bundle install 之后执行 $ bundle exec cap install, 会自动生成以下几个文件

├── Capfile                   # Cap 配置文件
├── config
│   ├── deploy
│   │   ├── production.rb     # 不同环境的部署配置
│   │   └── staging.rb
│   └── deploy.rb             # 公共变量
└── lib
    └── capistrano
            └── tasks         # 一些自定义的 task

3. Capfile 文件

Cap 的配置文件, 可按需求加载一些插件

require 'capistrano/setup' # 加载 Cap 的 DSL require 'capistrano/deploy' # 加载 Cap 的 Workflow require 'capistrano/rvm' # 加载 RVM 相关配置 # require 'capistrano/rbenv' # 加载 Rbenv 相关配置 require 'capistrano/bundler' # 加载 Bundle, 以便完成 bundle install require 'capistrano/rails/assets' # 加载 Rails 的 js, css 文件预编译 require 'capistrano/rails/migrations' # 加载 Rails 的数据库自动迁移 require 'capistrano3/unicorn' # 加载 Unicorn 服务 Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

其中, require 'capistrano3/unicorn' 后, 会增加几个 Unicorn 的部署命令, 可在本地远程运行命令直接控制服务器 Unicorn 的服务

cap unicorn:add_worker # 增加一个 Unicorn Worker cap unicorn:duplicate # Restart cap unicorn:legacy_restart # 传统方式 Restart, 使用 USR2 + QUIT cap unicorn:reload # Reload cap unicorn:remove_worker # 减少一个 Unicorn Worker cap unicorn:restart # 无缝 Restart, 使用 USR2 cap unicorn:start # 启动 Unicorn cap unicorn:stop # 关闭 Unicorn (QUIT)

4. config/deploy.rb 文件

用来配置不同环境的一些公共变量

# config valid only for Capistrano 3.1 lock '3.2.1' set :application, 'your app name' # 设置部署项目的名字 set :repo_url, 'git@xxx.git' # 设置项目的 git repo set :deploy_to, "/var/www/xxx" # 设置部署目录 set :deploy_user, 'deploy' # 设置部署时的用户 set :scm, :git set :format, :pretty set :pty, true # linked_dirs # 是将项目的指定目录 link 到 shared 目录中, 这个操作会在从 repo 取下代码之后进行. # 比如 log 目录, 每次部署完毕后新的版本中的 log 目录都会 link 到 shared/log 下 set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system} # linked_files # 它是将 shared 目录中的文件 link 到项目中, 文件要首先存在于 shared 目录中, 不然 deploy 时会报错 # 在 Rails 项目中, 主要就是 database.yml, secret.yml 这样的敏感文件 set :linked_files, %w{config/database.yml} # rvm_type # :auto (default): just tries to find the correct path. ~/.rvm wins over /usr/local/rvm # :system: defines the RVM path to /usr/local/rvm # :user: defines the RVM path to ~/.rvm set :rvm_type, :system set :rvm_ruby_version, '2.1.2' set :rvm_roles, [:app, :web, :db] set :keep_releases, 10 # 最多存放十个部署版本 namespace :deploy do # 自定义了一个部署任务, 即自动运行 rake RAILS_ENV=rails_env db:create # 其中 release_path 指的是当前 release 目录 # `fetch(:rails_env)` 读取配置中的 rails_env 变量, 并在 rake 命令中带上 env 变量 task :create_database do on roles(:db) do within release_path do with rails_env: fetch(:rails_env) do execute :rake, 'db:create' end end end end before :migrate, :create_database # 在每次 rake db:migrate 前都运行 rake db:create after :finishing, 'deploy:cleanup' # 在每次部署完毕后, 清理部署时生成的 tmp 文件及多余的版本 end

这里有几个细节需要特别注意:

  • deploy_user 一定需要有 /var/www/[deploy_to] 的权限, 在自动化部署中, 部署者的权限是个很重要的因素!

  • deploy_user 建议使用 id_rsa.pub authorized_keys 的方式进行免密码登陆, 这也是 cap3 中推荐的方法

  • 首次部署, 需要执行 cap [environment] deploy:check 命令, 把 linked_files 在服务器上创建!

  • 首次部署, 如果用 Mysql 的话, 服务器上是没有 database 的, 需要自己手动 rake db:create, 这里我写了个 create_database 的 task 来执行 rake db:create

  • rvm 与 rbenv 的安装路径一定要确认, 是在 root 下安装的还是在 deploy_user 下安装的, 这里强烈建议用 deploy_user 安装 rvm/rbenv, 并且把 /var/www 文件夹的权限赋予deploy_user, 这样会少走很多弯路


5. config/deploy/production.rb | staging.rb

Cap 中的运行环境(又称 Stage ), 默认建立了2个 Stage, 不同的 Stage 可以定义一些专有的变量, 并可以重写 deploy.rb 中定义的公共变量, 相当于不同环境下对应不同的服务器.

# Production Stage set :stage, :production # 设置 stage set :branch, 'master' # 设置 git branch set :rails_env, :production # 设置 rails_env # 以下几个 server 会同时部署 server 'xxx.xxx.xxx.xxx', user: 'deploy', roles: %w(web app db), primary: true server 'xxx.xxx.xxx.xxx', user: 'deploy', roles: %w(web app db)

这里需要说明的是 roles 的定义, 在 Cap 中, 不同的 server 是可以有不同的 role 的, 一些服务器负责 web 服务, 一些服务器负责 db 服务, 从上面的自定义 create_database 命令中, 可以看到, on roles(:db), 说明这条命令只有在指定了 role 为 db 的服务器上运行.

这里讲的是多台服务器同时部署, 那么如何实现多台服务器依次部署呢? 只要再写一个 Stage, 运行指定的 stage 就可以了


6. Cap Flow

部署的时候执行命令, cap [environment] deploy, Cap 会自动执行一系列 Task, 这些 Task 被称为 Cap Flow, 每个 Task 都可以通过 before 和 after 来添加自定义的 Task.

deploy
  deploy:starting [before] deploy:ensure_stage
      deploy:set_shared_assets
    deploy:check # 检查 ssh, rvm/rbenv, linked_dirs, linked_files, git deploy:started
  deploy:updating
    git:create_release
    deploy:symlink:shared
  deploy:updated [before] deploy:bundle # 重新 bundle install [after] deploy:migrate # rake db:migrate deploy:compile_assets
      deploy:normalize_assets
  deploy:publishing
    deploy:symlink:release
    deploy:restart # restart, 可自定义一些需要 restart 的服务 deploy:published
  deploy:finishing
    deploy:cleanup
  deploy:finished
    deploy:log_revision

7. Cap stage deploy

最后 show 一张运行 cap [environment] deploy 命令部署成功后的图片

Capistrano Deploy


Mina Mina


Mina 相对于 Cap 来说, 较为简洁, 只有基本的几个 Task(可用 mina -T 查看), 有点 Sinatra VS Rails 的感觉, 其服务器部署结构与 Cap 类似.


1. 安装 Mina

# Gemfile gem 'mina', '~> 0.3'

2. Mina init

$ bundle install 之后执行 $ mina init, 会生成 config/deploy.rb 文件, 定义了一系列的变量和 Task.

require 'mina/bundler' require 'mina/rails' require 'mina/git' # require 'mina/rbenv' # for rbenv support. (http://rbenv.org) # require 'mina/rvm' # for rvm support. (http://rvm.io) # Basic settings: # domain - The hostname to SSH to. # deploy_to - Path to deploy into. # repository - Git repo to clone from. (needed by mina/git) # branch - Branch name to deploy. (needed by mina/git) set :domain, 'foobar.com' set :deploy_to, '/var/www/foobar.com' set :repository, 'git://...' set :branch, 'master' # Manually create these paths in shared/ (eg: shared/config/database.yml) in your server. # They will be linked in the 'deploy:link_shared_paths' step. set :shared_paths, ['config/database.yml', 'log'] # Optional settings: # set :user, 'foobar' # Username in the server to SSH to. # set :port, '30000' # SSH port number. # This task is the environment that is loaded for most commands, such as # `mina deploy` or `mina rake`. task :environment do # If you're using rbenv, use this to load the rbenv environment. # Be sure to commit your .rbenv-version to your repository. # invoke :'rbenv:load' # For those using RVM, use this to load an RVM version@gemset. # invoke :'rvm:use[ruby-1.9.3-p125@default]' end # Put any custom mkdir's in here for when `mina setup` is ran. # For Rails apps, we'll make some of the shared paths that are shared between # all releases. task :setup => :environment do queue! %[mkdir -p "#{deploy_to}/shared/log"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"] queue! %[mkdir -p "#{deploy_to}/shared/config"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"] queue! %[touch "#{deploy_to}/shared/config/database.yml"] queue %[echo "-----> Be sure to edit 'shared/config/database.yml'."] end desc "Deploys the current version to the server." task :deploy => :environment do deploy do # Put things that will set up an empty directory into a fully set-up # instance of your project. invoke :'git:clone' invoke :'deploy:link_shared_paths' invoke :'bundle:install' invoke :'rails:db_migrate' invoke :'rails:assets_precompile' to :launch do queue "touch #{deploy_to}/tmp/restart.txt" end end end # For help in making your deploy script, see the Mina documentation: # # - http://nadarei.co/mina # - http://nadarei.co/mina/tasks # - http://nadarei.co/mina/settings # - http://nadarei.co/mina/helpers

3. Mina setup

部署的前执行命令, mina setup, 创建 shared 文件夹, 在编辑需要 shared 的文件后, 再执行 mina deploy 就可以部署了, 非常的简洁.


REF

Capistrano 3 实现Rails自动化部署

Capistrano 3 Tutorial

Mina For Deployment

December 14, 2014

作者:Spirit

本文为FIR.im团队原创,转载请注明出处!

版权声明:本文为博主原创文章,未经博主允许不得转载。

© 著作权归作者所有

风起云飞fir_im
粉丝 46
博文 136
码字总数 143328
作品 1
朝阳
私信 提问
使用 capistrano 部署 Rails 应用

原文发表于: www.rails365.net 1. 介绍 本站有很多篇使用mina来部署的文章,但是相信一定有很多人是使用capistrano来部署rails应用的。所以本篇文章也来讲讲如何用capistrano部署ruby on rai...

随风良辰
2017/11/30
0
0
php的自动化部署用什么方法?

Phing,heroku,capistrano,etc 看着都晕了 (PS:不会ruby,所以不要用写ruby代码的) Phing是一个build工具,capistrano是一个部署工具,这又是什么意思...

帖子列表
2012/12/13
2.4K
1
Capistrano集群部署CloudFoundry

开源的cloudfoundry部署时有两个必须解决的问题,一是服务器部署,如多少个cc节点,dea节点,官方推荐用BOSH,由于BOSH比较依赖底层IAAS,于是采用了手动部署的方案。 另一个问题是,这么多节...

长平狐
2013/11/25
791
0
使用 Capistrano 进行快速部署

在进行 Rails 部署的时候你可以直接从 svn 或者 git 下面更新代码,运行 db:migrate 来进行数据库的更新,然后进行这样那样的操作后,再启动服务器,便可进行部署,即便你只有一台机器,你也...

红薯
2010/03/19
2.1K
3
Rails应用快速部署工具--Capistrano

Capistrano 是一个用来并行的在多台机器上执行相同命令的工具,使用用来安装一整批机器。它最初是被开发用来发布 Rails 应用的。 在进行 Rails 部署的时候你可以直接从 svn 或者 git 下面更新...

匿名
2009/06/08
5.9K
0

没有更多内容

加载失败,请刷新页面

加载更多

rime设置为默认简体

转载 https://github.com/ModerRAS/ModerRAS.github.io/blob/master/_posts/2018-11-07-rime%E8%AE%BE%E7%BD%AE%E4%B8%BA%E9%BB%98%E8%AE%A4%E7%AE%80%E4%BD%93.md 写在开始 我的Arch Linux上......

zhenruyan
今天
5
0
简述TCP的流量控制与拥塞控制

1. TCP流量控制 流量控制就是让发送方的发送速率不要太快,要让接收方来的及接收。 原理是通过确认报文中窗口字段来控制发送方的发送速率,发送方的发送窗口大小不能超过接收方给出窗口大小。...

鏡花水月
今天
9
0
OSChina 周日乱弹 —— 别问,问就是没空

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享容祖儿/彭羚的单曲《心淡》: 《心淡》- 容祖儿/彭羚 手机党少年们想听歌,请使劲儿戳(这里) @wqp0010 :周...

小小编辑
今天
953
11
golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.shtml?id=6 本文全部代码https://idea.techidea8....

非正式解决方案
今天
5
0
Spring Context 你真的懂了吗

今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识。 1. context 是什么 我们经常在编程中见到 context 这个单词,当...

Java知其所以然
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部