hamayuzinの日記

ITベンチャーに新卒入社し、エンジニアとかデータサイエンティスト、とかやってます。

【rails/puma/nginx/cap】rails5.1をnginx puma環境にcap deployするときの設定

railsをnginx puma環境にcap deployするときの設定を残しておく rubyはrbenvで管理する webpack secrets.yml.key ridgepoleを使用している

nginx

upstream hogehoge {
  server unix:/data/hogehoge/shared/tmp/sockets/puma.sock;
}

geo $allow_ip_flag {
  default 0;
  hogehoge ip
}

server {
  listen 80;
  server_name hogehoge.com;

  underscores_in_headers on;
  client_max_body_size 8M;

  # maintenance-mode setting
  error_page 503 @maintenance;
  set $maintenance false;

  if ( -f "/data/hogehoge/shared/config/is_mainte.txt") {
    set $maintenance true;
  }

  if ( $allow_ip_flag ) {
    set $maintenance false;
  }

  if ( $maintenance = true ) {
    return 503;
  }

  location @maintenance {
    rewrite ^ /system/maintenance.html break;
    expires 0;
  }

  # main setting
  location ~ ^/(favicon.ico|assets/|audios/|system/|uploads/tmp/|sitemap.xml) {
    access_log /var/log/nginx/static_files.access.log main;
    error_log  /var/log/nginx/static_files.error.log;
    gzip_static on;

    root /data/hogehoge/current/public;
    expires 1y;
    add_header Cache-Control public;

    add_header ETag "";
    break;
  }

  location /cable {
    proxy_pass http://hogehoge.com;
    proxy_http_version 1.1;
    proxy_set_header Upgrade websocket;
    proxy_set_header Connection Upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
   }

  location / {
    access_log /var/log/nginx/hoghoge.access.log main;
    error_log  /var/log/nginx/hogehoge.error.log;

    if (-f $request_filename) { break; }

    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://hogehoge;

  }
}

gemfile

group :development, :test do
  gem 'capistrano', '~> 3.7'
  gem 'capistrano-bundler'
  gem 'capistrano-nodenv', '~> 1.0', '>= 1.0.1'
  gem 'capistrano-rails'
  gem 'capistrano-rbenv'
  gem 'capistrano-yarn', '~> 2.0', '>= 2.0.2'
  gem 'capistrano3-puma'
end

capfile

require 'capistrano/setup'
require 'capistrano/deploy'
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/migrations'
require 'capistrano/puma'
install_plugin Capistrano::Puma

Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

deploy/production.rb

set :rails_env, :production
set :branch, 'master'
server hogehoge.ip, user: 'webmaster', roles: %w(web app db batch ridgepole)

set :ssh_options, keys: ["#{ENV['HOME']}/.ssh/hogehoge.pem"],
                  forward_agent: false,
                  auth_methods: %w(publickey)

set :bundle_path, -> { shared_path.join('vendor/bundle') }
set :bundle_flags, '--deployment'
set :bundle_without, %w(development test).join(' ')

before 'deploy:starting', 'deploy:cleanup'
set :keep_releases, 3
set :puma_workers, 2

deploy,rb

lock '3.9.1'

set :application, 'hogehoge'
set :repo_url, 'git@github.com:fugafuga/hogehoge.git'
set :deploy_to, '/data/hogehoge'

set :rbenv_type, :user
set :rbenv_ruby, '2.4.1'
set :rbenv_path, '/usr/local/rbenv'
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w(rake gem bundle ruby rails puma pumactl)
set :rbenv_roles, :all # default value


append :linked_files, 'config/database.yml', 'config/secrets.yml.key'
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'tmp/uploads', 'vendor/bundle', 'public/assets', 'public/uploads/tmp'


set :keep_releases, 3

namespace :deploy do
  desc 'reload the database with seed data'
  task :seed 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

  task :apply_ridgepole do
    on primary :ridgepole do
      invoke 'ridgepole:apply'
    end
  end

  task :apply_seedfu do
    on primary :db do
      invoke 'seed_fu:apply'
    end
  end

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      invoke 'puma:restart'
    end
  end

  after :publishing, :restart do
    on roles(:app), in: :sequence, wait: 5 do
      # Your restart mechanism here, for example:
      # execute :touch, release_path.join('tmp/restart.txt')
    end
  end

  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
      # Here we can do anything such as:
      # within release_path do
      #   execute :rake, 'cache:clear'
      # end
    end
  end

  desc 'Upload secret files'
  task :upload_secret do
    on roles(:app) do
      execute :mkdir, '-p', shared_path.join('config')

      upload!('config/database.yml', "#{shared_path}/config/database.yml")
      upload!('config/secrets.yml.key', "#{shared_path}/config/secrets.yml.key")
    end
  end
end


namespace :js do
  desc 'build webpack'
  task :webpack do
    on roles(:app), in: :sequence, wait: 5 do
      within release_path do
        execute :rake, 'webpack:build_production'
      end
    end
  end
end

after 'bundler:install', 'js:webpack'
after 'deploy:migrating', 'deploy:apply_ridgepole'
after 'deploy:apply_ridgepole', 'deploy:apply_seedfu'

puma.rb

threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }
threads threads_count, threads_count

port        ENV.fetch('PORT') { 3000 }

environment ENV.fetch('RAILS_ENV') { 'development' }

app_dir = File.expand_path("../..", __FILE__)
bind "unix://#{app_dir}/tmp/sockets/puma.sock"
pidfile "#{app_dir}/tmp/pids/puma.pid"
state_path "#{app_dir}/tmp/pids/puma.state"
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true
plugin :tmp_restart