nginxとunicorn上で動いているrailsアプリをcapistranoでデプロイする
この記事の続きです
(今回の記事は実際に試してから時間が経っているため色々と漏れがあるかもしれません)
今回の目標
nginxとunicorn上で動いているrailsアプリをcapistranoでデプロイできること
capistranoとは
Capistrano is a remote server automation tool.
It supports the scripting and execution of arbitrary tasks, and includes a set of sane-default deployment workflows.
Capistrano can be used to:
- Reliably deploy web application to any number of machines simultaneously, in sequence or as a rolling set
- To automate audits of any number of machines (checking login logs, enumerating uptimes, and/or applying security patches)
- To script arbitrary workflows over SSH
- To automate common tasks in software teams.
- To drive infrastructure provisioning tools such as chef-solo, Ansible or similar.
Capistrano is also very scriptable, and can be integrated with any other Ruby software to form part of a large r tool.
Capistranoはリモートサーバの自動化ツール
ふむ、ログのチェックとかセキュリティパッチ当てたりとかは聞いたことなかったな〜
$ bundle exec cap production deploy
のようにコマンド一発でデプロイできます
capコマンドを実行する
capistrano、capistrano-rails を導入(Gemfileに書いてbundle install
)
導入後$ bundle exec cap install
コマンドを叩くと必要なファイル群を作成してくれます
├── Capfile ├── config │ ├── deploy │ │ ├── production.rb │ │ └── staging.rb │ └── deploy.rb └── lib └── capistrano └── tasks
githubを参考に設定(そのままコピペしました。必要に応じて修正すべきだと思います)
# Capfile + require 'capistrano/rails' # config/deploy.rb + set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads') + set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
続いてconfig配下のファイルにリポジトリやデプロイ先のサーバの設定を記述します
# config/deploy.rb - set :application, 'my_app_name' - set :repo_url, 'git@example.com:me/my_repo.git' + set :application, 'application_name' + set :repo_url, 'git@github.com:hogehoge/fugafuga.git' # config/deploy/production.rb - server 'example.com', user: 'deploy', roles: %w{app db web}, my_property: :my_value + server 'xx.xx.xx.xx', user: 'ubuntu', roles: %w{app db web}, my_property: :my_value - set :ssh_options, { - keys: %w(/home/rlisowski/.ssh/id_rsa), - forward_agent: false, - auth_methods: %w(password) - } + set :ssh_options, { + keys: %w(~/.ssh/oooooootuka.pem), + forward_agent: false, + auth_methods: %w(publickey) + }
設定終了。すわ!capコマンドを叩いたら対象サーバの/var/wwwディレクトリの権限が無いと怒られた
mkdir stderr: mkdir: cannot create directory '/var/www': Permission denied
そもそもwwwディレクトリ自体が無かったため作成して権限付与
ubuntu@ip-xx-xx-xx-xx:/var$ sudo mkdir www
ubuntu@ip-xx-xx-xx-xx:/var$ sudo chown ubuntu:ubuntu www
再度capコマンドを叩くが今度は別のエラーで怒られる
DEBUG [5687b546] /usr/bin/env: bundle: No such file or directory
見て欲しいのと違うパスを見に行ってしまっている様子。rbenvを使っているので capistrano-rbenv をインストール
githubを参考に設定追加(バージョン以外コピペ)してcapリベンジ
# Capfile -# require 'capistrano/rbenv' + require 'capistrano/rbenv' # config/deploy.rb + set :rbenv_type, :user + set :rbenv_ruby, '2.2.2' + 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 # default value
sqlite3がGemfileにありませんよと怒られる。Gemfileでgroup指定しているのが原因かと思い、外しても状況は変わらずで悩んでいたら、pushするのを忘れていました(・ω<)
Gem::LoadError: Specified 'sqlite3' for database adapter, but the gem is not loaded. Add `gem 'sqlite3'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord).
masterにpushするのもなんなので$ be cap production deploy BRANCH=hogehoge
のようにブランチを指定してデプロイできるようにしてそこからpushする
# config/deploy.rb + set :branch, ENV['BRANCH'] || :master
push後、capコマンドが通ることを確認
unicorn, nginx連携する
下準備として、nginxやunicornで今までホームディレクトリに仮置きしていたアプリを見ていたので/var/www配下を見に行くようにする
# config/nginx.conf - server unix:/home/ubuntu/my_new_application/tmp/sockets/.unicorn.sock fail_timeout=0; + server unix:/var/www/my_new_application/current/tmp/sockets/.unicorn.sock fail_timeout=0; - root /home/ubuntu/my_new_application/public; + root /var/www/my_new_application/current/public; - root /home/ubuntu/my_new_application/public; + root /var/www/my_new_application/current/public;
Capistrano tasks for automatic and sensible unicorn + nginx configuraion.
Goals of this plugin:
- automatic unicorn and nginx configuration for Rails apps
- no manual ssh to the server required
- zero downtime deployments enabled
- support for single node as well as cluster deployments
Specifics:
- generates nginx config file on the server (web role)
- generates unicorn initializer and config files (app role) application is started automatically after server restart
- capistrano tasks for server management, example: unicorn:restart see below for all available tasks
- automatic load balancing setup when there are multiple app nodes
capistrano-unicorn-nginx works only with Capistrano 3!
unicorn + nginx環境で最適化したcapistranoタスクだよ☆みたいな感じ
プラグインの目的:
仕様:
- nginxの設定ファイルを生成
- サーバ再起動後にunicornの初期化とconfigファイルの生成を自動的に始める
unicorn:restart
などのサーバ管理タスクが使える- 複数ノードの時負荷を分散してくれる?
capistrano3でのみ動作する!
Capfileやconfig配下の設定ファイルを修正
# Capfile + require 'capistrano/unicorn_nginx' # config/nginx.conf - server unix:/var/www/my_new_application/current/tmp/sockets/.unicorn.sock fail_timeout=0; + server unix:/tmp/unicorn.my_new_application_production.sock fail_timeout=0; # config/unicorn.rb - listen '/var/www/my_new_application/current/tmp/sockets/.unicorn.sock' # by default Unicorn listens on port 8080 + listen '/tmp/unicorn.my_new_application_production.sock' # by default Unicorn listens on port 8080
上記対応で、capコマンドを叩いた後にunicornとnginxを再起動してくれるようになりました
今回は一度動作させることを確認した後でcapistranoデプロイするという手順を踏みましたが、configファイルを自動生成してくれるらしいので、最初からcapistrano-unicorn-nginxを使ったほうが良かったのかなと思ったりしました。