どうもこんにちは。
AWS Elastic Beanstalk を使ってアプリケーションをデプロイしているときに、.ebextensions
ディレクトリ内の設定ファイルで commands
と container_commands
の違いによってデプロイに失敗したので、備忘録として残しておきます。
commands
でエラーが発生
Elastic Beanstalk のデプロイでエラーが発生しました。commands
セクションに記述していた pecl install
コマンドがうまく実行されていないようでした。
当初の設定は以下の通りです。
packages:
yum:
git: []
libyaml-devel: []
ImageMagick: []
ImageMagick-devel: []
commands:
01-wget:
command: "wget -O /tmp/ffmpeg.tar.xz https://johnvansickle.com/ffmpeg/old-releases/ffmpeg-6.0-amd64-static.tar.xz"
02-mkdir:
command: "if [ ! -d /opt/ffmpeg ] ; then mkdir -p /opt/ffmpeg; fi"
03-tar:
command: "tar xvf /tmp/ffmpeg.tar.xz -C /opt/ffmpeg"
04-ln:
command: "if [[ ! -f /usr/bin/ffmpeg ]] ; then ln -sf /opt/ffmpeg/ffmpeg-6.0-amd64-static/ffmpeg /usr/bin/ffmpeg; fi"
05-ln:
command: "if [[ ! -f /usr/bin/ffprobe ]] ; then ln -sf /opt/ffmpeg/ffmpeg-6.0-amd64-static/ffprobe /usr/bin/ffprobe; fi"
06-pecl:
command: "if [ `pecl list | grep imagick` ] ; then pecl install -f imagick; fi"
container_commands
に変更したら通った!
commands
セクションを container_commands
に変更したところ、無事にデプロイが成功しました。
変更後の設定はこちらです。
packages:
yum:
git: []
libyaml-devel: []
ImageMagick: []
ImageMagick-devel: []
container_commands: # ここが変わった!
01-wget:
command: "wget -O /tmp/ffmpeg.tar.xz https://johnvansickle.com/ffmpeg/old-releases/ffmpeg-6.0-amd64-static.tar.xz"
02-mkdir:
command: "if [ ! -d /opt/ffmpeg ] ; then mkdir -p /opt/ffmpeg; fi"
03-tar:
command: "tar xvf /tmp/ffmpeg.tar.xz -C /opt/ffmpeg"
04-ln:
command: "if [[ ! -f /usr/bin/ffmpeg ]] ; then ln -sf /opt/ffmpeg/ffmpeg-6.0-amd64-static/ffmpeg /usr/bin/ffmpeg; fi"
05-ln:
command: "if [[ ! -f /usr/bin/ffprobe ]] ; then ln -sf /opt/ffmpeg/ffmpeg-6.0-amd64-static/ffprobe /usr/bin/ffprobe; fi"
06-pecl:
command: "if [ `pecl list | grep imagick` ] ; then pecl install -f imagick; fi"
なぜ commands
ではダメで container_commands
ならOKだったのか?
この現象の鍵は、Elastic Beanstalk のデプロイプロセスにおける commands
と container_commands
の実行タイミングの違いにありました。
commands
と container_commands
の違いを理解する
AWS Elastic Beanstalk のドキュメントによると、これらのコマンドはデプロイの異なるフェーズで実行されます。
commands
- 実行タイミング: アプリケーションとウェブサーバーがセットアップされる前、かつアプリケーションコードが展開される前に実行されます。デプロイプロセスの非常に初期段階です。
-
用途: OSレベルのパッケージインストール (
yum
,apt-get
など)、OS設定の変更、ユーザーの作成といった、アプリケーションコードに依存しない低レベルなシステム設定に適しています。 -
注意点: アプリケーションのコードがまだ展開されていないため、
commands
内でアプリケーションのソースコードや、アプリケーションが依存するディレクトリ(例:/var/app/current
)にアクセスしようとすると失敗します。また、環境変数も利用できない場合があります。
container_commands
-
実行タイミング: アプリケーションとウェブサーバーがセットアップされ、アプリケーションバージョンアーカイブが抽出された後、ただしアプリケーションバージョンがデプロイされる前に実行されます。つまり、アプリケーションコードが
/var/app/staging
(またはcurrent
) に展開された後に実行されます。 -
用途: アプリケーションコードに依存する操作、例えばデータベースマイグレーションの実行、アプリケーションのキャッシュディレクトリの作成、PHPの
pecl install
、Node.js のnpm install
、Python のpip install
といった、アプリケーションのセットアップに必要なコマンドに適しています。 - 注意点: アプリケーションのソースコードにアクセスできます。環境変数も利用できます。
まとめ
Elastic Beanstalk の .ebextensions
でコマンドを実行する際は、以下の点を覚えておきましょう。
-
commands
: システムの初期設定やOSレベルのパッケージインストールなど、アプリケーション環境が整う前の処理に使う。 -
container_commands
: アプリケーションコードのデプロイ後に実行されるため、アプリケーション固有のセットアップや依存関係のインストールに適している。
特に、特定の言語のパッケージマネージャ(PHPのpecl
、Node.jsのnpm
、Pythonのpip
など)を利用する場合は、そのランタイム環境が利用可能になっている必要があるため、container_commands
を使用するのが正しいアプローチです。
もし、.ebextensions
のコマンドでエラーが発生した場合は、そのコマンドが実行されるべきタイミングと、commands
または container_commands
のどちらがそのタイミングに合致しているかを改めて確認してみてください。