Github
登録しrepositoryを作成します。
今回はcapistrano-example
で作成します。
Cloud9
Githubアカウントでログインできます。
Workspace作成
Clone from Git or Mercurial URLは空のままにしておきます。
Choose a templateはBlank(旧Custom)を選びます。
railsを選ばないのは自動でプロジェクトを生成されないようにするためで、git repositoryを設定しないのはworkspaceのルートとrepositoryのルートが一致しないためです。
PostgreSQL
DBの初期設定を行います。
今回はmy_app_name
で登録します。
$ sudo service postgresql start
$ sudo sudo -u postgres psql
postgres=# create role my_app_name with createdb login password 'PA$$W0rd';
Cloud9の初期で入っているモノはそのままだとエラーを出すのでdatabase templateを更新します。
postgres# UPDATE pg_database SET datistemplate = FALSE WHERE datname = 'template1'; postgres# DROP DATABASE template1; postgres# CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = 'UNICODE'; postgres# UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template1'; postgres# \c template1 postgres# VACUUM FREEZE; postgres# \q
https://github.com/Aerogami/guides/wiki/Cloud9-workspace-setup-with-Rails-and-Postgresql
RoRプロジェクトの作成
DBの名前等と合わせてmy_app_name
で生成します。
$ rails new my_app_name -TB --database=postgresql
$ cd my_app_name
Git
$ git init
$ echo "config/secrets.yml" >> .gitignore
$ git add .
$ git commit -m "first commit"
$ git remote add origin git@github.com:USER/capistrano-example.git
$ git push origin master
これ以降の作業はブランチ切って行うと戻りやすいです。
Bundler
#追加
group :development do
gem 'capistrano-rails'
gem 'capistrano-rvm'
gem 'capistrano3-unicorn'
gem 'dotenv-rails'
end
gem 'unicorn'
$ bundle install --path vendor/bundle
$ echo "vendor/bundle" >> .gitignore
Database
default: &default
adapter: postgresql
encoding: unicode
pool: 5
# この3行を追加
username: my_app_name
password: <%= ENV['MY_APP_NAME_DATABASE_PASSWORD'] %>
host: localhost
development:
<<: *default
database: my_app_name_development
test:
<<: *default
database: my_app_name_test
production:
<<: *default
database: my_app_name_production
username: my_app_name
password: <%= ENV['MY_APP_NAME_DATABASE_PASSWORD'] %>
dotenv
$ vi .env
$ echo ".env" >> .gitignore
MY_APP_NAME_DATABASE_PASSWORD='PA$$W0rd'
動作確認
$ rake db:setup
$ rails g scaffold Post title:string body:text
$ rake db:migrate
$ rails s -b $IP -p $PORT
右上に表示されるURLをクリックするか上のメニューからPreview->Preview Running Applicationを選択すると該当ページを参照できます。
unicorn
$ mkdir config/unicorn
$ vi config/unicorn/production.rb
# アプリ名を自身のものにする
root = "/home/rails/apps/my_app_name/current"
# ソケットをnginxと合わせる
# DigitalOceanの/etc/nginx/sites-enabled/rails参照
listen '/tmp/unicorn.my_app_name.sock', backlog: 64
worker_processes 4
# ユーザ名をDigitalOceanデフォルトのrailsにする
user "rails"
working_directory root
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn.log"
stdout_path "#{root}/log/unicorn.log"
リンク先を参考にしつつDigitalOceanのデフォルト/etc/unicorn.conf
を書き換えました。
https://gist.github.com/ChuckJHardy/f44dda5f94c6bbdba9a4
Capistrano
$ bundle exec cap install
# 編集内容全体はリンク先を参照
$ vi Capfile
$ vi config/deploy.rb
$ vi config/deploy/production.rb
# repositoryを設定
set :repo_url, 'git@github.com:USER/capistrano-example.git'
# databaseはDigitalOceanの環境変数で管理し、secretsはそれで管理できないのでgit管理外にしてdeploy時にアップロードする
set :linked_files, fetch(:linked_files, []).push('config/secrets.yml')
namespace :deploy do
desc 'Upload secrets.yml'
task :upload do
on roles(:app) do |host|
if test "[ ! -d #{shared_path}/config ]"
execute "mkdir -p #{shared_path}/config"
end
upload!('config/secrets.yml', "#{shared_path}/config/secrets.yml")
end
end
task :restart do
invoke 'unicorn:reload'
end
before :starting, :upload
end
下記リンクを参考にdeploy:upload
を追加
http://chroju89.hatenablog.jp/entry/2014/04/12/215628
#ユーザ名をDigitalOceanデフォルトのrailsにする
set :user, 'rails'
#DigitalOceanで作成したドロップレットのIPを指定する
server '123.333.333.333',
# ssh_optionsのuserもrailsにする
# user: 'deployer',
user: fetch(:user),
上記設定の内repositoryの公開に疑問がある設定は全部ENV['key_name']
に変換しましょう。Capistrano関連のファイルは.env
ファイルに書いても適用されません。なので/etc/profile.d/deploy.sh
等にexport SERVER_IP='123.333.333.333'
といった感じで記述してシェルを再起動してからdeployするようにしましょう。
完成
$ git push origin master
DigitalOcean
有料ですので別のサービス利用の方は適宜対応してください。
ドロップレットの作成
Create Droplets
を選択し、One-click Apps
からRuby on Rails
を選択します。
料金プランは一番安いのでも可能ですが後述のスワップ領域の作成を行う必要があります。
webコンソール以外を利用する場合はAdd your SSH keys
の項目で作業端末の公開鍵を登録しておいてください。
スワップ領域の確保
メモリが足りない場合は、リンク先の手順通り行えば問題は無くなります。
最安プラン採用時この手順を行わなかった場合bundle install
した際にout of memory
で中断されます。
また、この手順をせずにdeployするとここでハマってCPUが常にビジー状態になってsshすら弾かれるようになったので気を付けてください。
鍵交換
# Cloud9側の公開鍵を取得する
$ cat ~/.ssh/id_rsa.pub
# Error reading response length from authentication socketにならないようにssh-agentを設定する
$ eval `ssh-agent -s`
$ ssh-add ~/.ssh/id_rsa
# DigitalOceanのドロップレットへ入る
$ ssh root@123.123.123.123
$ su rails
$ ssh-keygen
$ vi ~/.ssh/authorized_keys
# Cloud9の公開鍵を設定
$ cat ~/.ssh/id_rsa.pub
# 公開鍵をgithubに登録
unicorn
稼働しているソケットを確認します。
$ ps auxf | grep unicorn | grep -v grep
root 1562 0.0 2.4 77696 12356 ? Sl 01:33 0:00 unicorn master -D -c /etc/unicorn.conf -E production
$ vi /etc/unicorn.conf
listen "unix:/var/run/unicorn.sock"
#デフォルトのunicornプロセスは停止させておく
$ kill -QUIT 1562
/var/run/unicorn.sock
で稼働している事が分かったので/etc/unicorn.conf
を参考にunicornの設定を書きました。
Nginx
upstream app_server {
server unix:/tmp/unicorn.my_app_name.sock fail_timeout=0;
}
$ sudo service nginx restart
PostgreSQL
DigitalOcean側のDBの初期設定を行います。
Cloud9と同じmy_app_name
で登録します。
$ sudo -u postgres psql
postgres=# create role my_app_name with createdb login password 'PA$$W0rd';
postgres=# create database my_app_name_production owner my_app_name;
環境変数
$ sudo vi /etc/environment
# MY_APP_NAME_DATABASE_PASSWORD='PA$$W0rd' # ADD
リンク先にもっと良いやり方が書いてあるような気がするのですが、試してみても上手くいきませんでした。
http://stackoverflow.com/questions/23672631/capistrano-and-environment-variables
Cloud9からデプロイ
$ rake secret
$ vi config/secrets.yml
# 環境変数なり直書きなりでproductionのsecret_key_baseを設定する
$ bin/bundle exec cap production deploy