Dockerfile | Docker
Ref.
- Dockerfile reference
- Dockerfile リファレンス
- https://qiita.com/uehaj/items/e6dd013e28593c26372d
命令
Dockerfileで指定できるおもな命令。
| 命令 | 内容 |
|---|---|
| FROM | ベースイメージ指定 |
| COPY | コンテナ内のファイルシステムにコピー |
| RUN | イメージをビルドするときに実行するコマンドを指定 |
| CMD | コンテナ起動時に実行 |
| ENTRYPOINT | コンテナ起動時に実行 |
| EXPOSE | ポート番号 |
| ENV | 環境変数 |
| ARG | 変数を定義して、ビルド時にその値を受け渡す |
| USER | 実行ユーザーを指定(未指定時はデフォルトで root) |
コマンド実行
- RUN・・・イメージ作成時に実行
- CMD・ENTRYPOINT・・・コンテナ実行時に(1回かぎり)実行(つまり
$ docker runのときに実行)
CMD
以下によって意味がことなる
ENTRYPOINT命令なしENTRYPOINT命令あり
ENTRYPOINT命令なし
コンテナの実行時のデフォルト処理を設定することです。 この処理設定においては、実行モジュールを含める場合と、実行モジュールを省略する場合があります。 省略する場合は ENTRYPOINT 命令を合わせて指定する必要があります。
https://docs.docker.jp/engine/reference/builder.html#cmd
ENTRYPOINTがない場合は実行モジュールを含める。
例) httpd
ENTRYPOINT命令はなくCMD命令のみ。
# Dockerfile
# ...
# デフォルト処理
CMD ["httpd", "-DFOREGROUND"]
実際はシェルスクリプトをCOPYでコンテナにコピーして、実行している。
# https://github.com/docker-library/httpd/blob/077141ee37fca63972292c562ec0f632d0f831b1/2.4/Dockerfile
# Dockerfile
# ...
COPY httpd-foreground /usr/local/bin/
EXPOSE 80
CMD ["httpd-foreground"]
#!/bin/sh
set -e
# Apache gets grumpy about PID files pre-existing
rm -f /usr/local/apache2/logs/httpd.pid
exec httpd -DFOREGROUND "$@"
※ 位置パラメーター"$@"はすべてのパラメーターを表す。
ENTRYPOINT命令あり
実行モジュールを省略する。CMD命令に記載した値は、ENTRYPOINT命令の引数になる。
ENTRYPOINT
- 実行可能モジュールを指定
ENTRYPOINT命令があるときCMD命令はENTRYPOINT命令の追加の引数として使用docker runで引数が指定された場合はCMD命令は上書きされるENTRYPOINTを指定した場合、docker runでは--entrypointで上書きしない限り任意のプロセスは指定できない
docker run
に対するコマンドライン引数は、exec 形式の ENTRYPOINT の指定要素の後に付け加えられます。 そして CMD において指定された引数は上書きされます。 これはつまり、引数をエントリーポイントに受け渡すことができるということです。 たとえば docker run
-d としたときの -d は、引数としてエントリーポイントに渡されます。 docker run --entrypoint を利用すれば ENTRYPOINT の内容を上書きすることができます。
https://docs.docker.jp/engine/reference/builder.html#entrypoint
ENTRYPOINTとCMDが使用されている例
Dockerfile
https://github.com/docker-library/wordpress/blob/dd8724a5b8c21eebd262aebf3593df0e13b5e917/latest/php7.4/fpm/Dockerfile
php:7.4.6を調査
php:7.4.6を調査。
$ docker pull php:7.4.6
$ docker inspect php:7.4.6
結果抜粋.
"Cmd": [
"php",
"-a"
],
"ArgsEscaped": true,
"Image": "sha256:79cc1ba190b4dd60b8acf8b5952def4ff458a6ddf50aa2ea83f887cf05067ec0",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"docker-php-entrypoint"
],
"OnBuild": null,
"Labels": null
コンテナにログインしてdocker-php-entrypointのパスを確認。
$ docker run -it php:7.4.6 /bin/bash
root@b21ffc5dc54d:/# find . -name docker-php-entrypoint
./usr/local/bin/docker-php-entrypoint
docker-php-entrypointの内容を確認。
root@b21ffc5dc54d:/# cat /usr/local/bin/docker-php-entrypoint
#!/bin/sh
set -e
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- php "$@"
fi
exec "$@"
※ 位置パラメーター"$@"はすべてのパラメーターを表す。
追加で覚えておくと便利な命令
WORKDIR
WORKDIR /app
USER(実行ユーザーの指定)
USER 命令を指定しない場合、コンテナ内およびビルド時のコマンドはデフォルトで root ユーザー(UID: 0) として実行されます。
セキュリティ上のベストプラクティスとして、実運用では以下のように非特権ユーザーを作成・指定して実行することが推奨されます。
# 非特権ユーザーの作成と切り替え例
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
# 以降の命令およびコンテナ実行時は appuser 権限で動く
USER appuser
※ ベースイメージ自体で USER が切り替えられている場合(例: Node.js 公式イメージの USER node 等)は、その指定が引き継がれます。
HEALTHCHECK
HEALTHCHECK CMD curl -f http://localhost/ || exit 1
COPY –chown
COPY --chown=appuser:appuser src/ .
マルチステージビルド
FROM golang:1.24 AS builder
WORKDIR /src
COPY . .
RUN go build -o app
FROM ubuntu:24.04
COPY --from=builder /src/app /usr/local/bin/app
USER www-data
CMD ["app"]