用Ruby编写的远程服务器自动化和部署工具

什么是Capistrano?

Capistrano是一种远程服务器自动化工具。 它支持任意任务的脚本和执行,并包括一组理智的默认部署工作流。 Capistrano可用于:
  • 可以按顺序或作为滚动集将Web应用程序可靠地同时部署到任意数量的计算机上
  • 自动审核任意数量的计算机(检查登录日志,计算正常运行时间和/或应用安全补丁)
  • 通过SSH编写任意工作流脚本
  • 自动执行软件团队中的常见任务。
  • 驱动架构配置工具,如chef-solo,Ansible或类似工具。
Capistrano也非常易于编写,可以与任何其他Ruby软件集成,构成更大工具的一部分。

为什么要使用Capistrano?

Capistrano是用于构建自动部署脚本的框架。尽管Capistrano本身是用Ruby编写的,但它可以很容易地用于部署任何语言或框架的项目,无论是Rails,Java还是PHP。 安装后,Capistrano为您提供了一个cap工具,可以在您的命令行中轻松执行部署。
$ cd my-capistrano-enabled-project
$ cap production deploy
至此,您的项目已经部署完成,不需要你 ssh 连接服务器, git pull 代码, 不需要执行类似 touch tmp/restart.txt 命令, 不需要执行一堆的命令来启动您需要的进程.

如何使用Capistrano?

首先你的服务器上得配置好web运行环境, 如ruby, nginx, passenger等.
本文使用环境配置如下:
  1. 服务器: Ubuntu 18.04
  2. Rails 5.2.1 + Ruby 2.5.1
  3. Mysql 5.7.24
在您的服务器上,新建用户, deploy, 待会配置时候会用到
# 服务器上
# 新建的deploy用户直接就有执行`sudo`命令的权限。
adduser deploy --ingroup sudo
    adduser deploy sudo 

# 切换到deploy用户
sudo su deploy

1.修改Gemfile

2.bundle install

bundle install

3.生成capistrano的相关配置文件

bundle exec cap install
这将为具有两个阶段的启用Capistrano的项目创建所有必需的配置文件和目录结构,staging并且production
├── Capfile
├── config
│ ├── deploy
│ │ ├── production.rb
│ │ └── staging.rb
│ └── deploy.rb
└── lib
    └── capistrano
            └── tasks

4.编辑 Capfile  (下面评论中,有该文件所有行)

# 根据需要注释或者取消注释一些行, 这里用到了rvm sidekiq, 所以取消注释了, 如果你不需要,则注释掉该行
require "capistrano/rvm"
# require "capistrano/rbenv"
# require "capistrano/chruby"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
require "capistrano/passenger"
require 'whenever/capistrano'
require 'capistrano/sidekiq'

5.编辑 config/deploy.rb 

# config valid for current version and patch releases of Capistranolock '~> 3.11.0'# 项目名称set :application, 'test_project'# 仓库地址set :repo_url, 'git@github.com:ErvinCheung/test_project.git'# Default branch is :master# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp# Default deploy_to directory is /var/www/my_app_name# set :deploy_to, "/var/www/my_app_name"# 需要部署到服务器的位置set :deploy_to, '/home/deploy/web/test_project'# rails envset :rails_env, 'production'set :bundle_flags, '--deployment --quiet --full-index'# Default value for :format is :airbrussh.# set :format, :airbrussh# You can configure the Airbrussh format using :format_options.# These are the defaults.# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto# Default value for :pty is false# set :pty, true# Default value for :linked_files is []# append :linked_files, "config/database.yml"# 去掉注释,并加上 "config/master.key", 如果有storage.yml 也加上append :linked_files, "config/database.yml", "config/master.key", "config/storage.yml"# Default value for linked_dirs is []# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"# 取消注释append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system", "storage"# Default value for default_env is {}# set :default_env, { path: "/opt/ruby/bin:$PATH" }ne# Default value for local_user is ENV['USER']# set :local_user, -> { `git config user.name`.chomp }# Default value for keep_releases is 5# set :keep_releases, 5set :keep_releases, 5# Uncomment the following to require manually verifying the host key before first deploy.# set :ssh_options, verify_host_key: :secure
# 在部署后你想做的事情, 可以放到这里namespace :deploy do after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do within release_path do with rails_env: fetch(:rails_env) do execute :rake, 'db:seed' end end end endend

6编辑config/deploy/production.rb

server 换上你服务器的ip

server "101.132.111.111", user: "deploy", roles: %w{app db web}

7.测试一下, 本地执行:

cap production deploy:check

出现以下错误

ERROR linked file /home/deploy/test_project/shared/config/database.yml does not exist on 

解决方法,是需要手动到服务器上,建config/database.ymlconfig/master.key等文件,并做好配置。

服务器上,会出现releasesshared两个目录。releases是每次部署的文件,shared目录则是一些公用的配置文件。那么我们现在就去shared目录中,添加这两个公用的配置文件。

在你的项目, 此路径下test_project/shared/config,建立 config/database.ymlconfig/master.key等文件

8.再次执行测试

cap production deploy:check

没有报错

9.部署

cap production deploy

第一次会比较慢,会在服务器上建立一个叫current的目录,用symbolic link指向releases目录下最新的版本。

10.配置nginx,

root需要指向current/public

 server {
        listen       80;
        server_name  www.vicw.com;
        #charset koi8-r;
        passenger_enabled on;
        #access_log  logs/host.access.log  main;

        location / {
            root   /home/deploy/web/test_project/current/public;
            index  index.html index.htm;
        }
}

11.重启nginx

您的程序部署完成, 当然, 下次部署时候您只需在您本地的机器上执行

cap production deploy

就可以完成部署, 

TIP:命令行用法

# 列出所有可用的任务 list all available tasks
$ bundle exec cap -T

# 部署到暂存环境 deploy to the staging environment
$ bundle exec cap staging deploy

# 部署到生产环境 deploy to the production environment
$ bundle exec cap production deploy

# 可模拟部署到生产环境 simulate deploying to the production environment
# 实际上并没有做任何事情 does not actually do anything
$ bundle exec cap production deploy --dry-run

# 列出任务相关 list task dependencies
$ bundle exec cap production deploy --prereqs

# 通过任务调用跟踪 trace through task invocations
$ bundle exec cap production deploy --trace

# 在部署任务之前列出所有配置变量 lists all config variable before deployment tasks
$ bundle exec cap production deploy --print-config-variables
1条评论 顺序楼层
# Load DSL and set up stages
require "capistrano/setup"

# Include default deployment tasks
require "capistrano/deploy"

# Load the SCM plugin appropriate to your project:
#
# require "capistrano/scm/hg"
# install_plugin Capistrano::SCM::Hg
# or
# require "capistrano/scm/svn"
# install_plugin Capistrano::SCM::Svn
# or
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git

# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
require "capistrano/rvm"
# require "capistrano/rbenv"
# require "capistrano/chruby"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
require "capistrano/passenger"
require 'whenever/capistrano'
require 'capistrano/sidekiq'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
请先登录再回复