はじめに
WORKDIR
は、Dockerfileでコンテナ内の作業ディレクトリを指定するための基本命令です。
しかし「単なるcd
の代わり」と軽視されがちで、複数階層のビルド、ユーザー切り替え、キャッシュ制御、CI/CD環境下での安定ビルドなどを意識する中・上級者にとっては、意外と奥深い命令です。
本記事では、WORKDIR
の仕組みを再確認しつつ、運用現場でのベストプラクティスと落とし穴を実例とともに解説します。
1. WORKDIR
の基本動作を再確認
WORKDIR
は指定したディレクトリを作成し、以降の命令(RUN
, CMD
, ENTRYPOINT
, COPY
, ADD
など)の実行ディレクトリを切り替えます。
FROM ubuntu:22.04
WORKDIR /app
COPY . .
RUN make
この例では、make
は/app
内で実行されます。
既に存在しないディレクトリでも、自動的に作成されるのがWORKDIR
の特徴です。
2. WORKDIR
と相対パスの組み合わせ
WORKDIR
は連続して記述することで階層を積み上げられます。
WORKDIR /usr/src
WORKDIR app
# 現在の作業ディレクトリは /usr/src/app
これにより、ベースイメージ側のパス構造を柔軟に継承可能です。
特に複数ステージビルドでの中間イメージでは、ベースのWORKDIR
構造を意識して相対指定することが重要です。
3. WORKDIR
とUSER
命令の順序関係
中~上級者が陥りやすい落とし穴として、USER
命令とWORKDIR
の順序があります。
FROM node:20-slim
USER node
WORKDIR /app
上記では、node
ユーザーに/app
ディレクトリの作成権限がない場合、ビルドが失敗します。
対策としては、権限付与または順序変更を行います。
WORKDIR /app
RUN chown node:node /app
USER node
USER
より前にWORKDIR
を設定し、権限を整えるのがベストプラクティスです。
4. マルチステージビルドにおけるWORKDIR
戦略
複数のビルドステージを使う場合、各ステージでWORKDIR
を明示的に指定しておくと可読性とメンテナンス性が向上します。
# ビルド用ステージ
FROM golang:1.22 as builder
WORKDIR /src
COPY . .
RUN go build -o app
# 実行ステージ
FROM debian:bookworm-slim
WORKDIR /app
COPY --from=builder /src/app .
CMD ["./app"]
WORKDIR
をステージごとに設定することで、ファイルパスの明示性とキャッシュ効率を高められます。
5. WORKDIR
を動的に設定する(ARGとの組み合わせ)
ビルド時の環境やターゲットによってディレクトリ構造を切り替えたい場合、ARG
と組み合わせることで柔軟なDockerfileを構築できます。
ARG TARGET_DIR=/opt/app
WORKDIR ${TARGET_DIR}
COPY . .
RUN ./build.sh
ただし、環境変数の展開はWORKDIR
命令でサポートされているものの、ENV
で定義した変数はその後の命令から有効になる点に注意してください。
6. キャッシュ戦略とWORKDIR
の関係
WORKDIR
の変更はキャッシュキーに影響します。
同一のRUN
命令でも、異なるWORKDIR
下で実行されれば別キャッシュ扱いになります。
そのため、キャッシュを有効に活用したい場合は、WORKDIR
を頻繁に変更せず、1つのビルドステップで固める設計が望ましいです。
7. ハンズオン:WORKDIR
で整える再現性の高いビルド
次のDockerfile例は、WORKDIR
の適切な利用で再現性と保守性を両立した構成です。
FROM python:3.12-slim
ENV APP_HOME=/usr/src/app
WORKDIR ${APP_HOME}
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
RUN adduser --disabled-password appuser \
&& chown -R appuser ${APP_HOME}
USER appuser
CMD ["python", "main.py"]
このように、WORKDIR
を明確化することで、
- 依存パスの混乱を防ぐ
- キャッシュ再利用を最適化
- ビルドの一貫性を担保
といった恩恵が得られます。
8. 運用現場でのベストプラクティスまとめ
シナリオ | 推奨アプローチ |
---|---|
権限が異なるユーザーを使用 | WORKDIR → RUN chown → USER の順に定義 |
複数ステージビルド | 各ステージでWORKDIR を定義して可読性確保 |
キャッシュ効率重視 | WORKDIR の切り替えを最小限にする |
可搬性重視 | ${APP_HOME} のようなENV 変数と組み合わせる |
まとめ
WORKDIR
は一見単純な命令ですが、イメージ構造・権限・キャッシュ・ステージ設計に密接に関わる、Dockerfileの設計品質を左右する要素です。
特に中~上級者ほど、WORKDIR
をどこで・どの順序で設定するかを意識することで、ビルドエラーや非効率なキャッシュ破棄を防げます。
次のステップとして、COPY
命令やUSER
命令との依存関係をさらに掘り下げた「セキュアなDockerfile設計」編へと進むと良いでしょう。
コメントを残す