READYFOR Tech Blog

READYFOR のエンジニアブログ

ecspressoでRailsアプリ(マストドン)をデプロイする

こんにちは。バックエンドエンジニアの安本です。

弊社も、新しいサービスはPRODUCTIONでECSが動いております。
現在は、既存の動いているサービスのECS化移行に向け取り組んでいますが
いろいろ考えることが多く、各社の記事を参考に四苦八苦しているところです。

ECS化検証の一環として、ecspressoに触れたので、マストドンをデプロイしたコードを共有します。

ecspressoとは

f:id:takaheraw:20210530072409p:plain

やったこと

サンプルコード

Railsとsidekiqを別Serviceで起動させる

f:id:takaheraw:20210530072810p:plain

デプロイフロー

f:id:takaheraw:20210530072858p:plain

準備

関連リソース構築

  • terraform。Service、Taskは管理していない。
$ cd terraform
$ terraform plan
$ terraform apply

ECRにマストドンimageをpush

ひとまずcloud9でbuildしてpushしておく。

$ git clone https://github.com/tootsuite/mastodon.git
$ cd mastodon
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 048225877211.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker build -t mastodon .
$ docker tag mastodon:latest 048225877211.dkr.ecr.ap-northeast-1.amazonaws.com/mastodon:latest
$ docker push 048225877211.dkr.ecr.ap-northeast-1.amazonaws.com/mastodon:latest

タスクの作成

f:id:takaheraw:20210602101102p:plain

サービスの作成

f:id:takaheraw:20210602100758p:plain

ログの確認

  • migrateは実行していないので、DBエラー。(それ以外のエラーは出ていなさそうなことを確認)

f:id:takaheraw:20210602101152p:plain

ecspresso

既存サービスの取り込み

  • 先程、作成したタスク、サービスを取り込む
$ ecspresso init --region ap-northeast-1 --cluster cluster-mastodon --service service-mastodon-rails --config rails.yaml
2021/06/01 17:35:35 service-mastodon-rails/cluster-mastodon save service definition to ecs-service-def.json
2021/06/01 17:35:35 service-mastodon-rails/cluster-mastodon save task definition to ecs-task-def.json
2021/06/01 17:35:35 service-mastodon-rails/cluster-mastodon save config to rails.yaml
  • わかりやすく、ファイル名を整理する
$ ls ecspresso
rails-service-def.json
rails-task-def.json
rails.yaml

db:create; db:migrate

  • runコマンドの--overridesオプションを用いてdb:create db:migrateをする
$ ecspresso --config rails.yaml run --overrides '{"containerOverrides": [{"name":"web", "command": ["rails","db:create"]}]}'
2021/06/01 17:44:59 service-mastodon-rails/cluster-mastodon Running task
Service: service-mastodon-rails
Cluster: cluster-mastodon
TaskDefinition: task-mastodon-rails:13
Deployments:
   PRIMARY task-mastodon-rails:13 desired:1 pending:1 running:0
Events:
2021/06/01 17:45:00 service-mastodon-rails/cluster-mastodon Registering a new task definition...
2021/06/01 17:45:00 service-mastodon-rails/cluster-mastodon Task definition is registered task-mastodon-rails:14
2021/06/01 17:45:00 service-mastodon-rails/cluster-mastodon Running task2021/06/01 17:45:57 Database 'mastodon' already exists
2021/06/01 17:46:23 service-mastodon-rails/cluster-mastodon Run task completed!
$ ecspresso --config rails.yaml run --overrides '{"containerOverrides": [{"name":"web", "command": ["rails","db:migrate"]}]}'
2021/06/01 17:51:06 service-mastodon-rails/cluster-mastodon Running task
Service: service-mastodon-rails
Cluster: cluster-mastodon
TaskDefinition: task-mastodon-rails:13
Deployments:
   PRIMARY task-mastodon-rails:13 desired:1 pending:1 running:0
Events:
2021/06/01 17:51:10 service-mastodon-rails/cluster-mastodon Registering a new task definition...
2021/06/01 17:51:10 service-mastodon-rails/cluster-mastodon Task definition is registered task-mastodon-rails:15
2021/06/01 17:52:41 service-mastodon-rails/cluster-mastodon Run task completed!

sidekiq

  • Railsの手順と同様に、AWS Webコンソールでタスク、サービスをポチポチ作成し、ecspressoで設定ファイルを取り込む。
$ ecspresso init --region ap-northeast-1 --cluster cluster-mastodon --service service-mastodon-sidekiq --config sidekiq.yaml
2021/06/01 21:47:21 service-mastodon-sidekiq/cluster-mastodon save service definition to ecs-service-def.json
2021/06/01 21:47:21 service-mastodon-sidekiq/cluster-mastodon save task definition to ecs-task-def.json
2021/06/01 21:47:21 service-mastodon-sidekiq/cluster-mastodon save config to sidekiq.yaml
  • わかりやすく、ファイル名を整理する
$ ls ecspresso
sidekiq-service-def.json
sidekiq-task-def.json
sidekiq.yaml

Github ActionsでDeploy

Workflow

name: Deploy to Amazon ECS

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      IMAGE_TAG: latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Checkout
        uses: actions/checkout@v2
        with:
          repository: yasumotty/mastodon
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          path: mastodon
          ref: feature/ecs_deploy

      - 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: ap-northeast-1

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build, tag, and push app image to Amazon ECR
        id: build
        env:
          DOCKER_BUILDKIT: 1
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: mastodon
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build \
            --cache-from=$ECR_REGISTRY/$ECR_REPOSITORY:latest --build-arg BUILDKIT_INLINE_CACHE=1 \
            -t mastodon ./mastodon/
          docker tag mastodon:latest $ECR_REGISTRY/$ECR_REPOSITORY:latest
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest

      - uses: kayac/ecspresso@v1
        with:
          version: v1.5.4

      - name: db:migrate
        run: |
          ecspresso run --config ecspresso/rails.yaml --overrides '{"containerOverrides": [{"name":"web", "command": ["rails","db:migrate"]}]}' --latest-task-definition

      - name: deploy rails
        run: |
          ecspresso deploy --config ecspresso/rails.yaml --latest-task-definition

      - name: deploy sidekiq
        run: |
          ecspresso deploy --config ecspresso/sidekiq.yaml --latest-task-definition

動作確認

  • Topページが見れた🎉

f:id:takaheraw:20210602101651p:plain

Fargateコンテナに入りたい

enableExecuteCommandtrue にする

  • enableExecuteCommandtrue にする必要がるので、serviceをdeleteして、createする。
$ ecspresso --config ecspresso/sidekiq.yaml delete
$ git diff ecspresso/sidekiq-service-def.json
-  "enableExecuteCommand": false,
+  "enableExecuteCommand": true,
$ ecspresso --config ecspresso/sidekiq.yaml create

コンテナに入る🎉🎉🎉

$ ecspresso exec --config ecspresso/sidekiq.yaml --command bash
4e9602e2c3704a1d8d5f2603bd499dd8    task-mastodon-sidekiq:9     RUNNING RUNNING 2021-06-01T22:37:57+09:00   service:service-mastodon-sidekiq    FARGATE
c9f7f781f4684de88273871047730a88    task-mastodon-sidekiq:9     RUNNING RUNNING 2021-06-01T22:37:57+09:00   service:service-mastodon-sidekiq    FARGATE
Enter task ID: 4e9602e2c3704a1d8d5f2603bd499dd8
task ID=4e9602e2c3704a1d8d5f2603bd499dd8

Starting session with SessionId: ecs-execute-command-07d68c8447477063f

root@ip-10-0-88-67:/opt/mastodon# ./bin/rails c
Chewy console strategy is `urgent`
Loading production environment (Rails 6.1.3.1)
irb(main):001:0> User.all
=> #<ActiveRecord::Relation []>

まとめ

  • 抽象化されているので、アプリケーション寄りのエンジニアとしてはとてもわかりやすかった
  • 周辺リソース管理と切り離されているので、アプリケーション側は service / task の運用のみに集中できる
  • 設定ファイル群が管理しやすい
  • 新機能の追従がされている
  • コンテナに入れるの感動する
  • 本題とは関係ないが、マストドンについて詳しくなった

さいごに

SRE絶賛募集しております !よろしくおねがいします!

www.wantedly.com