EC2のNodeサーバーと連携するReactクライアントをS3にデプロイしてみる
AWS Summitに参加してからAWS関連でなんかしたいなあと思っていたので、 S3にReactで作ったクライアントを、EC2にNodeのサーバーを置いて、 簡単にアプリをデプロイしてみます:desktop:
以下の準備が整っていることを前提とします。 ・Reactでクライアントアプリを作っており、これと連携しているサーバーサイドも作られている。 ・EC2インスタンスを作成しており、sshでEC2に入れる。 ・作成したEC2のセキュリティグループのインバウンドの設定でhttpによる接続を受け付けられるようにしておく(これは後で設定しても良いですが)。
EC2にNodeで作ったサーバーを置く
まず、
をインストールします。 Nodeサーバーの場合なので、他の言語で書いていたりしたらそれに合わせてください。
$ yum update -y $ yum install git -y $ yum install nginx -y $ yum install python3 -y $ pip3 install aws-cli $ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash $ vim ~/.bash_profile $ source ~/.bash_profile $ nvm install --lts $ nvm use --lts $ node -v
.bash_profileには以下を書き込みます。
# .bash_profile # /home/production/のところは個別に設定してください。アプリケーションのディレクトリを置くところとかでいいと思います。 export NVM_DIR="/home/production/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
次にサーバーのソースをクローンしてきます。 あと、nodeのプロセスを永続化するためにpm2を導入します。 pm2参考 => https://qiita.com/ikemura23/items/b3481393d4edca2d5188
$ git clone node-server $ npm install -g pm2 $ cd node-server $ pm2 start index.js --name node-server-on-ec2
EC2内で動いているサーバーにアクセスできるように、 外からやってきたhttpのリクエストをサーバーに転送してあげます。
ここで作ったindex.jsの設定ではlocalhost:3000をlistenしているので、 nginxでプロキシーの設定をして80番ポートにやってくるアクセスを3000番に転送します(localtion /を設定)。 nginxの設定参考 => https://qiita.com/morrr/items/7c97f0d2e46f7a8ec967 (プロキシーさせるためにもEC2へのhttpの接続をセキュリティグループで有効にしておくこと)
$ vim /etc/nginx/nginx.conf
# nginx.conf server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_pass http://localhost:3000; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
これでec2のパブリックIPに接続すると、EC2内で動いているnodeサーバーにアクセスできます。 エラーが出る場合、pm2やnginxの再起動などを行ってください。 セキュリティグループの設定も忘れずに:information_desk_person:
とりあえずここまででサーバー側のアプリをEC2に設置して、パブリックIPでアクセスできるようになります。
S3にReactで作ったクライアントを置く
1. バケット作成
S3でバケットを作成してください。 バケット名とリージョンを設定し、あとは基本的にデフォルトで良いです。 が、ブロックパブリックアクセスはオフにしておきます。
2. Static website hostingの設定
バケット作成後、Static website hostingを有効化するために、 Reactでbuildしたindex.htmlをインデックスドキュメントとして設定します。
3. バケットポリシーの設定
{ "Version":"2012-10-17", "Statement":[{ "Sid":"PublicReadForGetBucketObjects", "Effect":"Allow", "Principal": "*", "Action":["s3:GetObject"], "Resource":["arn:aws:s3:::example-bucket/*"] }] }
静的ウェブサイトをセットアップする => https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/HostingWebsiteOnS3Setup.html
4. IAMでアクセス権限を持ったユーザーを作成する
IAMに入ってサイドペインからユーザーを選択、ユーザーを追加ボタンでユーザーを作成します。
ユーザー名を設定し、プログラムによるアクセスにチェックを入れます。
次に、既存のポリシーを直接アタッチでs3のアクセス権を選択し、これを付与します。
ここではAmazonS3FullAccessを選びますが、セキュリティなども考慮すればReadOnlyAccessの方が良かったり、時と場合によっては何が良いかが別れると思うので、その都度使い分けてください。
後の項目は基本デフォルトで良いです。 ユーザーを作成すると、AccessKeyIdとSecretAccessKeyの情報が記載されたCSVができると思うので、 その中にあるそれぞれの文字列を次に利用していきます。
5. EC2内でaws configureを行う
先ほど取得したIAMユーザーのAccessKeyIdとSecretAccessKeyをEC2にインストールしたawsコマンドで有効化します。
$ aws configure AWS Access Key ID ************** AWS Secret Access Key ************** Default region name ap-northeast-1 Default output format json
AccessKeyId, SecretAccessKey, region, output formatの入力を促されるので、それぞれ入力します。 output formatはjsonで良いです。
6. ReactでbuildしたファイルをS3にアップロード
ここまでできたらあとはbuildしたファイルたちをS3にアップロードするだけです。 Reactプロジェクトの中に入って、以下のコマンドを打ちます。 バケット名は自分ので埋めてください。
$ aws s3 sync ./build s3://{バケット名} --acl public-read
.DS_StoreとかがS3に入るのが嫌なら、以下のオプションを追加して省くこともできます。
--exclude '*.DS_Store'
また、今回はEC2でIAMユーザーを一つだけ設定したかったので、aws configureを使いましたが、 複数のIAMユーザーが必要なら、~/.awsの中にあるconfigファイルおよびcredentialファイルにそれぞれの情報を書き込みます。
[default]となっているプロファイル(IAMユーザー)はaws configureで設定したものと同じになるようです。 [profile_name]としてプロファイルを複数作成していけます。
# ~/.aws/credentials [default] aws_access_key_id = XXXXXXXXXX aws_secret_access_key = XXXXXXXXXX [test] aws_access_key_id = XXXXXXXXXX aws_secret_access_key = XXXXXXXXXX
特定のIAMユーザーの権限でs3へアップロードを行いたい場合などは以下のようにコマンドを実行します。
$ aws s3 sync ./build s3://{バケット名} --acl public-read --profile {profile_name}
以上でデプロイが完了ですので、以下のようなURLでアプリケーションに接続できます。
http://{s3バケット名}.s3-website-ap-northeast-1.amazonaws.com
自分の作ったアプリが表示されれば成功です! EC2に置いてあるサーバーとも連携が取れているか確認してみてください。