使用 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

..

上一篇:Ubuntu 上创建常用磁盘阵列


下一篇:Raspberry Pi 上连接蓝牙设备