Elastic BeanstalkにRailsアプリケーションをデプロイした
Elastic BeanstalkでRailsアプリケーションを動かしたので、ハマったところ等をまとめました。
用途は少し限定されますが、負荷も大きくないような簡単なアプリケーションを動かすには良い選択肢になるかなと思いました。
特徴/メリット
- Dockerfileがあるアプリケーションを簡単に構築できる(※ 他の言語もサポートされてる)
- Nginxなどのwebサーバーの設定がほとんど不要なので、アプリケーションさえあれば動かせる
- デプロイフローの構築も割と簡単
デメリット
- 設定等にハマると、普通に構築した方が早いと思った
- ログがあまり充実してなさそうなので、要確認
- ガッツリ本番でリクエストを捌くレベルでは、心もとなく感じた
環境
インフラ構成
デプロイ
GitHub Actionsを利用しました。
- Github ActionsでDockerのビルド
- imageをECRにpush
- Elastic Beastalk上で動かすDockerfile等の作成
- 作成したDockerfileをElastic Beastalkへデプロイ
※ 事前にAWSでデプロイユーザを作成し、そのクレデンシャルをGitHubのsecretsで設定しています。
name: AWS Elastic Beanstalk Deploy on: push: branches: - production env: AWS_REGION: ap-northeast-1 AWS_ECR_REPO_NAME: application-name jobs: delivery: runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout the repository uses: actions/checkout@v1 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }} - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Build a docker image, and push to Amazon ECR env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} run: | docker build -t $ECR_REGISTRY/$AWS_ECR_REPO_NAME:${{ github.sha }} . docker push $ECR_REGISTRY/$AWS_ECR_REPO_NAME:${{ github.sha }} - name: Prepare for Beanstalk deployment env: DOCKER_IMAGE_URL: ${{ steps.login-ecr.outputs.registry }}/${{ env.AWS_ECR_REPO_NAME }}:${{ github.sha }} run: | cd elastic_beanstalk && ./build_dockerfile.sh && zip -r ./app-${{ github.sha }}.zip ./ - name: Deploy web to EB uses: einaregilsson/beanstalk-deploy@v14 with: aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} application_name: beanstalk-application environment_name: app-env wait_for_environment_recovery: 90 version_label: app-${{ github.sha }} region: ${{ env.AWS_REGION }} deployment_package: elastic_beanstalk/app-${{ github.sha }}.zip
Prepare for Beanstalk deployment
のステップでは、以下のようにDockerfileのimageのURLを書き込んだりしています。
FROM {{DOCKER_IMAGE_URL}} ENV RAILS_ENV=production EXPOSE 3000 ENTRYPOINT [""] CMD ["/usr/bin/docker_init.sh"]
インフラ構築
ドメイン
こちらで無料で取得できました。
Elastic Beanstalk周りでハマったところ
Nginxの設定
AWSの公式ドキュメントや、その他の記事を見ていると .ebextentions
配下に設定ファイルを置けば読み込まれると言った情報が見られましたが、以下のように .platform
配下に置く必要がありました。 .ebextentions
でも実行自体はされるみたいでしたが、Elastic Beanstalkのライフサイクルの都合で、更に上書きされてしまうようでした。
10MB以上のファイルをアップロードすると、413エラーが返ってくる状態だったため、 client_max_body_size
を設定しました。
$ tree -a elastic_beanstalk elastic_beanstalk ├── .platform │ └── nginx │ └── conf.d │ └── client-max-body-size.conf └── Dockerfile $ cat elastic_beanstalk/.platform/nginx/conf.d/client-max-body-size.conf client_max_body_size 30m;
他にも、デプロイ時に実行するフックなどを設定できます。
Sidekiq
今回の用途では、そこまで高負荷でもなく、Sidekiq用にコンテナの数を増やすほどでもなかったので、少し力技で同一のコンテナ上で動かしました。
docker_init.sh
#!/bin/sh rm -f tmp/pids/server.pid && \ rails db:migrate && \ rails assets:precompile && \ bundle exec sidekiq & \ rails server -b 0.0.0.0