EC2にdocker-composeでRailsをデプロイする (CI/CDまでの道⑥)
はじめに
前回はRailsをProductionモードで起動しました。今回はEC2
にDockerをインストールして、そのうえでProductionモードで起動して、独自のドメインで実際にアクセスできるところまでチャレンジしていきます。
作成に利用するリポジトリはこちら
注意
このハンズオンでは以下の書籍を用います。
AWSではじめるインフラ構築入門 安全で堅牢な本番環境のつくり方
このハンズオンですべてインフラ環境構築の手順を画像付きで載せてもよかったのですが、ほぼこの本通りになってしまい、本を模写することになってしまい著作権に触れてしまう可能性があるためほぼ書籍通りに環境構築をおこないながら進めていきます。一部変更箇所があるのでそこだけ説明を別途入れたいと思います。EC2にドメインでアクセスできるような環境があればインフラ構築は飛ばしていただいて大丈夫です。
本ハンズオンの構成は以下となります。
CI/CDまでの道シリーズ
- Rails6+MySQLのDocker環境構築 (CI/CDまでの道①)
- DockerにWebpacker環境構築(jquery, Bootstrap5, Vue) (CI/CDまでの道②)
- Rails(Docker)に必要なGemを追加する (CI/CDまでの道③)
- Rails(Docker)にNginxを導入する (CI/CDまでの道④)
- Rails(Docker)をProductionモードで起動してみる (CI/CDまでの道⑤)
- EC2にdocker-composeでRailsをデプロイする (CI/CDまでの道⑥)
環境
- WSL2 (Ubuntu20.04)
- Docker 20.10.9
- docker-compose 1.29.1
- Git 2.25.1
- VSCode
AWSインフラ環境の構築
上で説明した通り基本的には書籍通りにインフラ環境を行います。一部だけ変更がありますのでそこは説明を行います。
第1章 AWSをはじめよう
今回は関係ないのでスキップで大丈夫です。
第2章 AWSアカウントを作ろう
書籍通りに作業を行ってください
第3章 安全に作業するための準備
関係ないのでスキップで大丈夫です。
第4章 仮想ネットワークを作ろう
書籍通りに作業を行ってください
第5章 踏み台サーバーを用意しよう
書籍通りに作業を行ってください
第6章 Webサーバーを用意しよう
書籍通りに作業を行ってください
第7章 ロードバランサーを用意しよう
ここは一部修正を行います。
書籍のハンズオンではNginx
のポートを3000番
で開いているためロードバランサーはEC2
の3000番をみにいくように設定していますが、私たちの作成している環境はNginxが80番ポート
で受け付けているのでターゲットグループ
作成で3000
と設定しているところを80
に変更します。
具体的な修正箇所は以下です。
ここの80
は変更せずターゲットグループを作成します。
このように設定をします。
ターゲットの登録でweb01
とweb02
を選択してinclude as pending below
でしっかりと登録してからターゲット登録するのを忘れないようにしてください。
あとは書籍通りですが7.3.1
の動作確認で
$ python -m SimpleHTTPServer 3000
をしていますが、これは今回80番ポートにしたので動作確認はできません。 飛ばして大丈夫です。
その代わりに実際にデプロイして確認します。
第8章 データベースサーバーを用意しよう
基本的には書籍通りです。
しかし、データベースのパスワードに関してはこのハンズオンではpassword
にしたいと思います。
あとで.env
にこのパスワードを設定しますが、password
としましたので各自読み替えて設定してください。
9章以降について
これ以降で行う必要があるのは10章のみ
となりますが、これはデプロイ後に行いますので9章まで行ったらデプロイにチャレンジします。
9, 11, 12, 13, 14, 15章はこのハンズオンには不要です。
EC2にデプロイする
まずはWebサーバー(web01)にssh接続します。
$ ssh web01
ここでWSL2でなぜか多段階接続ができず、PowershellでC:\Users\ユーザー名\.ssh
にconfig
とpem
をおいて接続(ssh web01)を行ったあとにWSL2で多段階接続するといけました。
Windows環境との競合などが発生しているようです。
以下の記事を参考にEC2にDocker
、docker-compose
、Git
をインストールしていきます。
【AWS】EC2にDockerとDocker Composeをインストール
AWS EC2 AmazonLinux2 Gitをインストールする
$ sudo amazon-linux-extras install -y docker
$ sudo systemctl start docker
$ VER=v2.2.3
$ sudo curl -L https://github.com/docker/compose/releases/download/${VER}/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
$ sudo yum install git
次にGitから作成したDocker環境をクローンしてきます。
$ git clone https://github.com/jinwatanabe/CICD_Road
VSCodeのリモートSSHを利用してweb01
のCICD_Road/chapter05
にはいります。
※ web01のCI_CD_Road_4となっていますが、皆様の画面ではCICD_Roadとなっているかと思います
リモートSSHについては以下を参考に入れてみてください。
VSCode の Remote - SSH 機能を使って EC2 上で開発する
CICD_Road/chapter05
のディレクトリに移動します。
config/credentials.yml.enc
を削除します(ない場合は省略)
前回作成したconfig/credentials.yml.enc
とconfig/master.key
をconfig/
にコピーします。
以下の記事を参考にProductionモードをEC2ように修正していきます。
EC2上でRailsアプリケーションにDockerを導入する(Rails、Nginx、RDS)
まずは.env
の内容を以下に変更します。
DB_USERNAME="admin"
DB_PASSWORD="password"
DB_HOST="RDSのエンドポイント名"
DB_DATABASE="myapp"
RDSのエンドポイント名のところには、書籍のP178で確認したエンドポイントを入れてください。
次にDBのProduction時の設定を変えます。config/database.yml
のproduction
部分を以下に修正します。
(省略)
production:
<<: *default
database: <%= ENV['DB_DATABASE'] %>
adapter: mysql2
encoding: utf8mb4
charset: utf8mb4
collation: utf8mb4_general_ci
host: <%= ENV['DB_HOST'] %>
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
今回はRDS
を利用するのでdocker-compose.production.yml
のDBに関する部分をコメントアウトします。
version: "3.9"
services:
rails:
build: .
container_name: rails
command: bundle exec puma -C config/puma.rb -e production
volumes:
- .:/myapp
- public-data:/myapp/public
- tmp-data:/myapp/tmp
- log-data:/myapp/log
- /myapp/node_modules
env_file:
- .env
# depends_on:
# - db
user: root
# db:
# image: mysql:8.0.27
# container_name: db
# environment:
# TZ: Asia/Tokyo
# MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
# ports:
# - "3306:3306"
# volumes:
# - db:/var/lib/mysql
web:
build:
context: containers/nginx
volumes:
- public-data:/myapp/public
- tmp-data:/myapp/tmp
ports:
- 80:80
depends_on:
- rails
volumes:
# db:
# driver: local
public-data:
tmp-data:
log-data:
次にNginx
の設定をします。containers/nginx/nginx.conf
のserver_name
を変更します。
# プロキシ先の指定
# Nginxが受け取ったリクエストをバックエンドのpumaに送信
upstream myapp {
# ソケット通信したいのでpuma.sockを指定
server unix:///myapp/tmp/sockets/puma.sock;
}
server {
listen 80;
# ドメインもしくはIPを指定
server_name [Web01のプライベートIP]; #修正
(省略)
Web01のプライベートIPをいれます。
※ 注意 Web02の場合はWeb02のプライベートIPをいれます
次にコンテナを起動するための準備としてコンパイル
とDB作成
(Web01とWeb02で共有しているのでWeb01でやる1回でOK)を行います。
またDockerコマンド、docker-composeコマンドはすべてsudo
で実行する必要があります。
$ sudo docker-compose -f docker-compose.production.yml build
$ sudo docker-compose -f docker-compose.production.yml run rails rails assets:precompile RAILS_ENV=production
# DB作成はweb01でのみ
$ sudo docker-compose -f docker-compose.production.yml run rails rails db:create RAILS_ENV=production
# 起動
$ sudo docker-compose -f docker-compose.production.yml up
実際にデプロイが成功しているか踏み台サーバーbastion
から確認します。別のターミナル(Powershellなど)を開きbastion
にssh接続
して確認します。
$ ssh bastion
$ curl [web01のプライベートIP]/test
以下のように出力されていればうまくデプロイができています。
[ec2-user@ip-10-0-0-236 ~]$ curl 10.0.71.6/test
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type'>
<title>Myapp</title>
<meta content='width=device-width,initial-scale=1' name='viewport'>
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="wOB_duwKTFg2RWJThBSxhJyRM0ZhZpiM5StGDa648VnVaTP7VqhFIVGV8rLIa63WDcoO83cA5s22BgtDo96LBA" />
<script src="/packs/js/application-5c597b4d3c61e38cc616.js"></script>
<link rel="stylesheet" media="screen" href="/packs/css/application-8b2e0365.css" />
<script src="/packs/js/main-4c9d47074ceee9ee29cb.js"></script>
</head>
<body>
<h1>Hello World</h1>
<h2>CSSが適応されると色が変わる</h2>
<button class='btn btn-primary' type='button'>Bootstrap適応</button>
こんにちは
/test
がないとproductionモードでは404
エラーになります。(万歳画面はなくなるので)
ここまでできたら、Web02
に関しても同じ手順でコンテナを起動します。nginx.conf
のプライベートIPをWeb02のプライベートIPにして、DB作成
は行わないが違う点です。
ドメインを登録する
ここまでできたら書籍の第10章 独自ドメインとDNSを用意しようを行います。
こちらも書籍通りに行います。
Webサイトを確認する
https://www.自分のドメイン/test
にアクセスしてページが表示され、CSSやJavascriptが適応されていれば成功です。
JavascriptのアラートはChorome
だと最初の1回のみしか(リロードでは)表示されませんので注意してください。Choromeをすべて閉じてから再度開いてください
/test
を忘れるとNginx
のエラー画面になるので注意してください。
おわりに
作成したものはこちらのリポジトリに用意しています。
ひとまずデプロイができるようになりました。
しかしこの状態ではコンテナを差し替えるときに起動までの時間ユーザーに利用できない時間ができたり、手間がかかったりと問題は多いので次はコンテナに適したデプロイにチャレンジしていきたいです。
Discussion