wuyuedefeng / blogs

博客文章在issue中
5 stars 0 forks source link

Rails capistrano部署 #17

Open wuyuedefeng opened 5 years ago

wuyuedefeng commented 5 years ago

基本部署

基础命令

# root
apt-get update  

创建用户

# root
adduser deploy # 默认生成的 用户组 和 用户名 相同
groups deploy # 查看用户属于哪些用户组
usermod -a -G root deploy # 将deploy加入root组

# vim /etc/sudoers, 找到 root ALL=(ALL:ALL) ALL,在这行下面增加
deploy ALL=(ALL) NOPASSWD: ALL # NOPASSWD表示切换sudo时候无需密码

# 切换用户
su deploy

# 删除用户
deluser deploy --remove-home

#  变更文件所有者
sudo chown [新用户名] [文件名]

# 修改文件权限
chmod 700 iphone6 # 现在,其他用户已经不能读这个“ iphone6 ”文件了
# 加减赋值操作
chmod go-rw iphone6 # g、o 还有 u 分别表示 group、others 和 user,+ 和 - 分别表示增加和去掉相应的权限。

添加SSH 到服务器

cd ~
mkdir .ssh
cd .ssh
vim authorized_keys # 将本机id_rsa.pub中的key粘贴进去

服务器生成ssh key

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

安装git

$ sudo apt-get install git

安装nginx

[sudo] apt-get update  
[sudo] apt-get install nginx

配置文件

# (配置文件生效所在目录:/etc/nginx/sites-enabled/)
# cd /etc/nginx/sites-available
upstream huobi-api {
    server unix:///mnt/www/huobi/huobi-api/shared/tmp/sockets/puma.sock;
  }
server {
  listen 80;
  server_name api.huobi.zezeping.com apa.huobi.zezeping.com; # change to match your URL
  root /mnt/www/huobi/huobi-api/shared/public; # I assume your app is located at that location
  location / {
    proxy_pass http://huobi-api; # match the name of upstream directive which is defined above
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
  location /cable {
    proxy_pass http://huobi-api;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
  }
  location ~* ^/assets/ {
    # Per RFC2616 - 1 year maximum expiry
    expires 1y;
    add_header Cache-Control public;

    # Some browsers still send conditional-GET requests if there's a
    # Last-Modified header or an ETag header even if they haven't
    # reached the expiry date sent in the Expires header.
    add_header Last-Modified "";
    add_header ETag "";
    break;
  }
}
# sudo ln -sf /etc/nginx/sites-available/huobi-api.conf /etc/nginx/sites-enabled/huobi-api.conf

启动报错可以执行下面命令,会打印出错误信息(个人测试)

sudo nginx -t -c /etc/nginx/nginx.conf

配置https, 请去这里这里

安装Mysql

# 检查系统中是否已经安装了MySQL
sudo netstat -tap | grep mysql 
# 如果没有安装,则安装MySQL.
sudo apt-get install mysql-server mysql-client libmysqlclient-dev
# 测试安装是否成功:
sudo netstat -tap | grep mysql
# 也可通过登录MySQL测试
mysql -uroot -p

MySQL的一些简单管理:

# 启动MySQL服务:                       
sudo service mysql start 
# 停止MySQL服务:                       
sudo service mysql stop
# 修改 MySQL 的管理员密码:     
sudo mysqladmin -u root password newpassword
# 设置远程访问(正常情况下,mysql占用的3306端口只是在IP 127.0.0.1上监听,拒绝了其他IP的访问(通过netstat可以查看到)。取消本地监听需要修改 my.cnf 文件:):    
sudo vi /etc/mysql/my.cnf
bind-address = 127.0.0.1 //找到此内容并且注释

MySQL安装后的目录结构分析(此结构只针对于使用apt-get install 在线安装情况):

# 数据库存放目录:               
/var/lib/mysql/
# 相关配置文件存放目录:          
/usr/share/mysql
# 相关命令存放目录:             
/usr/bin(mysqladmin mysqldump等命令)
# 启动脚步存放目录:            
/etc/rc.d/init.d/

图形软件

安装node

# sudo apt install -y curl
# 安装16.x版本
# curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - 
sudo apt-get install nodejs

安装rbenv

rbenv install 2.4.1 rbenv versions rbenv local 2.4.1 gem install bundler


### Capstrano部署

[参考项目](https://gitee.com/huzanbang/huzanbang-api)
* [gem "capistrano", "~> 3.11", require: false](https://github.com/capistrano/capistrano)
* [gem "capistrano-rails", "~> 1.4", require: false](https://github.com/capistrano/rails)
* [gem 'capistrano-bundler', '~> 1.6'](https://github.com/capistrano/bundler)
* [gem 'capistrano3-puma'](https://github.com/seuros/capistrano-puma)
* [gem 'capistrano-rbenv', '~> 2.1'](https://github.com/capistrano/rbenv)
* [gem 'capistrano-sidekiq'](https://github.com/seuros/capistrano-sidekiq)
```ruby
# Gemfile
group :development do
  # deploy
  gem "capistrano", require: false
  gem "capistrano-rails", require: false
  gem "capistrano-bundler", require: false
  gem "capistrano3-puma", require: false
  gem 'capistrano-rbenv', require: false
  # gem 'capistrano-sidekiq', require: false
end

初始化文件

# bundle install
$ bundle exec cap install
$ cap [environment] deploy:check
# Capfile
# 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"
# 第一次部署注释这一样去服务器执行 RAILS_ENV=staging bundle exec rails db:create后再打开注释,重新部署
require "capistrano/rails/migrations"
# require "capistrano/passenger"

require 'capistrano/puma'
install_plugin Capistrano::Puma  # Default puma tasks
install_plugin Capistrano::Puma::Workers  # if you want to control the workers (in cluster mode)
install_plugin Capistrano::Puma::Jungle # if you need the jungle tasks
# install_plugin Capistrano::Puma::Monit  # if you need the monit tasks
# install_plugin Capistrano::Puma::Nginx  # if you want to upload a nginx site template

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
# config/deploy.rb
# config valid for current version and patch releases of Capistrano
lock "~> 3.11.2"

set :rbenv_type, :deploy # or :system, depends on your rbenv setup
set :rbenv_ruby, File.read('.ruby-version').strip

set :application, "huzanbang-api"
set :repo_url, "git@gitee.com:huzanbang/huzanbang-api.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, "/mnt/www/huzanbang/huzanbang-api"

# 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"
append :linked_files, "config/database.yml", "config/application.yml", "config/master.key", "config/puma.rb"

# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
append :linked_dirs, "storage", "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system", "public/uploads"

# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }

# 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

# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure

#  set puma.rb path default #{shared_path}/puma.rb
set :puma_conf, "#{shared_path}/config/puma.rb"
# config/deploy/staging.rb
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:

# set :rails_env, 'staging'

# server "example.com", user: "deploy", roles: %w{app db web}, my_property: :my_value
# server "example.com", user: "deploy", roles: %w{app web}, other_property: :other_value
# server "db.example.com", user: "deploy", roles: %w{db}
server "47.93.21.147", user: "deploy", roles: %w{app db}

set :branch, :capstrano

# role-based syntax
# ==================

# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.

# role :app, %w{deploy@example.com}, my_property: :my_value
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
# role :db,  %w{deploy@example.com}

# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.

# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
#  set :ssh_options, {
#    keys: %w(/home/rlisowski/.ssh/id_rsa),
#    forward_agent: false,
#    auth_methods: %w(password)
#  }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# server "example.com",
#   user: "user_name",
#   roles: %w{web app},
#   ssh_options: {
#     user: "user_name", # overrides user setting above
#     keys: %w(/home/user_name/.ssh/id_rsa),
#     forward_agent: false,
#     auth_methods: %w(publickey password)
#     # password: "please use keys"
#   }

set :sidekiq_processes, 2
# :sidekiq_config => nil # if you have a config/sidekiq.yml, do not forget to set this.
set :sidekiq_config, "config/sidekiq.yml"
# /mnt/www/huzanbang/huzanbang-api/shared/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  collation: utf8mb4_unicode_ci
  username: root
  password: root123 
  port: 3306
staging:
  primary:
    <<: *default
    database: huzanbang_api_staging
    pool: 20
  logs:
    <<: *default
    database: huzanbang_api_logs_staging
    migrations_paths: db/logs_migrate
    pool: 5
# /mnt/www/huzanbang/huzanbang-api/shared/config/application.yml
default: &default
production:
  <<: *default
  sidekiq_secret: mars1234
  hosts:
    - api.huzanbang.zezeping.com
    - apa.huzanbang.zezeping.com
# /mnt/www/huzanbang/huzanbang-api/shared/config/master.key
f7bfdc141e1cbab67a526c15252a15xx
# /mnt/www/huzanbang/huzanbang-api/shared/config/puma.rb
#!/usr/bin/env puma
app_name = "huzanbang-api"
app_path = "/mnt/www/huzanbang/#{app_name}"

environment "production"

daemonize true
workers 1
threads 1,16

directory "#{app_path}/current"

bind "unix://#{app_path}/shared/tmp/sockets/puma.sock"
pidfile "#{app_path}/shared/tmp/pids/puma.pid"
state_path "#{app_path}/shared/tmp/pids/puma.state"
stdout_redirect "#{app_path}/shared/log/puma.stdout.log", "#{app_path}/shared/log/puma.stderr.log"
activate_control_app "unix://#{app_path}/shared/tmp/sockets/pumactl.sock"

on_restart do
  puts 'On restart...'
end
prune_bundler
$ cap staging setup
$ cap staging deploy

集成Sidekiq

gem 'capistrano-sidekiq', github: 'seuros/capistrano-sidekiq'

# Gemfile
gem 'capistrano-sidekiq', github: 'seuros/capistrano-sidekiq'
# Capfile
# sidekiq
require 'capistrano/sidekiq'
# require 'capistrano/sidekiq/monit' #to require monit tasks # Only for capistrano3
# cofnig/deploy.rb 追加 config/sidekiq.yml
append :linked_files, "config/database.yml", "config/application.yml", "config/master.key", "config/puma.rb", "config/sidekiq.yml"
# config/deploy.rb
set :sidekiq_processes, 1
# :sidekiq_config => nil # if you have a config/sidekiq.yml, do not forget to set this.
set :sidekiq_config, "config/sidekiq.yml"

in Server

安装Redis

$ sudo  apt-get install redis-server
# service  redis status
# 设置密码: 找到/et/redis/redis.conf文件修改如下   ,添加  requirepass kingredis(密码设置为kingredis)
# 测试连接: 如果是阿里云服务器,切记要在安全组、安全策略里面加入服务的端口号,允许所有地址访问,如下图,才可以,即在阿里云服务器的所有服务都需要把端口映射出来才可以,如果没有做这一步,上面的redis-cli命令就会处于一直等待的状态
# /mnt/www/huzanbang/huzanbang-api/shared/config/sidekiq.yaml
---
:concurrency: 5
staging:
  :concurrency: 20
:queues:
- highest
- higher
- high
- default
- low
- lower
- lowest

启动

$ cap staging sidekiq:start

whenever 集成

# Gemfile
gem 'whenever', require: false
# 创建初始化文件
$ bundle exec wheneverize .
# Capfile
# whenever
require "whenever/capistrano"

如果需要给whenever命名空间,默认命名空间以项目名做区分

# config/deploy.rb
# whenever
set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:stage)}" }

可能会出现crontab无法执行whenever生成的文件,出现此问题可能是rbenv相关环境没有加载。issue

# top of schedule.rb
job_type :rake, %Q{export PATH=/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:/usr/bin:$PATH; eval "$(rbenv init -)"; \
                         cd :path && :environment_variable=:environment :bundle_command rake :task --silent :output }

job_type :runner, %Q{export PATH=/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:/usr/bin:$PATH; eval "$(rbenv init -)"; \
                         cd :path && :bundle_command :runner_command -e :environment ':task' :output }
wuyuedefeng commented 4 years ago

git submodules

Capfile
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
# 在这里添加
require "capistrano/scm/git-with-submodules"
install_plugin Capistrano::SCM::Git::WithSubmodules

webpacker

wuyuedefeng commented 4 years ago

自定义部署指令

deploy.rb

namespace :deploy do
  desc 'Runs rake db:seed for SeedMigrations data'
  task :seed => [:set_rails_env] do
    on primary fetch(:migration_role) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, "db:seed"
        end
      end
    end
  end
end
# 部署完成后自动执行
after 'deploy:migrate', 'deploy:seed'
# 或者手动执行:cap production deploy:seed
wuyuedefeng commented 1 year ago

新版 gem 'capistrano3-puma' 使用

# Capfile
require 'capistrano/puma'
install_plugin Capistrano::Puma  # Default puma tasks
install_plugin Capistrano::Puma::Systemd

通过如下命令自动生成puma配置

cap production puma:config
cap production puma:systemd:config
cap production start
wuyuedefeng commented 6 months ago

安装postgresql