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

..

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容