Ubuntu 14.04でGitフックを使用してRailsアプリをデプロイする方法

前書き

このチュートリアルでは、Gitフックを使用して、Railsアプリケーションの本番環境のリモートUbuntu 14.04サーバーへのデプロイメントを自動化する方法を示します。 Gitフックを使用すると、データベース移行の実行などを手動でプルして実行する代わりに、変更を運用サーバーにプッシュするだけでアプリケーションをデプロイできます。 アプリケーションでの作業を続けると、Gitフックなどの何らかの形の自動デプロイをセットアップすると、長期的に時間を節約できます。

この特定のセットアップは、アプリケーションサーバーとしてのPuma、PumaへのリバースプロキシとしてのNginx、およびデータベースとしてのPostgreSQLに加えて、単純な「受信後」のGitフックを使用します。

Git Hooksが初めてで、先に進む前に詳細を知りたい場合は、このチュートリアルを読んでください:https://www.digitalocean.com/community/tutorials/how-to-use-git-hooks-to-automate-development -and-deployment-tasks [Gitフックを使用して開発および展開タスクを自動化する方法]。

前提条件

Ubuntuサーバーでスーパーユーザー特権を持つ非ルートユーザーへのアクセスが必要になります。 サンプルのセットアップでは、「++」というユーザーを使用します。 このチュートリアルでは、その設定方法を説明します:https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04[Ubuntu 14.04での初期サーバー設定]。 パスワードを入力せずに展開する場合は、必ずSSHキーを設定してください。

サーバーにRubyをインストールする必要があります。 まだ行っていない場合は、https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-ubuntuを使用してRailsとともにインストールできます-14-04 [rbenv]またはhttps://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-on-ubuntu-14-04-using-rvm[RVM]。

ローカル開発マシンのgitリポジトリで管理されるRailsアプリケーションも必要です。 まだ持っていないのでフォローしたい場合は、簡単なサンプルアプリを提供します。

始めましょう!

PostgreSQLをインストールする

ほとんどの実動Rails環境はPostgreSQLをデータベースとして使用するため、今すぐサーバーにインストールしてみましょう。

*運用*サーバーで、apt-getを更新します。

sudo apt-get update

次に、これらのコマンドを使用してPostgreSQLをインストールします。

sudo apt-get install postgresql postgresql-contrib libpq-dev

実稼働データベースユーザーの作成

物事を簡単にするために、運用データベースユーザーにアプリケーション名と同じ名前を付けましょう。 たとえば、アプリケーションの名前が「appname」の場合、次のようなPostgreSQLユーザーを作成する必要があります。

sudo -u postgres createuser -s

データベースユーザーのパスワードを設定したいので、次のようにPostgreSQLコンソールを入力します。

sudo -u postgres psql

次に、データベースユーザーのパスワード(この例では「appname」)を次のように設定します。

\password

希望のパスワードを入力して確認します。

次のコマンドでPostgreSQLコンソールを終了します。

\q

これで、適切なデータベース接続情報を使用してアプリケーションを構成する準備が整いました。

Railsアプリケーションを準備する

開発マシン、おそらくローカルコンピューターで、アプリケーションを展開する準備をします。

オプション:Railsアプリケーションを作成する

理想的には、デプロイしたいRailsアプリケーションがすでに存在します。 この場合、このサブセクションをスキップして、それに沿って適切な置換を行うことができます。 そうでない場合、最初のステップは新しいRailsアプリケーションを作成することです。

これらのコマンドは、ホームディレクトリに「appname」という名前の新しいRailsアプリケーションを作成します。 強調表示された「アプリ名」を別のものに置き換えてください。

cd ~
rails new

次に、アプリケーションディレクトリに移動します。

cd

サンプルアプリの場合、scaffoldコントローラーを生成して、アプリケーションに表示するものを追加します。

rails generate scaffold Task title:string note:text

次に、アプリケーションがgitリポジトリにあることを確認します。

Gitリポジトリの初期化

何らかの理由でアプリケーションがまだGitリポジトリにない場合は、初期化して最初のコミットを実行します。

*開発マシン*で、アプリケーションのディレクトリに移動します。 この例では、アプリは「appname」と呼ばれ、ホームディレクトリにあります。

cd
git init
git add -A
git commit -m 'initial commit'

次に、アプリケーションを調整して、実稼働PostgreSQLデータベースに接続する準備をします。

データベース構成の更新

*開発マシン*で、アプリケーションのディレクトリにまだ移動していない場合は変更します。 この例では、アプリは「appname」と呼ばれ、ホームディレクトリにあります。

cd

ここで、お気に入りのエディターでデータベース構成ファイルを開きます。 `+ vi +`を使用します。

vi config/database.yml

アプリケーションのデータベース構成の* production *セクションを見つけ、それを本番データベースの接続情報に置き換えます。 正確に設定された例を実行した場合、次のようになります(必要に応じて値を置き換えます)。

config / database.ymlの抜粋

production:
 <<: *default
 host: localhost
 adapter: postgresql
 encoding: utf8
 database:
 pool: 5
 username: <%= ENV['_DATABASE_USER'] %>
 password: <%= ENV['_DATABASE_PASSWORD'] %>

保存して終了。 これは、アプリケーションの本番環境がローカルホストの本番サーバーで「appname_production」というPostgreSQLデータベースを使用することを指定します。 データベースのユーザー名とパスワードは環境変数に設定されていることに注意してください。 これらは後でサーバー上で指定します。

Gemfileを更新

GemfileにPostgreSQLアダプターgem、 + pg +、およびPuma gemがまだ指定されていない場合は、ここで追加する必要があります。

お気に入りのエディターでアプリケーションのGemfileを開きます。 ここでは、「+ vi +」を使用します。

vi Gemfile

Gemfileに次の行を追加します。

Gemfileの抜粋

group :production do
 gem 'pg'
 gem 'puma'
end

保存して終了。 これは、 + production`環境が + pg + + puma + `gemを使用することを指定します。

プーマを構成する

Pumaを構成する前に、サーバーのCPUコアの数を調べる必要があります。 次のコマンドを使用すると、サーバー上で簡単に実行できます。

grep -c processor /proc/cpuinfo

次に、*開発マシン*で、Puma設定を `+ config / puma.rb +`に追加します。 テキストエディターでファイルを開きます。

vi config/puma.rb

この構成をコピーしてファイルに貼り付けます。

config / puma.rb

# Change to match your CPU core count
workers

# Min and Max threads per worker
threads 1, 6

app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"

# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env

# Set up socket location
bind "unix://#{shared_dir}/sockets/puma.sock"

# Logging
stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true

# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
activate_control_app

on_worker_boot do
 require "active_record"
 ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
 ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
end

`+ workers +`の数をサーバーのCPUコアの数に変更します。 この例では、2つのコアがあることを前提としています。

保存して終了。 これにより、アプリケーションの場所と、ソケット、ログ、およびPIDの場所でPumaが構成されます。 ファイルを自由に変更するか、必要な他のオプションを追加してください。

最近の変更をコミットします。

git add -A
git commit -m 'added pg and puma'

次に進む前に、アプリの本番環境で使用される秘密鍵を生成します。

rake secret
rake secret sample output:29cc5419f6b0ee6b03b717392c28f5869eff0d136d8ae388c68424c6e5dbe52c1afea8fbec305b057f4b071db1646473c1f9a62f803ab8386456ad3b29b14b89

出力をコピーし、それを使用して、次のステップでアプリケーションの `+ SECRET_KEY_BASE`を設定します。

Puma Upstartスクリプトを作成する

Upstart initスクリプトを作成して、Pumaを簡単に起動および停止し、起動時に確実に起動できるようにします。

*実稼働サーバー*で、Puma GitHubリポジトリからホームディレクトリにJungle Upstartツールをダウンロードします。

cd ~
wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/upstart/puma-manager.conf
wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/upstart/puma.conf

提供された `+ puma.conf +`ファイルを開いて、Pumaデプロイメントユーザーを設定します。

vi puma.conf

`+ setuid `と ` setgid +`を指定する2行を探し、「apps」を展開ユーザーとグループの名前に置き換えます。 たとえば、展開ユーザーが「展開」と呼ばれる場合、行は次のようになります。

puma.confの抜粋1/2

setuid
setgid

次の行を探します: + exec / bin / bash << 'EOT' +。 その下に次の行を追加し、PostgreSQLのユーザー名とパスワード、および以前に作成したrakeシークレットを必ず置き換えます。

puma.confの抜粋2/2

 export _DATABASE_USER=''
 export _DATABASE_PASSWORD=''
 export SECRET_KEY_BASE=''

保存して終了。

次に、スクリプトをUpstartサービスディレクトリにコピーします。

sudo cp puma.conf puma-manager.conf /etc/init

`+ puma-manager.conf `スクリプトは、管理するアプリケーションの ` / etc / puma.conf +`を参照します。 そのインベントリファイルを作成して編集しましょう。

sudo vi /etc/puma.conf

このファイルの各行は、 `+ puma-manager +`で管理したいアプリケーションへのパスでなければなりません。 ユーザーのホームディレクトリにある「appname」という名前のディレクトリにアプリケーションをデプロイします。 この例では、次のようになります(アプリが存在する場所へのパスを必ず更新してください:

/etc/puma.conf

/home//

保存して終了。

これで、Upstartを使用して、起動時にアプリケーションが起動するように設定されました。 これは、サーバーを再起動した後でもアプリケーションが起動することを意味します。 アプリケーションをデプロイしていないため、まだ開始したくないことに注意してください。

Nginxのインストールと構成

アプリケーションがインターネットにアクセスできるようにするには、NginxをWebサーバーとして使用する必要があります。

apt-getを使用してNginxをインストールします。

sudo apt-get install nginx

次に、デフォルトのサーバーブロックをテキストエディターで開きます。

sudo vi /etc/nginx/sites-available/default

ファイルの内容を次のコードブロックに置き換えます。 強調表示された部分を適切なユーザー名とアプリケーション名(2つの場所)に置き換えてください:

/ etc / nginx / sites-available / default

upstream app {
   # Path to Puma SOCK file, as defined previously
   server unix:/home///shared/sockets/puma.sock fail_timeout=0;
}

server {
   listen 80;
   server_name localhost;

   root /home///public;

   try_files $uri/index.html $uri @app;

   location @app {
       proxy_pass http://app;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Host $http_host;
       proxy_redirect off;
   }

   error_page 500 502 503 504 /500.html;
   client_max_body_size 4G;
   keepalive_timeout 10;
}

保存して終了。 これにより、Nginxがリバースプロキシとして構成され、HTTPリクエストがUnixソケットを介してPumaアプリケーションサーバーに転送されます。 必要に応じて自由に変更を加えてください。

アプリケーションがまだサーバーに存在しないため、Nginxの再起動は今のところ控えています。 次にアプリケーションを準備します。

Production Git Remoteを準備する

*本番サーバー*で、apt-getを使用してgitをインストールします。

sudo apt-get install git

次に、リモートリポジトリ用のディレクトリを作成します。 「appname_production」というホームディレクトリにベアgitリポジトリを作成します。 リモートレポジトリには自由に名前を付けてください(ただし、 `+〜/ appname +`には入れないでください)

mkdir ~/
cd ~/
git init --bare

これはベアリポジトリであるため、作業ディレクトリはなく、従来のセットアップでは.gitにあるすべてのファイルはメインディレクトリ自体にあります。

ポスト受信gitフックを作成する必要があります。これは、実稼働サーバーがgit pushを受信したときに実行されるスクリプトです。 エディターで `+ hooks / post-receive +`ファイルを開きます:

vi hooks/post-receive

次のスクリプトをコピーして、 `+ post-receive +`ファイルに貼り付けます:

フック/受信後

#!/bin/bash

GIT_DIR=/home/
WORK_TREE=/home/
export _DATABASE_USER=''
export _DATABASE_PASSWORD=''

export RAILS_ENV=production
. ~/.bash_profile

while read oldrev newrev ref
do
   if [[ $ref =~ .*/master$ ]];
   then
       echo "Master ref received.  Deploying master branch to production..."
       mkdir -p $WORK_TREE
       git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout -f
       mkdir -p $WORK_TREE/shared/pids $WORK_TREE/shared/sockets $WORK_TREE/shared/log

       # start deploy tasks
       cd $WORK_TREE
       bundle install
       rake db:create
       rake db:migrate
       rake assets:precompile
       sudo restart puma-manager
       sudo service nginx restart
       # end deploy tasks
       echo "Git hooks deploy complete"
   else
       echo "Ref $ref successfully received.  Doing nothing: only the master branch may be deployed on this server."
   fi
done

以下の強調表示された値を必ず更新してください。

  • + GIT_DIR +:前に作成したベアgitリポジトリのディレクトリ

  • + WORK_TREE +:アプリケーションをデプロイするディレクトリ(これは、Puma設定で指定した場所と一致する必要があります)

  • + APPNAME_DATABASE_USER +:PostgreSQLユーザー名(rakeタスクに必要)

  • + APPNAME_DATABASE_PASSWORD +:PostgreSQLパスワード(rakeタスクに必要)

次に、 +#start deploy tasks +`と `+#end deploy tasks +`コメントの間のコマンドを確認する必要があります。 これらは、masterブランチが本番gitリモート( `+ appname_production +)にプッシュされるたびに実行されるコマンドです。 そのままにしておくと、サーバーはアプリケーションの実稼働環境に対して次のことを試みます。

  • バンドラーを実行

  • データベースを作成する

  • データベースを移行する

  • アセットをプリコンパイルします

  • プーマを再起動

  • Nginxを再起動します

変更を加えるか、エラーチェックを追加する場合は、ここでそれを行ってください。

受信後スクリプトの確認が完了したら、保存して終了します。

次に、スクリプトを実行可能にします。

chmod +x hooks/post-receive

パスワードなしのSudo

post-receiveフックはsudoコマンドを実行する必要があるため、デプロイユーザーがパスワードなしの「+ sudo +」を使用できるようにします(異なる場合は、ここにデプロイユーザー名を代入します)。

sudo sh -c 'echo " ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-deploy'

これにより、 `+ deploy `ユーザーはパスワードを入力せずに ` sudo +`コマンドを実行できます。 おそらく、デプロイユーザーがスーパーユーザー特権で実行できるコマンドを制限することに注意してください。 少なくとも、SSHキー認証を使用し、パスワード認証を無効にする必要があります。

Production Git Remoteを追加する

実稼働サーバーですべての設定が完了したので、実稼働gitリモートをアプリケーションのリポジトリに追加しましょう。

*開発マシン*で、アプリケーションのディレクトリにいることを確認します。

cd

次に、実稼働サーバーで作成したベアgitリポジトリ `+ appname_production +`を指す「production」という名前の新しいgitリモートを追加します。 ユーザー名(展開)、サーバーIPアドレス、およびリモートリポジトリ名(appname_production)を置き換えます。

git remote add production @:

これで、アプリケーションをgit pushでデプロイする準備が整いました。

本番にデプロイする

すべての準備が完了したら、次のgitコマンドを実行して、アプリケーションを運用サーバーに展開できます。

git push production master

これは、先ほど作成した本番用のリモートにローカルマスターブランチをプッシュするだけです。 プロダクションリモコンがプッシュを受信すると、前に設定した `+ post-receive +`フックスクリプトを実行します。 すべてを正しくセットアップすると、アプリケーションは運用サーバーのパブリックIPアドレスで利用できるようになります。

サンプルアプリケーションを使用した場合、Webブラウザーで `+ http:/// tasks +`にアクセスして、次のように表示できるはずです。

image:https://assets.digitalocean.com/articles/rails_githooks/tasks.png [Railsアプリのサンプル]

結論

アプリケーションに変更を加えるときはいつでも、同じgit pushコマンドを実行して運用サーバーにデプロイできます。 これだけでも、プロジェクトの全期間にわたって多くの時間を節約できます。

このチュートリアルでは「受信後」フックについてのみ説明しましたが、展開プロセスの自動化を改善するのに役立つ他の種類のフックがいくつかあります。 Gitフックの詳細については、このチュートリアルをお読みください:https://www.digitalocean.com/community/tutorials/how-to-use-git-hooks-to-automate-development-and-deployment-tasks[How To Use Git開発および展開タスクを自動化するフック]!