この記事はエイチーム引越し侍 / エイチームコネクト Advent Calendar 2019 14日目の記事です。本日はエイチーム引越し侍に入社してWEBエンジニア歴4ヶ月目に突入した@halktが担当します!
なぜこれをやろうと思ったのか?
一言で言うと、自分の力でWEBサービスをデプロイする経験をしてみたかったからです。
WEBエンジニアになる前は、社内サービスの維持運用を主として行なっていたため、物理的なサーバを建てたり、仮想マシンを作成したりということはしておりましたが、インフラなどはすでに構成された社内ネットワークの中でしか触ったことはありませんでした。
そのため、Webサービスを外部に公開する上での考慮事項や外からサービスに接続するための知識は特に足りていないと感じていたので、このテーマにまずは挑戦しようと思いました!!
兎にも角にもまずは触ってみなきゃ始まらん!と思い、下記の構成を目指し、タイトル通りハンズオン形式で学んだ内容をまとめてみたいと思います!
ゴールのイメージ
Railsなのは特にこだわりがあるわけでなく、たまたまあるアプリを使っただけです。最近だとECSやFargateを使った構成が多いと知りましたので別途挑戦したいと思います・・・!
🐳docker/docker-compose編
最初にローカルで作成していた既存のRailsアプリをdockerにのせました。dockerの勉強したいから、という理由がきっかけですが、コンテナをデプロイできるようになれば、他のアプリでデプロイをしたいときに応用が効くことを期待してdocker化から初めました。
実施内容
細かな作業内容などは割愛しますが、ざっくり下記のようなことをやりました。
- Dockerfile(Railsやnginx)の作成
- pumaとnginxのソケット通信の設定
- nginxの設定ファイルの修正
- docker-compose.ymlの作成
- buildしてアプリケーションを実行しアクセスする
- githubにpushしておく
docker-compose.ymlの作成
docker-composeは、複数コンテナ群の構成や動きを管理することができます。所謂インフラ構成のコード化が実現できます。
version: '3'
services:
app:
build:
context: .
environment:
MYSQL_ROOT_PASSWORD: XXX
MYSQL_DATABASE: XXX
command: bundle exec puma -C config/puma.rb
volumes:
- .:/app
- public-data:/app/public
- tmp-data:/app/tmp
- log-data:/app/log
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: XXX
MYSQL_DATABASE: XXX
ports:
- "3306:3306"
web:
build:
context: containers/nginx
volumes:
- public-data:/app/public
- tmp-data:/app/tmp
ports:
- 80:80
depends_on:
- app
volumes:
public-data:
tmp-data:
log-data:
db-data:
docker-composeコマンドを使ってbuildしてアクセス!
ここまで準備が整えば、あとはbuildするだけで環境の作成ができます。便利なのは、このファイル群を使えば同じインフラが一発で再現ができるようになった点ですね〜本当にいい時代だ。。。(しみじみ)
# コンテナを起動する
$ docker-compose build # コンテナをビルド
$ docker-compose up -d # コンテナの一斉起動
# railsの設定
$ docker-compose run --rm app rails db:create
$ docker-compose run --rm app rails db:migrate
ここまでするとnginx経由でアクセスができるようなりました!
ここで学んだこと
頭では理解していたつもりでしたが、もともと普通に構築したアプリをdocker化することでその良さをより知ることができたと思います!
それまでミドルウェアのインストールから設定からまでやっていた環境構築が数回のコマンドで再現できるのは感動的😂😂😂
今後はガシガシコンテナを使って色々と構築していき、理解を深めていきたいと思います!!
🌥AWS編
コンテナ化までできたので、デプロイそのもののハードルはほぼなくなりました。ここからは、本丸に挑戦・・・!
実施した内容
- VPCの作成
- RDSインスタンスの構築と接続設定
- EC2インスタンスの作成
- ALBの作成
- ドメインの取得
- ACMによる証明書の作成
- HTTPS化
RDSインスタンスの構築と接続設定
RDSは、DBエンジンを提供するサービスでDBサーバーとして利用することができます。こちらの生成は正直そこまで難しいことはありませんが、RailsアプリからこちらのDBに接続する設定を直接書き出してしまうのは危険なため、credentialを使って隠蔽する設定を行いました。
# credentialsの設定
$ docker-compose run -e EDITOR="vim" app rails credentials:edit
# credentialsの中身
# ここに書いた内容は外から見ることはできません
rds:
host: RDSのエンドポイント
database: RDSの「データベースの名前」
username: RDSの「マスターユーザの名前」
password: RDSの「マスターパスワード」
- config/database.yml
production:
<<: *default
host: <%= Rails.application.credentials.rds[:host] %>
database: <%= Rails.application.credentials.rds[:database] %>
username: <%= Rails.application.credentials.rds[:username] %>
password: <%= Rails.application.credentials.rds[:password] %>
こうすることで、本番環境の接続DBをRDSに設定することができました。
EC2インスタンスの作成
EC2インスタンスはssh接続できるように設定し、コンテナを動かすためにdockerやdocker-composeのインストールを行いました。
その後、🐳docker編で作成したアプリのgithubからリポジトリごとcloneしてきます。また、githubには存在しないmaster.key
を個別にconfigファイルにコピーしていきます。これをしないと、先ほどcredentialsに設定した内容を参照できないのでご注意を。
$ scp -i ~/.ssh/myapp.pem ~/myapp/config/master.key
ここまできたらdockerを起動してアプリを起動・・・!
$ docker-compose build
$ docker-compose run app rails db:create
$ docker-compose run app rails db:migrate
$ docker-compose run app rails assets:precompile
# nginxとpumaのソケット通信
$ mkdir tmp/sockets
$ touch tmp/sockets/puma.sock
# コンテナ起動
$ docker-compose up
IPアドレス経由ですが、Webアプリケーションにアクセスができるようになりました!!!
HTTPS化
最後に、EC2+RDSで構成されたアプリにALB経由で接続するようにします。また、ACMで証明書を作成してALBに設定することで、**外部→ALBの通信をHTTPS化(暗号化)**します。※ALBとnginx間は同一ネットワーク内なのでHTTP通信になります。
これにより、特定のドメインでHTTPS化した状態でWebアプリにアクセスできるようになりましたーーー!!!
ここで学んだこと
今回、ほぼ無料枠のみでWebアプリケーションをSSL化してインターネット上に公開することができました!!
インスタンスの生成やロードバランサーがこんなにサクッとできるのはやはりすごいですね。今回は1台構成ですが、冗長構成なども容易にできそうな実感を得られました。
また、デプロイは単純にEC2上にリポジトリをコピーしただけだったので、今後はCIできるようにしたり、Githubと連携させたり、なかなかコストはかかりそうですが色々やりたいことも見えてきたので、他のサービスの利点を知るためにも継続的に触っていきたいと思います。
まとめ
目的だった自分の力でWEBサービスをデプロイする経験することができ、知らなかったサービスやインフラの基礎的な部分を効率よく学ぶことができたのはGOODでした!
ハンズオン形式で触りながら学ぶことで、技術の恩恵をより実感することができました。一度触ることで、学びたいサービスや領域が広がったのもいい収穫だったと思います。まだまだいろんなサービスがあるので、どんどん触れてみてITで解決できることの幅を増やしていきたいと思います!
まだまだ勉強不足で毎日学ぶことの連続ですが、着実に力をつけていきたいと思います!!
参考にさせていただいた記事
これを実施するために下記の記事を参考にさせていただきました。
docker-compose(公式)
知識0から、AWSのEC2でウェブサーバーを構築するまで
丁寧すぎるDocker-composeによるrails5 + MySQL on Dockerの環境構築(Docker for Mac)
Docker導入のための、コンテナの利点を解説した説得資料
Nginx + Rails (Puma) on Docker のいくつかの実用パターン
無料!かつ最短?で Ruby on Rails on Docker on AWS のアプリを公開するぞ。
お知らせ
エイチームグループでは一緒に活躍してくれる優秀な人材を募集中です。
興味のある方はぜひともエイチームグループ採用ページよりご応募ください。
WEBエンジニア詳細ページよりお問い合わせ下さい。
明日
明日は@2boさんの記事です!
どんな内容か楽しみです、それではお楽しみに〜〜