LoginSignup
51
51

More than 5 years have passed since last update.

Ansible を使って EC2 に Railsサーバーを立ち上げる

Last updated at Posted at 2015-07-11

バージョン&記載ソースリポジトリ

version
ansible 1.9.2

ポイントとなるソースのみ載せています。全てのソースが見たい場合は、以下のリポジトリを参照してください。

Ansible で構築したサーバーのアプリの各バージョン

version
rbenv 0.4.0-151-g83ac0fb
ruby 2.2.2p95
bundler 1.10.5
node.js 0.10.40
npm 1.4.28
nginx 1.6.2

概要

AWS EC2 Amazon Linux 環境に Rails アプリを nginx + unicorn で動かすための playbook を作成しました。

rbenv を利用した ruby、node.js、bundler、nginx をインストールします。
DB は RDS を利用する予定です。DataBase Server のインストールはしません。
unicorn は gem にてインストールするため playbook での記述は特にありません。

capistrano3 を利用した unicorn Rails アプリのデプロイについては、
Capistrano3 を使って Rails4 + unicorn + nginx + rbenv にデプロイする
に記載しました。

注意点

EC2 インスタンスを作るときに注意点があります。
インスタンスタイプが t2.micro, t2.small では rbenv での ruby 2.2.2 のインストールが最後まで終わりませんでした。
エラーも発生せず、途中で止まっているような状態です。インストールのプロセスが消えていることは確認しましたが、詳細は確認していません。

t2.medium で問題なく ruby 2.2.2 がインストールできることを確認しました。

rbenv, ruby のインストール

Ansible と Vagrant を使って Rails 開発環境(Ubuntu + rbenv + MySQL5.6 + node.js)を構築する - rbenv, ruby のインストール

以前、ubuntu にインストールする手順を書いていたので、この内容を Amazon Linux でも動くように修正しました。

roles/ec2-rbenv/taks/main.yml
---
- name: Install dependencies for rbenv
  yum: name={{ item }} state=latest
  with_items:
    - git

- name: Install rbenv
  sudo: yes
  sudo_user: "{{ rbenv_user }}"
  git: repo=https://github.com/sstephenson/rbenv.git dest=~/.rbenv

- name: Add ~.rbenv/bin to PATH
  sudo: yes
  sudo_user: "{{ rbenv_user }}"
  lineinfile: >
    dest="~/.bash_profile"
    line="export PATH=$HOME/.rbenv/bin:$PATH"

- name: Eval rbenv init in ~/.bash_profile
  sudo: yes
  sudo_user: "{{ rbenv_user }}"
  lineinfile: >
    dest="~/.bash_profile"
    line='eval "$(rbenv init -)"'

- name: Install dependencies for ruby-build (see. https://github.com/sstephenson/ruby-build/wiki)
  yum: name={{ item }} state=latest
  with_items:
    - gcc
    - openssl-devel
    - libyaml-devel
    - libffi-devel
    - readline-devel
    - zlib-devel
    - gdbm-devel
    - ncurses-devel

- name: Install ruby-build as rbenv plugin
  sudo: yes
  sudo_user: "{{ rbenv_user }}"
  git: repo=https://github.com/sstephenson/ruby-build.git dest=~/.rbenv/plugins/ruby-build

- name: Check if version is installed ruby
  shell: "sudo -iu {{ rbenv_user }} rbenv versions | grep {{ rbenv_ruby_version }}"
  register: rbenv_check_install
  changed_when: False
  ignore_errors: yes

- name: Install ruby
  command: "sudo -iu {{ rbenv_user }} rbenv install {{ rbenv_ruby_version }}"
  when: rbenv_check_install|failed

- name: Check if version is the default ruby version
  shell: "sudo -iu {{ rbenv_user }} rbenv version | grep {{ rbenv_ruby_version }}"
  register: rbenv_check_default
  changed_when: False
  ignore_errors: yes

- name: Set default ruby version
  command: "sudo -iu {{ rbenv_user }} rbenv global {{ rbenv_ruby_version }}"
  when: rbenv_check_default|failed

node.js のインストール

therubyracer でも良いのですが、node.js をインストールします。

Ansible と Vagrant を使って Rails 開発環境(Ubuntu + rbenv + MySQL5.6 + node.js)を構築する - node.js のインストール

node.js も、以前、ubuntu にインストールする手順を書いていたので、この内容を Amazon Linux でも動くように修正しました。

get_url の url を変更したのみです。

roles/ec2-nodejs/tasks/main.yml
---
- name: Download setup shell for nodejs
  get_url: url="https://rpm.nodesource.com/setup" dest="/tmp/setup_node.sh" mode=0755

- name: Setup nodejs
  shell: /tmp/setup_node.sh

- name: Install nodejs
  yum: name=nodejs state=latest

2015.07.12時点では、https://rpm.nodesource.com/setup_0.12 を利用して 0.12 系をインストールしようとすると以下のエラーが出ました。

## Installing the NodeSource Node.js 0.12 repo...


## Inspecting system...

+ rpm -q --whatprovides redhat-release || rpm -q --whatprovides centos-release || rpm -q --whatprovides cloudlinux-release
+ uname -m

## Confirming "el7-x86_64" is supported...

+ curl -sLf -o /dev/null 'https://rpm.nodesource.com/pub_0.12/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'

## Your distribution, identified as "system-release-2015.03-0.1.noarch", is not currently supported, please contact NodeSource at https://github.com/nodesource/distributions/issues if you think this is incorrect or would like your distribution to be considered for support

FATAL: all hosts have already failed -- aborting

ざっと見る限り、RHEL7(epel7)からの対応ということでしょうか。
最新の nodejs を利用したい場合/開発で利用する場合は、nvm, nodebrew からインストールしたほうが良さそうです。複数バージョンの管理もできるようになります。

今回は、ツールとして利用するだけですので 0.10系で問題ないと判断しました。

rails 環境用の各種インストール

RDS(MySQL)を利用する予定なので、gem mysql2 をインストールできるように mysql-devel をインストールします。
あと Rails アプリデプロイ時に必須となる bundler もインストールします。

riles/ec2-railsenv/tasks/main.yml
---
- name: Install mysql-devel
  yum: name={{ item }} state=latest
  with_items:
    - mysql-devel

- name: Install dependencies for nokogiri
  yum: name={{ item }} state=latest
  with_items:
    - patch

- name: Install bundler
  sudo_user: "{{ rbenv_user }}"
  gem: name={{ item }} executable=.rbenv/shims/gem user_install=False
  with_items:
    - bundler

2015.07.14 nokogiri のインストールで以下のエラーが発生しました。
patch.log を見ると patch がないためにエラーが発生していることがわかりましたので、上記の main.yml に patch のインストールを追加しました。

ERROR:  Error installing nokogiri:
    ERROR: Failed to build gem native extension.

    /home/ec2-user/.rbenv/versions/2.2.2/bin/ruby -r ./siteconf20150713-20402-2gqq60.rb extconf.rb
checking if the C compiler accepts ... yes
Building nokogiri using packaged libraries.
checking for gzdopen() in -lz... yes
checking for iconv... yes
************************************************************************
IMPORTANT NOTICE:

Building Nokogiri with a packaged version of libxml2-2.9.2
with the following patches applied:
    - 0001-Revert-Missing-initialization-for-the-catalog-module.patch
    - 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch

Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:

    gem install nokogiri -- --use-system-libraries
        [--with-xml2-config=/path/to/xml2-config]
        [--with-xslt-config=/path/to/xslt-config]

If you are using Bundler, tell it to use the option:

    bundle config build.nokogiri --use-system-libraries
    bundle install

Note, however, that nokogiri is not fully compatible with arbitrary
versions of libxml2 provided by OS/package vendors.
************************************************************************
Extracting libxml2-2.9.2.tar.gz into tmp/x86_64-unknown-linux-gnu/ports/libxml2/2.9.2... OK
Running patch with /home/ec2-user/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/nokogiri-1.6.6.2/ports/patches/libxml2/0001-Revert-Missing-initialization-for-the-catalog-module.patch...
Running 'patch' for libxml2 2.9.2... ERROR, review '/home/ec2-user/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/nokogiri-1.6.6.2/ext/nokogiri/tmp/x86_64-unknown-linux-gnu/ports/libxml2/2.9.2/patch.log' to see what happened.
*** extconf.rb failed ***

Nginx のインストール

本番サーバーでは使うことはないと思いますが、SSL を利用するための自己証明書(オレオレ証明書)も以下を参考に作っています。

デフォルトの index.html, 404.html, 50x.html の置き換えもここで実施しています。
今はできていませんが、上記の html は、playbook で変更できるようにしたかったです。

Nginx の設定は、改善する必要があります。
最低限の設定のみ行っています。設定内容は以下で確認できます。

roles/ec2-nginx/tasks/main.yml
---
- name: Install nginx
  yum: name=nginx state=latest

- name: Set nginx service to start on boot
  service: name=nginx enabled=true

- name: Put nginx.conf
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf backup=true mode=0644
  notify: restart nginx

- name: Create self signed certificate
  shell: |
    mkdir -p /etc/nginx/certs &&
    crt_file="/etc/nginx/certs/local-ssl.crt" &&
    key_file="/etc/nginx/certs/local-ssl.key" &&
    crt_and_key_file="/etc/nginx/certs/local-ssl.crt_and_key" &&
    subject="/C=JP/ST=Osaka/L=Osaka City/CN=local-ssl" &&
    openssl req -new -newkey rsa:2048 -sha1 -x509 -nodes \
      -set_serial 1 \
      -days 3650 \
      -subj "$subject" \
      -out "$crt_file" \
      -keyout "$key_file" &&
    cat "$crt_file" "$key_file" >> "$crt_and_key_file" &&
    chmod 400 "$key_file" "$crt_and_key_file"
    creates="/etc/nginx/certs/local-ssl.crt"

- name: Put share index.html
  template: src=index.html.j2 dest=/usr/share/nginx/html/index.html mode=644

- name: Put share 404.html
  template: src=404.html.j2 dest=/usr/share/nginx/html/404.html mode=644

- name: Put share 50x.html
  template: src=50x.html.j2 dest=/usr/share/nginx/html/50x.html mode=644

Playbook のサンプルと実行

必要な role を読み込みます。

ec2-rails.example.yml
- hosts: all
  sudo: yes
  vars:
    rbenv_user: ec2-user
    rbenv_ruby_version: 2.2.2
  roles:
    - ec2-yum-update
    - ec2-rbenv
    - ec2-nodejs
    - ec2-railsenv
    - ec2-nginx

以下で inventory ファイルなしで実行できます。
ぼくは相変わらず inventory ファイルなしで実行してばかりです。
本格的な運用をしてないからだと思います。

$ ansible-playbook -i "xxx.xxx.xxx.xxx," --user=ec2-user --private-key=xxx.pem ec2-rails.example.yml

感想

Ansible と Vagrant を使って Rails 開発環境(Ubuntu + rbenv + MySQL5.6 + node.js)を構築する

で、Rails 開発環境構築を行う playbook を作っていたので、簡単に作ることができると思いましたが、インスタンスタイプで ruby 2.2.2 のインストールができないところでつまづきました。
エラーすら発生しなかったので、終わらないなーっと思いながら、ボーッと待って時間を無駄にしました。

51
51
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
51