nocobaseをAWS ECSで動かす方法

2024.04.09

困っていたこと

NocoBaseはdockerが推奨環境になっています。

docker-composeのファイルが公式のレポジトリに含まれていて、ローカルPCであればdocker-composeのコマンドを使って簡単に起動できます。

これをマネージド型のコンテナサービス(今回はAWS ECS)で動かしたい場合はどうすればいいのでしょうか.

どう対応すればいいの?

タスク定義

ECSのタスク定義は、コンテナアプリケーションの実行方法を記述した設定ファイルで、ECSクラスターにデプロイされます。

クラスターは、タスク定義に基づいてコンテナをプロビジョニングし、実行します。タスク定義を更新すると、新しい設定でタスクが実行されます。

タスク定義を適切に設定することで、コンテナアプリケーションのリソース、ネットワーク、ログ、シークレットなどを一元的に管理でき、アプリケーションの実行環境を柔軟に制御できます。

今回はこれをECSの管理コンソール上から作成していきます。

参考) nocobaseのdocker-compose.yml mysql版

タスク定義の画面に移動し、

タスク定義の設定

タスク定義ファミリー名を入力します

インフラストラクチャの要件

  • 起動タイプ
    • AWS Fargateにします
  • オペレーティングシステム/アーキテクチャ
    • 選択できるものから選びます(Linux/X86など)
  • ネットワークモード
    • awsvpc を選択します
    • Fargate でホストされるタスクには [awsvpc] ネットワークモードが必要
  • タスクサイズ
    • CPU, メモリ量を選択します。今回はデフォルトのものにします。
  • タスク実行ロール
    • 新しいタスク実行ロールを作成する を選択します(初めての場合)

アプリケーションコンテナ

docker-compose.ymlの services セクションの各サービスをECSタスク定義のコンテナ項目にします。

今回はDBをRDSとする想定ですので、app部分の設定を行っていきます。

  • コンテナの詳細
    • コンテナ名とイメージ URI(nocobase/nocobase:latest) を必須にして入力します
  • ポートマッピング
    • docker-composeで13000となっているので、同じポート番号にします。
    • プロトコルはtcp,アプリケーションプロトコルはhttpです。ポート名を空欄のままにするとデフォルトが割り当てられます。
  • リソース割り当て制限
    • コンテナレベルの CPU、GPU、メモリの制限をする場合は指定していきます
    • CPU 値は vCPU の数として指定されます。メモリ値は GB 単位で指定します

docker-compose.ymlのenvironmentに書かれている環境変数を設定し、値を自身で決めたものに変えます

mysql版に設定されている値は以下

environment:
      - APP_KEY=your-secret-key # Replace it with your own app key
      - DB_DIALECT=mysql
      - DB_HOST=mysql
      - DB_DATABASE=nocobase
      - DB_USER=root
      - DB_PASSWORD=nocobase
      - DB_TIMEZONE=+08:00

DBの値は、後述する用意したDBコンテナの値に変更します。

DB_HOSTですが、今回のように同一のタスクで起動している場合、127.0.0.1 に設定しておきます。

ログ記録

AWS Fargate で実行されるタスクには、ログ収集を使用することをお勧めします となっています。

コンテナのログをルーティングする先を決定します。

デフォルトではcloudwatchの設定になっていますので、このまま使えます。

ボリューム

docker-compose.ymlのvolumesに書かれている内容を設定します。

volumes:
      - ./storage:/app/nocobase/storage

量は最低で20GBで、カスタムする場合は21GB以上の設定にできます。

ボリューム名をstorage、あとはデフォルトのままにします。

コンテナマウントポイントでっは、コンテナパスを/app/nocobase/storageにします。

DBコンテナ

  • コンテナの詳細
    • コンテナ名とイメージ URI(mysql:latest) を必須にして入力します

docker-compose.ymlのenvironmentに書かれている環境変数を設定し、値を自身で決めたものに変えます

mysql版に設定されている値は以下

environment:
      MYSQL_DATABASE: nocobase
      MYSQL_USER: nocobase
      MYSQL_PASSWORD: nocobase
      MYSQL_ROOT_PASSWORD: nocobase

ボリュームの追加も行います

docker-compose.ymlのvolumesに書かれている内容を設定します。

volumes:
      - ./storage/db/mysql:/var/lib/mysql

ボリューム名をstorage-db-mysql、あとはデフォルトのままにします。

コンテナマウントポイントでっは、コンテナパスを/var/lib/mysqlにします。


最低限の設定が終わったので、この状態で作成します。

タスクを起動する

最終的にはALBを経由してコンテナにアクセスしたいのですが、今回はタスクを起動してパブリック IP経由で確認します

新しいタスクの実行を押して設定していきます。

環境

起動タイプをFARGATEにして作成します。

デプロイ設定

  • アプリケーションタイプ
    • タスクを選択します
  • タスク定義
    • 作成したタスク定義を選択します

ネットワーキング

タスク定義で awsvpc ネットワークモードを使用する場合、またはロードバランサーを使用するようにサービスを設定する場合は、Amazon Virtual Private Cloud (VPC) が必要です

ブラウザからアクセスするので、VPCやセキュリティグループはそれに合わせたものにしておきます。


最低限の設定が終わったので、この状態で作成します。

設定した2つのコンテナが立ち上がっていると成功です。

アプリケーションコンテナのパブリックIP:13000 にアクセスし、ログイン画面が表示されればECSでの起動は成功です

初期ユーザー名とパスワードでログインしてみましょう。

readonlyRootFilesystem の場合

コンテナ内のルートファイルシステムが読み取り専用にするreadonlyRootFilesystem がtrueだと、nocobaseのlatestイメージをそのまま使うと色々な箇所で書き込みエラーが発生し起動エラーになりました。

回避策の一つとして、書き込みに使用している箇所をDockerfileなどから特定し、バインドマウントを行うことで起動するようになりました。

コンテナマウントポイントを追加したパス)

  • /tmp
  • /usr/local/share
  • /etc/nginx/sites-enabled/
  • /var/log/nginx
  • /var/lib/nginx
  • /app/nocobase
  • /app/nocobase/storage
  • /app/my-nocobase-app
  • /run

参考資料