使用 Capistrano 进行远程部署

Captstrano

Captstrano 是一个Ruby世界中著名的用于远程部署的自动化工具。

安装

在 gem 里加入

gem 'capistrano', '~> 3.6'
gem 'capistrano-rails', '~> 1.1'
gem 'capistrano-bundler'
gem 'capistrano-rvm'
gem 'capistrano3-puma'
gem 'capistrano3-nginx'
gem 'capistrano-npm'
gem 'capistrano-postgresql'
gem "nokogiri"
gem 'capistrano-rbenv'
gem 'capistrano-upload-config'
gem 'engineyard', '~> 2.3'
$ bundle

工作目录结构

├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
    └── capistrano
            └── tasks

Captstrano 的发布目录结构

需要注意的一点是Captstrano 在生产服务器上的目录结构与开发环境目录是迥然不同的!以下是 Captstrano 发布后的目录结构。

.
├── current -> /var/www/uni_reporting/releases/20161019041358
├── db
│   └── database.yml
├── releases
│   └── 20161019041358
├── repo
│   ├── branches
│   ├── config
│   ├── description
│   ├── FETCH_HEAD
│   ├── HEAD
│   ├── hooks
│   ├── info
│   ├── objects
│   ├── packed-refs
│   └── refs
├── revisions.log
└── shared
    ├── bundle
    ├── config
    ├── log
    ├── public
    └── tmp

工作流程

生成数据库配置文件config/database.yml并上传到服务器

$ cap production setup # 由于引入 capistrano-postgresql 后加入的任务

开始部署

$ cap production deploy

Captstrano 的插件

必备插件

  • capistrano-puma
  • capistrano-nginx
  • capistrano-npm
  • capistrano-postgresql
00:00 postgresql:generate_database_yml_archetype
      01 mkdir -pv /var/www/<应用程序目录>/db
      01 mkdir: created directory ‘/var/www/<应用程序目录>
      01 mkdir: created directory ‘/var/www/<应用程序目录>/db’
    ✔ 01 uni@192.168.1.37 0.010s
      Uploading /var/www/<应用程序目录>/db/database.yml 100.0%
00:00 postgresql:generate_database_yml
      Downloading database.yml 100.0%
      01 mkdir -pv /var/www/<应用程序目录>/shared/config
      01 mkdir: created directory ‘/var/www/<应用程序目录>/shared’
      01 mkdir: created directory ‘/var/www/<应用程序目录>/shared/config’
    ✔ 01 uni@192.168.1.37 0.048s
      Uploading /var/www/<应用程序目录>/shared/config/database.yml 100.0%

技巧: cap <环境> doctor 的使用

安装

00:00 git:wrapper
      01 mkdir -p /tmp
    ✔ 01 uni@192.168.1.37 0.008s
      Uploading /tmp/git-ssh-uni_reporting-production-ray.sh 100.0%
      02 chmod 700 /tmp/git-ssh-uni_reporting-production-ray.sh
    ✔ 02 uni@192.168.1.37 0.008s
00:00 git:check
      01 git ls-remote --heads git@192.168.1.31:uni-reporting/uni-reporting.git
      01 825ee4ee695053b55156b2f0a973f7b32e4676b9   refs/heads/lixiaochan
      01 2479ac34266739f98f785728c8c25e932acbfb12   refs/heads/master
      01 10e05d77c2f13084233f26725174f53a822cce38   refs/heads/zhangyesheng
    ✔ 01 uni@192.168.1.37 30.843s
00:30 deploy:check:directories
      01 mkdir -p /var/www/uni_reporting/shared /var/www/uni_reporting/releases
    ✔ 01 uni@192.168.1.37 0.010s
00:30 deploy:check:linked_dirs
      01 mkdir -p /var/www/uni_reporting/shared/log /var/www/uni_reporting/shared/tmp/pids /var/www/uni_reporting/shared/tmp/cache /var/www/uni_reporting/shared/tmp/sockets /var/www/uni_reporting/shared/public/s…
    ✔ 01 uni@192.168.1.37 0.008s
00:30 deploy:check:make_linked_dirs
      01 mkdir -p /var/www/uni_reporting/shared/config
    ✔ 01 uni@192.168.1.37 0.007s
00:30 puma:config
      Uploading /var/www/uni_reporting/shared/config/puma.rb 100.0%
00:31 puma:nginx_config
      Uploading /tmp/nginx_uni_reporting_production 100.0%
      01 sudo mv /tmp/nginx_uni_reporting_production /etc/nginx/sites-available/uni_reporting_production
    ✔ 01 uni@192.168.1.37 0.033s
      02 sudo ln -fs /etc/nginx/sites-available/uni_reporting_production /etc/nginx/sites-enabled/uni_reporting_production
    ✔ 02 uni@192.168.1.37 0.016s
00:31 nginx:create_log_paths
      01 sudo mkdir -pv /var/www/uni_reporting/shared/log
    ✔ 01 uni@192.168.1.37 0.015s
00:31 git:clone
      01 git clone --mirror git@192.168.1.31:uni-reporting/uni-reporting.git /var/www/uni_reporting/repo
      01 Cloning into bare repository '/var/www/uni_reporting/repo'...
    ✔ 01 uni@192.168.1.37 25.727s
00:56 git:update
      01 git remote update --prune
      01 Fetching origin
    ✔ 01 uni@192.168.1.37 30.584s
01:27 git:create_release
      01 mkdir -p /var/www/uni_reporting/releases/20161019041358
    ✔ 01 uni@192.168.1.37 0.009s
      02 git archive zhangyesheng | tar -x -f - -C /var/www/uni_reporting/releases/20161019041358
    ✔ 02 uni@192.168.1.37 0.021s
01:27 git:set_current_revision
      01 echo "10e05d77c2f13084233f26725174f53a822cce38" >> REVISION
    ✔ 01 uni@192.168.1.37 0.008s
01:27 deploy:symlink:linked_files
      01 mkdir -p /var/www/uni_reporting/releases/20161019041358/config
    ✔ 01 uni@192.168.1.37 0.008s
      02 rm /var/www/uni_reporting/releases/20161019041358/config/database.yml
    ✔ 02 uni@192.168.1.37 0.018s
      03 ln -s /var/www/uni_reporting/shared/config/database.yml /var/www/uni_reporting/releases/20161019041358/config/database.yml
    ✔ 03 uni@192.168.1.37 0.008s
01:27 deploy:symlink:linked_dirs
      01 mkdir -p /var/www/uni_reporting/releases/20161019041358 /var/www/uni_reporting/releases/20161019041358/tmp /var/www/uni_reporting/releases/20161019041358/public
    ✔ 01 uni@192.168.1.37 0.008s
      02 rm -rf /var/www/uni_reporting/releases/20161019041358/log
    ✔ 02 uni@192.168.1.37 0.008s
      03 ln -s /var/www/uni_reporting/shared/log /var/www/uni_reporting/releases/20161019041358/log
    ✔ 03 uni@192.168.1.37 0.008s
      04 ln -s /var/www/uni_reporting/shared/tmp/pids /var/www/uni_reporting/releases/20161019041358/tmp/pids
    ✔ 04 uni@192.168.1.37 0.008s
      05 ln -s /var/www/uni_reporting/shared/tmp/cache /var/www/uni_reporting/releases/20161019041358/tmp/cache
    ✔ 05 uni@192.168.1.37 0.013s
      06 ln -s /var/www/uni_reporting/shared/tmp/sockets /var/www/uni_reporting/releases/20161019041358/tmp/sockets
    ✔ 06 uni@192.168.1.37 0.008s
      07 ln -s /var/www/uni_reporting/shared/public/system /var/www/uni_reporting/releases/20161019041358/public/system
    ✔ 07 uni@192.168.1.37 0.009s
      08 ln -s /var/www/uni_reporting/shared/public/assets /var/www/uni_reporting/releases/20161019041358/public/assets
    ✔ 08 uni@192.168.1.37 0.007s
01:27 bundler:install
      01 ~/.rvm/bin/rvm default do bundle install --path /var/www/uni_reporting/shared/bundle --without development test --deployment --quiet
    ✔ 01 uni@192.168.1.37 172.331s
04:20 deploy:assets:precompile
      01 ~/.rvm/bin/rvm default do bundle exec rake assets:precompile
      01 I, [2016-10-19T12:17:51.286856 #106133]  INFO -- : Writing /var/www/uni_reporting/releases/20161019041358/public/assets/turnovers-b5e398ca6e25fdedb7f75e794e1f507f05d6e93eb3c1c89330697103062c13ea.js
      ......
      # 这里有好多记录的,在此略过
    ✔ 01 uni@192.168.1.37 46.174s
05:06 deploy:assets:backup_manifest
      01 mkdir -p /var/www/uni_reporting/releases/20161019041358/assets_manifest_backup
    ✔ 01 uni@192.168.1.37 0.010s
      02 cp /var/www/uni_reporting/releases/20161019041358/public/assets/.sprockets-manifest-86405ab0b7069de312a544d41b08a4e0.json /var/www/uni_reporting/releases/20161019041358/assets_manifest_backup
    ✔ 02 uni@192.168.1.37 0.009s
05:06 deploy:migrate
      [deploy:migrate] Run `rake db:migrate`
05:06 deploy:migrating
      01 ~/.rvm/bin/rvm default do bundle exec rake db:migrate
      01 == 20160927005034 CreatePlatforms: migrating ==================================
      01
      01 -- create_table(:platforms)
      01
      01    -> 0.0089s
      01
      01 == 20160927005034 CreatePlatforms: migrated (0.0093s) =========================
      01
      01
      01 == 20160927005036 CreateProjects: migrating ===================================
      01
      01 -- create_table(:projects)
      01
      01    -> 0.0064s
      01
      01 -- create_table(:platforms_projects)
      01
      01    -> 0.0132s
      01 == 20160927005036 CreateProjects: migrated (0.0201s) ==========================
      01
      01 == 20160927005037 CreateGoals: migrating ======================================
      01 -- create_table(:goals)
      01
      01    -> 0.0160s
      01 == 20160927005037 CreateGoals: migrated (0.0161s) =============================
      01
      01 == 20160927005117 CreateTurnovers: migrating ==================================
      01 -- create_table(:turnovers)
      01    -> 0.0161s
      01 == 20160927005117 CreateTurnovers: migrated (0.0162s) =========================
      01
    ✔ 01 uni@192.168.1.37 3.458s
05:09 deploy:symlink:release
      01 ln -s /var/www/uni_reporting/releases/20161019041358 /var/www/uni_reporting/releases/current
    ✔ 01 uni@192.168.1.37 0.008s
      02 mv /var/www/uni_reporting/releases/current /var/www/uni_reporting
    ✔ 02 uni@192.168.1.37 0.008s
05:09 deploy:log_revision
      01 echo "Branch zhangyesheng (at 10e05d77c2f13084233f26725174f53a822cce38) deployed as release 20161019041358 by ray" >> /var/www/uni_reporting/revisions.log
    ✔ 01 uni@192.168.1.37 0.010s
05:09 puma:start
      using conf file /var/www/uni_reporting/shared/config/puma.rb
      01 ~/.rvm/bin/rvm default do bundle exec puma -C /var/www/uni_reporting/shared/config/puma.rb --daemon
      01 Puma starting in single mode...
      01 * Version 3.6.0 (ruby 2.3.1-p112), codename: Sleepy Sunday Serenity
      01 * Min threads: 0, max threads: 16
      01 * Environment: production
      01 * Daemonizing...
    ✔ 01 uni@192.168.1.37 1.605s
05:11 nginx:restart
      01 sudo service nginx restart
      01  * Restarting nginx nginx
      01    ...done.
    ✔ 01 uni@192.168.1.37 1.336s

技巧说明:

production.rb 的设置中必须明文声明数据库名称,用户名和密码,否则 capistrano-postgresql总是会在执行 rake db:migrate 时出现用户名密码不配对的错误:

...

SSHKit::Command::Failed: rake exit status: 1
rake stdout: Nothing written
rake stderr: rake aborted!
PG::ConnectionBad: FATAL:  password authentication failed for user "uni_report"
FATAL:  password authentication failed for user "uni_report"

...

服务器上要做的调整

创建系统发布用户

在开始之前我们需要在Ubuntu中为 Capistrano 添加一个负责发布的用户和角色,以执行各种发布的工作。

创建一个新的系统用户:

$ adduser deployer

设置用户密码:

passwd deployer
# Enter a password
# Confirm the password

在发布过程中我们不希望
Edit /etc/sudoers using the text editor nano:

$ nano /etc/sudoers

Scroll down the file and find where root is defined:

..

## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root    ALL=(ALL)   ALL

..

Append the following right after root ALL=(ALL) ALL:

deployer ALL=(ALL) ALL

This section of the /etc/sudoers file should now look like this:

..

## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root     ALL=(ALL)  ALL
deployer ALL=(ALL) ALL

..

Press CTRL+X and confirm with Y to save and exit.

Creating Users For Deploying With Capistrano

When using Capistrano for deployment, the good way of executing the recipes is by using a user other than default root. To begin with, we will create a deployers group, and give them the permission to proceed.

To add a new group to your droplet, run the following:

$ groupadd deployers

Now we can continue with adding users to our deployers group with privileged access.

Let's add deployer as a deployer:

# Usage: sudo usermod -a -G deployers [name]
$ sudo usermod -a -G deployers deployer

Finally, to give the deployers group the permissions, run the following and edit the /etc/sudoers file:

$ nano /etc/sudoers

Add the following line to after the groups:

# /ect/sudoers

..

## Allows people in group wheel to run all commands
%deployers      ALL=(ALL) ALL

..

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容