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
..