Rails+Capistrano環境でデプロイ

Rails+Capistranoでデプロイした時のメモ

Gitで管理

tsyknsr.hatenablog.com

Capistrano

GitHub - capistrano/capistrano: Remote multi-server automation tool

動作確認用に最小限の設定です。設定等はお好みで適宜変更してください。(記事に関係ない部分は一部省略している箇所もあります)

  • Gemfile
group :development do
  gem 'capistrano', '~> 3.10'
  gem 'capistrano-rails'
  gem 'capistrano-rbenv'
  gem 'capistrano-bundler'
  gem 'capistrano3-unicorn'
end
$ bundle install
$ bundle exec cap install
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
create Capfile
Capified
  • config/deploy/production.rb
set :branch, 'master'
server '192.0.2.0', user: 'username', roles: %w{web app db}

role :app, %w{username@192.0.2.0}
role :web, %w{username@192.0.2.0}
role :db,  %w{username@192.0.2.0}

# ポートフォワーディングを利用する場合
set :ssh_options, {
  keys: %w(~/.ssh/id_rsa),
  forward_agent: true,
  auth_methods: %w(publickey)
}
  • Capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano3/unicorn'
require 'capistrano/sitemap_generator'
require 'whenever/capistrano'

require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git

Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
  • config/deploy.rb
# config valid only for current version of Capistrano
lock "3.8.0"

set :application, "my_app_name"
set :repo_url, "git@example.com:me/my_repo.git"
set :deploy_to, "/var/www/nginx/example.com"

set :pty, true

set :linked_files, "config/database.yml", "config/secrets.yml"
set :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"

# rbenv
set :rbenv_type, :user
set :rbenv_ruby, '2.5.0'
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}
set :rbenv_roles, :all

# unicorn
set :unicorn_pid, "#{shared_path}/tmp/pids/unicorn.pid"
set :unicorn_config_path, "config/unicorn.rb"

# whenever
set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:stage)}" }

before 'deploy:publishing', 'db:seed_fu'
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end
after 'deploy:restart', 'deploy:sitemap:create'
app_path = "/var/www/nginx/example.com"
working_directory "#{app_path}/current"
pid "#{app_path}/shared/tmp/pids/unicorn.pid"

listen "#{app_path}/shared/tmp/sockets/unicorn.sock"

stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"

worker_processes 3

timeout 15

preload_app true

before_exec do |server|
  Dotenv.overload
  ENV['BUNDLE_GEMFILE'] = "#{app_path}/current/Gemfile"
end

before_fork do |server, worker|
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.disconnect!
  end

  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

after_fork do |server, worker|
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
  end
end

動作確認

$ bundle exec cap production deploy:check

参考リンク

DeviseとOmniAuthで複数のSNSを利用して認証する

DeviseとOmniAuthで複数のSNSを利用して認証する機能を開発した時のメモ。

全体の流れ

参考リンク

Controller周り

参考リンク

Model周り

omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end
get '/auth/:action/callback', controller: 'authentications', constraints: { action: /twitter/ }

app/controllers/authentications_controller.rb

class AuthenticationsController < ApplicationController
  auth = request.env['omniauth.auth']
end

https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview#facebook-example https://github.com/omniauth/omniauth/wiki/Managing-Multiple-Providers

$ rails g model Authentications user:references provider uid access_token access_secret
class CreateAuthentications < ActiveRecord::Migration[5.0]
  def change
    create_table :authentications do |t|
      t.references :user, foreign_key: true, null: false
      t.string :provider, null: false
      t.string :uid, null: false
      t.string :access_token
      t.string :access_secret

      t.timestamps
    end

    add_index :authentications, [:provider, :uid], unique: true
  end
end

authentication.rb

class Authentication < ApplicationRecord
  belongs_to :user

  validates :user_id, presence: true
  validates :provider, presence: true
  validates :uid, presence: true, uniqueness: { scope: :provider }
end

https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview#facebook-example

参考

https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview https://github.com/plataformatec/devise/wiki/OmniAuth-with-multiple-models https://techracho.bpsinc.jp/hachi8833/2017_05_18/40208 https://github.com/omniauth/omniauth/wiki/Managing-Multiple-Providers https://qiita.com/awakia/items/03dd68dea5f15dc46c15 http://sinsoku.hatenablog.com/entry/2016/01/03/090000 https://qiita.com/kami_zh/items/94aec2d94a2b4e9a1d0b

node.jsをインストール

node.jsをインストールした時のメモ

$ brew install nodebrew
$ nodebrew -v
$ nodebrew ls-remote
$ mkdir -p ~/.nodebrew/src
$ nodebrew install-binary v8.9.3
$ nodebrew ls
$ nodebrew use v8.9.3
$ nodebrew ls
v8.9.3

current: v8.9.3
$ node -v
-bash: node: command not found

~/.bash_profile

export PATH=$HOME/.nodebrew/current/bin:$PATH

$ source ~/.bash_profile
$ node -v
v8.9.3
$ npm -v
5.5.1

参考

Railsでサイトマップを作成

Railsサイトマップを作成した時のメモ

XMLサイトマップの作成

リンク先の記事の方法でxmlの作成から定期更新まで実装できます。

post.simplie.jp

サイトマップの内容

食べログサイトマップを参考に値の設定を行いました。

https://tabelog.com/sitemap.xml

食べログの例:

changefreq priority
都道府県 always 1
店舗 weekly 0.5
口コミ monthly 0.3

BL902HWの子機にWLI-UTX-AG300/Cを設定

BUFFALO 11n/a/g/b 300Mbps 簡単無線LAN子機 WLI-UTX-AG300/C

BUFFALO 11n/a/g/b 300Mbps 簡単無線LAN子機 WLI-UTX-AG300/C

加えてMacbookAirでWLI-UTX-AG300/Cの設定を行うためLANアダプタを購入。

Error:Execution failed for task ':app:processDebugManifest'.

エラー内容

参考書籍の写経をしていたところ以下のエラーが表示されました。

Error:Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute meta-data#android.support.VERSION@value value=(25.3.0) from AndroidManifest.xml:5:55-77
    is also present at [com.android.support:design:25.3.1] AndroidManifest.xml:27:9-31 value=(25.3.1).
    Suggestion: add 'tools:replace="android:value"' to <meta-data> element at AndroidManifest.xml:5:5-80 to override.

対応

エラー内容を参考に'tools:replace=“android:value”‘をAndroidManifest.xmlに設置してみましたが解消されませんでした。Design Support Libraryのバージョンの問題ではと考えて、他のテンプレートの読み込み方法を参考に以下の内容に変更しました。

変更前

compile 'com.android.support:design:25.3.1'

変更後

compile 'com.android.support:design:26.+'

先程のエラーは解消されましたが、新しいエラーが表示されました。

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

エラー内容に従ってAndroidManifest.xmlのactivityのthemeを変更しました。

android:theme="@style/Theme.AppCompat"

正常に表示を確認できました。

その他

今回のエラーをきっかけにAndroid Studioログの見方を学びました。

developer.android.com

参考