AWSでRailsアプリを動かしてみよう計画【最終回:RDS連携とCircleCI連携】

計3回にわたってお送りした「AWSRailsアプリを動かしてみよう計画」も今回で最終回です

今回はRDS連携とCircleCI連携を目指します。以下のことが達成できれば目的達成とします

RDS連携…EC2で動いているアプリをRDS上のDBに接続する

CircleCI連携githubにpushしてテストが通ったら自動的にデプロイされるようにする

RDS連携

RDSとは

Amazon Relational Database Service (Amazon RDS) を使用すると、クラウドで簡単にリレーショナルデータベースを設定、運用、スケールできます。このサービスは、手間のかかるデータベース管理タスクをお客様の代わりに行いながら、コスト効率がよく、サイズ変更が可能な容量を提供します。これによってお客様は自身のアプリケーション開発やビジネスに集中することができます。

だそうです。訳さないでいいので楽ちん

第1回で軽く述べていますが、自動的にバックアップを取ってくれたり色々便利だそうです

現状

今まではとりあえず動かすということに注力していたため、DB周りは何も触っておらずデフォルトのsqlite3を使っていました

ちなみにRDSのインスタンスはたてており、かつPostgreSQLを導入済みとします(画面上からポチポチ出来たはずです)

EC2→RDSの接続確認

PostgreSQL導入

EC2インスタンスのコンソール上からRDSにアクセス出来るか確認してみます(以下の作業はEC2にsshで接続して行っています)

psqlコマンドで接続確認を行います。意気揚々とpsqlコマンドを叩いたらpostgresql-client-commonを入れろみたいなことを言われたので入れます

EC2側はPostgreSQLのクライアント側のみあれば良さそうなのでここを参考にインストール

$ sudo apt-get install postgresql-client-common

再挑戦

ubuntu@ip-xx-xx-xx-xx:~$ psql -h
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LC_CTYPE = "ja_JP.UTF-8",
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
Error: You must install at least one postgresql-client-<version> package.

最下行でエラー発生、postgresql-client-<version>をインストールする(バージョン指定するの忘れてました(・ω<))

$ sudo apt-get install postgresql-client

バージョンを確認してみると9.3が入った模様

ついでにここを参考にlocaleの警告にも対応

# ~/.bashrc
export LC_ALL=en_US.UTF-8

これでpsqlコマンドが使えるようになりました

接続確認

下記のオプションを使ってEC2→RDSの接続確認を行います(オプション群に名を連ねていませんが--dbnameも指定します) 参考

Connection options:
  -h, --host=HOSTNAME      database server host or socket directory (default: "local socket")
  -p, --port=PORT          database server port (default: "5432")
  -U, --username=USERNAME  database user name (default: "ubuntu")
  -w, --no-password        never prompt for password
  -W, --password           force password prompt (should happen automatically)

実際に叩くコマンドは以下の様な感じ

$ psql --host=[HOSTNAME] --port=[PORT] --username=[USERNAME] --password --dbname=[DBNAME]

ポートが開放されていなかった模様

psql: could not connect to server: Connection timed out
        Is the server running on host "[HOSTNAME]" (xx.xx.xx.xx) and accepting
        TCP/IP connections on port 5432?

PostgreSQLのデフォルトポートである5432ポートを解き放ちます(ブラウザ上からRDSにインバウンドを追加します) 参考

ubuntu@ip-xx-xx-xx-xx:~$ psql --host=[HOSTNAME] --port=[PORT] --username=[USERNAME] --password --dbname=[DBNAME]
Password for user [USERNAME]:
psql (9.3.9, server 9.4.1)
WARNING: psql major version 9.3, server major version 9.4.
         Some psql features might not work.
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
[DBNAME]=>

接続自体はできたようですがバージョンが違うため警告が出ているようです。癪に障るのでバージョン9.4を入れて警告が出なくなったことを確認

ubuntu@ip-xx-xx-xx-xx:~$ psql --version
psql (PostgreSQL) 9.4.4

ubuntu@ip-xx-xx-xx-xx:~$ psql --host=[HOST] --port=[PORT] --username=[USERNAME] --password --dbname=[DBNAME]
Password for user [USERNAME]:
psql (9.4.4, server 9.4.1)
SSL connection (protocol: TLSv1.2, cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

[DBNAME]=>

接続確認終了

RailsアプリとPostgreSQLを接続

EC2→RDS間の接続確認ができたので、続いてRailsアプリとRDS上のPostgreSQLを接続させていきます

設定ファイルの反映

サーバのshared配下のdatabase.yml修正

# /var/www/[APPLICATION_NAME]/shared/config/database.yml

production:
  adapter: postgresql
  encoding: unicode
  database: [DBNAME]
  pool: 5
  username: [USERNAME]
  password: [PASSWORD]
  host: [HOST]
  port: [PORT]

production環境でpostgresqlを使うようにします

# Gemfile

group :dvelopment, :test do
  gem 'sqlite3'
end

gem 'pg', group: :production

bundle install後にpushしてコマンド叩くとエラー発生

$ be cap production deploy BRANCH=postgresql

(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as ubuntu@xx.xx.xx.xx: bundle exit status: 5
bundle stdout: An error occurred while installing pg (0.18.2), and Bundler cannot continue.
Make sure that `gem install pg -v '0.18.2'` succeeds before bundling.
bundle stderr: Nothing written

ググってみたらlibpq-devを入れたら良さそう

$ sudo apt-get install libpq-dev

libpq-dev導入後にcapコマンドが通るようになりました

これで反映されているはずです

データが登録されているか確認

Railsアプリにブラウザ上からアクセスしてユーザを作りDBを覗いてちゃんと作られているか確認(Userモデルがあり、ブラウザ上からcreateできるという想定です)

EC2上で以下のコマンドでDBにアクセスしてテーブル一覧確認を確認してみます

$ RAILS_ENV=production bundle exec rails db

usersというテーブルがあれば以下のような感じで表示されるはずです(※編集の都合上テーブルのフォーマットいじっています)

[DBNAME]=> \d

          List of relations
| Schema | Name  | Type  | Owner      |
|--------|-------|-------|------------|
| public | users | table | [USERNAME] |

データが入っていることを確認できると思います

[DBNAME]=> select * from users;

| id | name | email            | password   |
|----|------|------------------|------------|
| 1  | hoge | hoge@example.com | [PASSWORD] |

これでEC2インスタンス上のRailsアプリから、RDSインスタンス上のPostgreSQLに接続できるようになりました

CircleCI連携

CircleCIとは

Improve Productivity, Reduce Risk, and Scale with CircleCI

Let CircleCI help your team focus on making a great product. Speed up your testing and development cycle to improve productivity. CircleCI is flexible to run in your environment and scale with your growth. Have the peace of mind by reducing bugs and improving the quality of your application.

  • 生産性の向上、リスク低減
  • テストや開発サイクルの高速化
  • バグの減少とアプリケーションの質の向上により心の平和を保つ

ちゃんと把握しきれていませんが「テストや開発サイクル(デプロイとか?)の高速化」というのがメインの機能かなという認識です

Setup

Getting started with CircleCIにも書いてあるように容易にセットアップが完成します(ほとんどのアプリで以下の3ステップで完結するようです)

  • CircleCIにサインアップする
  • 権限を与える
  • プロジェクトをクリックする

setup後、pushしたら自動でbuildしてくれるみたいです

push後buildは淡々と進んでいきますが、bundle installで落ちました

Gem::InstallError: babosa requires Ruby version >= 2.0.0.

バージョン指定して再度挑戦したら通りました

# Gemfile
ruby '2.2.2'

buildが通ることを確認してsetup終了

デプロイさせる

今までは開発環境からcapコマンドを打っていましたが、githubにpushした時に問題(テスト失敗など)がなければ自動的にcapコマンドを実行してくれるように設定します

circle.ymlを下記記事を参照して設定します

色々設定ができるようですが、今回はmasterブランチにpushしたらデプロイが行われるようにします

machine:
  ruby:
    version: 2.2.2

deployment:
  production:
    branch: master
    commands:
      - bundle exec cap production deploy

pushしてみたら$ bundle exec cap production deployのところでbuildに失敗しました

DEBUG [887a13b5] Running /usr/bin/env [ -d ~/.rbenv/versions/2.2.2 ] as ubuntu@xx.xx.xx.xx
DEBUG [887a13b5] Command: [ -d ~/.rbenv/versions/2.2.2 ]
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as ubuntu@xx.xx.xx.xx: Authentication failed for user ubuntu@xx.xx.xx.xx

Net::SSH::AuthenticationFailed: Authentication failed for user ubuntu@xx.xx.xx.xx

Tasks: TOP => rbenv:validate

bundle exec cap production deploy returned exit code 1

(See full trace by running task with --trace) Action failed: bundle exec cap production deploy

sshの認証で失敗している様子なので~/Download/oooooootuka.pemの中身をCircleCIのSSH keysに追加して、再度pushするとデプロイまで通ったようです。push後、currentディレクトリのリンク先がpushした時刻になっていることを確認します

ubuntu@ip-xx-xx-xx-xx:/var/www/[APPLICATION_NAME]$ ls -l
total 16
lrwxrwxrwx 1 ubuntu ubuntu   47 Jun 25 06:19 current -> /var/www/[APPLICATION_NAME]/releases/20150625061845
...
...

大丈夫そう


設定とか調整する必要はありますが、これで「AWSRailsアプリを動かしてみよう計画(CircleCIのおまけ付き)」は一旦終了です。めでたしめでたし