0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DockerImageにCLI実行モードを実装してECSでバッチ運用する

Last updated at Posted at 2025-03-24

ECSで稼働するphp:fpm-alpineベースのPHP/Phalconで構築したアプリケーションイメージを流用して、ECSでバッチ処理をスケジュール実行するためのアーキ。

要件

  • ECSで運用中のアプリケーションのイメージを流用できること。
  • スケジュール実行できること。実行後、exit終了すること。
  • ログはCloudWatchLogに出力すること。

PhalconでCLI実行

CLIエントリポイントとバッチ処理を実装する。
下記のコードスニペットがそのまま使えました。ありとうございます。

CLIモードのスタンドアロン実行

shell
# cliモードで起動
php /path/to/CLIエントリポイント.php \
&& className(→ ClassNameTaskクラス) \
&& action_name(→ actionNameActionメソッド) \
&& param1(→ メソッドの引数1) \
&& param2(→ メソッドの引数2)

Dockerイメージのフレキシブル運用

ENTRYPOINTCMDに応じて サーバー起動 or CLI実行 を切り替えるシェルスクリプトを用意して、docker run イメージ {コマンド上書き}あるいは、ecsのコマンド上書き設定で起動モードをスイッチ出来るようにする。

こんな感じ
image.png

Dockerfile

Dockerfile
...

# エントリポイントスクリプトをコピー
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

# エントリポイントを設定
ENTRYPOINT ["/entrypoint.sh"]

# デフォルトでは FPM を起動
CMD ["fpm"]

entrypoint.sh

entrypoint.sh
#!/bin/sh
set -e  # エラー時に停止

# 引数がない場合、または "fpm" の場合は PHP-FPM を起動
if [ "$1" = "fpm" ] || [ -z "$1" ]; then
    echo "Starting PHP-FPM..."
    exec php-fpm
fi

# "cli" の場合は、引数を `php` に渡して実行(CLIモード)
if [ "$1" = "cli" ]; then
    shift # `cli` を削除
    echo "Running PHP CLI..."
    exec php "$@"
fi

# それ以外のコマンドは直接実行
exec "$@"

実行

shell
# サーバー起動モード
docker run -d イメージ
#=> php-fpm

# CLI実行でワンショット起動
docker run --rm イメージ cli /path/to/cli.php arg1 arg2
#=> php /path/to/cli.php arg1 arg2

# メンテコマンドでワンショット起動
docker run --rm イメージ ls -l
#=> ls -l

ECS

初見はいろいろと問題が出るので、新しいタスクの実行でデバッグしてからスケジュールされたタスクを構築することを推奨。

  • バッチ用のタスク定義を作成して、上記のイメージを指定する。
    • 起動タイプ(Fagate?EC2?)
      クラスタレイヤーの話なのにここで選ぶのかい?と混乱していたら、フォームを想定環境に最適化してくる親切設計であった。
      Amazon ECS 起動タイプ - Amazon Elastic Container Service
    • デバッグ、モニタリングためCloudWatchLogは必ずオンしておく。
  • クラスタ > スケジュールされたタスクでは主にタスク定義cron式および、コンテナの上書き > コマンドの上書きでCMDをCLI起動用に上書きする。
コマンドの上書き
# だめ ひとつのコマンドとして認識される
# cli /path/to/cli.php className action_name
#=> /entrypoint.sh: exec: line X: cli /path/to/cli.php className action_name: not found

# OK カンマでCMD引数としてプロットしてくれる(説明どおり)
cli,/path/to/cli.php,className,action_name
#=> exec php /path/to/cli.php className action_name

こんな感じ
image 2.png

つまずき

ResourceInitializationError

クラスター > タスクの状態
ResourceInitializationError: unable to pull secrets or registry auth: The task cannot pull registry auth from Amazon ECR: There is a connection issue between the task and Amazon ECR. Check your task network configuration. RequestError: send request failed caused by: Post "https://api.ecr.ap-northeast-1.amazonaws.com/": dial tcp 99.77.58.41:443: i/o timeout

イメージのpull → イメージのECRエンドポイントに接続できていない。

タスクのサブネットがプライベートサブネットだったのでNAT/IGWの準備がなくECRに接続できない。パブリックサブネットに設置して通過。

Essential container in task exited

クラスター > タスクの状態
Essential container in task exited

プロセスが終了してexit状態なのでOK。CloudWatchLogで実行結果を確認する。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?