⛳
Dockerfile の ENTRYPOINT で環境変数が展開されない件の対応
もう述べ3回ぐらいハマってるので備忘録として。
結論
ENTRYPOINT に "sh", "-c"
を付けて、実行するコマンドを文字列にまとめる。シェルが環境変数を展開するため。
ENV PORT=8000
ENV HOST=0.0.0.0
COPY server.py server.py
ENTRYPOINT ["sh", "-c", "/app/.venv/bin/uvicorn server:app --host $HOST --port $PORT"]
背景
FastAPI で書いた API サーバを docker イメージにして、アプリケーション側の docker compose でポート番号やホストを適宜変更可能にして使いたかったので、以下のように環境変数を設定するようにしたんですが、うまく変数展開がされませんでした。
ENV PORT=8000
ENV HOST=0.0.0.0
COPY server.py server.py
ENTRYPOINT ["/app/.venv/bin/uvicorn", "server:app", "--host", "$HOST", "--port", "$PORT"]
実行時エラー
Error: Invalid value for '--port': '$PORT' is not a valid integer.
Usage: uvicorn [OPTIONS] APP
Try 'uvicorn --help' for help.
公式リファレンスの記載
シェル 形式とは異なり、 exec 形式はコマンドシェルを呼び出しません。つまり、通常のシェルとしての処理が怒らないのを意味します。たとえば、 ENTRYPOINT [ "echo", "$HOME" ] では、 $HOME を変数展開しません。シェルとしての処理を行いたい場合には、 シェル 形式を使うか、 ENTRYPOINT [ "sh", "-c", "echo $HOME" ] のようにシェルを直接実行します。exec 形式を使って直接シェルを実行する場合は、シェル形式の場合と同様に、環境変数の展開をするのはシェルであり、 Docker ではありません。
Discussion