Edited at

ansibleを使った事ない僕がansibleつかってawsにRails + Nginx + Unicorn 環境をセットアップをしてみた(まさかの手動あり)

More than 5 years have passed since last update.


前提

AWSのインスタンス立ち上げ済み


ansibleってみる

まずはinstall

brew install python

sudo easy_install pip
sudo pip install ansible

ansibleのひな形を取得

git clone https://github.com/morizyun/vagrant-ansible-rails

cd vagrant-ansible-rails
cp ./ansible/hosts_vagrant ./ansible/hosts_aws

./ansible/hosts_aws の内容を書き換える


書き換え前

[app]

192.168.33.10 ansible_ssh_user=vagrant ansible_connection=ssh ansible_ssh_private_key_file=~/.ssh/id_rsa


書き換え後(例)

[app]

(IP) ansible_ssh_user=ec2user ansible_connection=ssh ansible_ssh_private_key_file=(pemファイルのパス)

playbookの内容を書き換える


書き換え前

---

- hosts: app
sudo: true
vars:
hostname:
server-production
environtment: production
ruby_version: 2.1.2
rbenv_root: /home/vagrant/.rbenv
rbenv_bin: /home/vagrant/.rbenv/libexec/rbenv
roles:
- common
- rvm
- nginx
- mysql
- rails
#- troubleshooting


書き換え後(例)

---

- hosts: app
sudo: true
vars:
hostname:
server-production
environtment: production
ruby_version: 2.1.2
rbenv_root: /home/ec2-user/.rbenv
rbenv_bin: /home/ec2-user/.rbenv/libexec/rbenv
roles:
- common
- rvm
- nginx
- mysql
- rails
#- troubleshooting

nginxのパスやsslの設定を書き換える(下記の①、②)。


ansible/roles/nginx/files/production/nginx.conf

user  nginx;

worker_processes 1;

error_log /var/log/nginx/error.log;

pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

gzip on;
gzip_http_version 1.0;
gzip_types text/plain
text/xml
text/css
application/xml
application/xhtml+xml
application/rss+xml
application/atom_xml
application/javascript
application/x-javascript
application/x-httpd-php;
gzip_disable "MSIE [1-6]\.";
gzip_disable "Mozilla/4";
gzip_comp_level 1;
gzip_proxied any;
gzip_vary on;

# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;

upstream backend {
server 127.0.0.1:5001;
}

server {
listen 80;
server_name DOMAIN_NAME;
# root は自分の好きな場所に設定 ①
root /home/ec2-user/apps/public;

location ~* \.(ico|css|js|gif|jpg|jpeg|png|otf|svg|woff|eot|ttf)(\?[0-9]+)?$ {
# only production
expires 1y;
break;
}
}

# ひとまず https は使わないのでコメントアウトしました。 ②
# server {
# listen 443 default ssl;
# server_name DOMAIN_NAME;
# root /home/ec2-user/apps/public;
#
# ssl on;
# ssl_certificate /etc/nginx/ssl/cert.pem;
# ssl_certificate_key /etc/nginx/ssl/server.key;
#
# include mime.types;
# default_type application/octet-stream;
# sendfile on;
# keepalive_timeout 65;
#
# location / {
# client_max_body_size 20M;
# rewrite ^\/ja(/.*)$ $1 permanent;
# rewrite ^\/ja$ / permanent;
# rewrite ^(.+[^/])/$ $1 permanent;
# proxy_pass http://backend;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header Host $http_host;
# proxy_set_header X-Forwarded-Proto https;
# }
#
# satisfy any;
# }

}


ansibleの実行を行う

export ANSIBLE_HOSTS=./ansible/hosts_aws

ansible-playbook ./ansible/playbook_production.yml

以上でサーバに環境がそろいました。

ここからは手動でunicornを入れていきます。

sshでログイン後、railsのインストールとアプリの作成をします。

rvmsudo gem install rails bundler --no-ri --no-rdoc

rails new apps --database=mysql
cd apps

Gemfileに下記を追加します

gem 'therubyracer', platforms: :ruby

gem 'unicorn'

bundle installしてDBを作ります。

bundle install

rake db:create

Unicornの設定を行います。vim config/unicorn.rb


unicorn.rb

@app_path = '/home/ec2-user/apps'

worker_processes 2
working_directory "#{@app_path}/"

# This loads the application in the master process before forking
# worker processes
# Read more about it here:
# http://unicorn.bogomips.org/Unicorn/Configurator.html
preload_app true

timeout 30

# This is where we specify the socket.
# We will point the upstream Nginx module to this socket later on
listen "/tmp/unicorn.sock", :backlog => 64

pid "/tmp/unicorn.pid"

# Set the path of the log files inside the log folder of the testapp
stderr_path "#{@app_path}/log/unicorn.stderr.log"
stdout_path "#{@app_path}/log/unicorn.stdout.log"

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

old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end

sleep 1
end

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


nginxのconfを触ります。


/etc/nginx/conf.d/apps.conf

upstream unicorn_server {

# This is the socket we configured in unicorn.rb
server unix:/tmp/unicorn.sock
fail_timeout=0;
}

server {
listen 80;
client_max_body_size 4G;
server_name _;

keepalive_timeout 5;

# Location of our static files
root /home/ec2-user/apps/public;

location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;

# If you don't find the filename in the static files
# Then request it from the unicorn server
if (!-f $request_filename) {
proxy_pass http://unicorn_server;
break;
}
}

error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/ec2-user/apps/public;
}
}


nginxの再起動とunicornの再起動をする

sudo /etc/init.d/nginx restart

unicorn_rails -c config/unicorn.rb -E development -D

以上で EC2インスタンスのipにアクセするとrailsアプリが動いている事が確認できると思います。


雑感

途中unicornあたりは本来であれば自分のRailsアプリごとgit cloneしてきてするなどして、

またnginxに継ぎ足したところなどももともとそう書いておけば完全自動化できそうです。

(今回の目的はあくまで使ってみる事にあったのでやりませんでしたが)


参考

Vagrant(CentOS6.5)にRails4.1 + Nginx + Unicorn + MySQL環境でRailsを起動する。

Vagrant/AWS + AnsibleでCentOS/Nginx/MySQL/RVM/Ruby2.1.2環境を構築

Ansible の Playbook を使ってみる