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

什么是Capistrano?

Capistrano是一种远程服务器自动化工具。

它支持任意任务的脚本和执行,并包括一组理智的默认部署工作流。

Capistrano可用于:

  • 可以按顺序或作为滚动集将Web应用程序可靠地同时部署到任意数量的计算机上
  • 自动审核任意数量的计算机(检查登录日志,计算正常运行时间和/或应用安全补丁)
  • 通过SSH编写任意工作流脚本
  • 自动执行软件团队中的常见任务。
  • 驱动架构配置工具,如chef-soloAnsible或类似工具。

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

# 切换到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 Capistrano
lock '~> 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 env
set :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, 5
set :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

end
end

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 }
请先登录再回复