Dockerfile@Docker¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. セットアップ¶
インストール¶
▼ aptリポジトリから¶
Dockerエンジン、CLI、インストールする。
$ apt-get install -y \
docker-ce \
docker-ce-cli
docker
プロセスをデーモンとして起動する。
$ systemctl start docker
イメージのデバッグ¶
*例*
ビルドに失敗したコンテナイメージからコンテナを作成し、接続する。
rm
オプションを設定し、接続の切断後にコンテナを削除する。
Dockerfileで、コンテナイメージのプロセスの起動コマンドをENTRYPOINT
で設定している場合は、後から上書きできなくなる。
そのため、docker run
コマンドの引数として新しいコマンドを渡せずに、デバッグできないことがある。
$ docker run --rm -it <ビルドに失敗したコンテナイメージID> /bin/bash
その他、プルしたコンテナイメージ内でちょっとしたコマンドを検証したいといった場合にも役立つ。
$ docker run --rm -it <検証したいコンテナイメージID> ls
02. ADD¶
ADDとは¶
ホスト側のファイルを、コンテナの指定ディレクトリ配下にコピーし、このファイルがtar
ファイルの場合は解凍する。
また、URLを直接的に指定して、ダウンロードから解凍までを実行もできる。
COPYとの違い¶
似た命令としてCOPY
処理がある。
ADD
処理はCOPY
処理とは異なり、インターネットからファイルをダウンロードして解凍した上で、コピーする。
解凍によって意図しないファイルがDockerfileに組み込まれる可能性があるため、COPY
処理が推奨である。
*実装例*
以下ではADD
処理を使用している。
URLを直接的に指定し、ダウンロードから解答までを実行している。
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
これは、次のように書き換えるべきである。
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz | tar -xJC /usr/src/things \
&& make -C /usr/src/things all
03. ARG¶
ARGとは¶
Dockerfikeの命令で扱える変数を定義する。
ENVとの違い¶
似た命令としてENV
がある。
ARG
はENV
とは異なり、OS上のコマンド処理に展開するための変数として定義できない。
# ARGは、OS上のコマンド処理に展開するための変数として定義できない。
ARG PYTHON_VERSION="3.8.0"
# 変数を展開できない
RUN pyenv install ${PYTHON_VERSION}
# ENVは、OS上のコマンド処理に展開するための変数として定義できる。
ARG PYTHON_VERSION="3.8.0"
RUN pyenv install ${PYTHON_VERSION}
一方で、Dockerfikeの命令に展開するための変数として定義できる。
# ARGは、Dockerfikeの命令に展開するための変数として定義できる。
ARG OS_VERSION="8"
FROM centos:${OS_VERSION}
# ENVは、Dockerfikeの命令に展開するため変数として定義できない。
ENV OS_VERSION "8"
# 変数を展開できない
FROM centos:${OS_VERSION}
そのため、以下の様に使い分けることになる。
# 最初に全て、ARGで定義
ARG CENTOS_VERSION="8"
ARG PYTHON_VERSION="3.8.0"
# 変数展開できる
FROM centos:${CENTOS_VERSION}
# ARGを事前に宣言
ARG PYTHON_VERSION
# 必要に応じて、事前にENVに詰め替える。
ENV PYTHON_VERSION ${PYTHON_VERSION}
# 変数展開できる
RUN pyenv install ${PYTHON_VERSION}
スコープ¶
▼ FROMより前のARG¶
FROM
より前で使用したARGS
は、後続含めてFROM
でしか使用できない。
ARG PYTHON_VERSION="3.8.0"
FROM python:${PYTHON_VERSION}
# 変数の値を使えない
RUN echo $PYTHON_VERSION
# 変数の値を使える
FROM python:${PYTHON_VERSION}
もしFROM
内で使用する場合は、変数の再宣言が必要である。
値の格納は不要である。
ARG PYTHON_VERSION="3.8.0"
FROM python:${PYTHON_VERSION}
# 変数の再宣言
ARG PYTHON_VERSION
# 変数の値を使えない
RUN echo $PYTHON_VERSION
# 変数の値を使える
FROM python:${PYTHON_VERSION}
04. CMD¶
CMDとは¶
イメージのプロセスの起動コマンドを実行する。
パラメーターの記述形式には、文字列形式、json
形式がある。
注意点¶
DockerfileでCMD
を指定しない場合、コンテナイメージのデフォルトのバイナリファイルが割り当てられる。
一旦、デフォルトのバイナリファイルを確認した後に、これをDockerfileに明示的に実装する。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b2d3dfafee8 ***** "/bin/sh" 11 seconds ago Up 8 seconds 0.0.0.0:8000->8000/tcp foo-image
静的型付け言語ではプロセスの起動時に、代わりにアーティファクトのバイナリファイルを実行しても良い。
その場合、bin
ディレクトリにバイナリファイルとしてのアーティファクトを配置することになる。
しかし、bin
ディレクトリへの認可スコープがないことがあるため、その場合は、1つ下にディレクトリを作成し、そこにバイナリファイルを配置するようにする。
# /go/bin にアクセスできない時は、/go/bin/cmdにアーティファクトを配置する。
ERROR: for xxx-container Cannot start service go: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "/go/bin": permission denied: unknown
05. COPY¶
COPYとは¶
ホスト側 (第一引数) のディレクトリ/ファイルをコンテナ側 (第二引数) にコピーする。
COPY ./src src/
コンテナ側のパスは、WORKDIR
をルートとした相対パスで定義できるが、絶対パスで指定した方がわかりやすい。
ディレクトリ内の複数ファイルを丸ごとコンテナ内にコピーする場合は、『/
』で終える必要がある。
イメージのビルド時にコピーされるのみで、ビルド後のコードの変更は反映されない。
設定ファイル (例:nginx.conf
ファイル、php.ini
ファイル) をホストからコンテナにコピーしたい時によく使用する。
--from¶
他のステージ名、ローカルのコンテナイメージ名、リモート (DockerHubのみ) のコンテナイメージ名、を指定して、そのコンテナイメージが持つファイルをコピーする。
COPY --from=composer:<バージョン> /usr/bin/composer /usr/bin/composer
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
06. ENTRYPOINT¶
ENTRYPOINTとは¶
イメージのプロセスの起動コマンドを実行する。
CMDとの違い¶
似た命令としてCMD
がある。
CMD
とは異なり、後から上書き実行できない。
使用者に、コンテナの起動方法を強制させたい場合に適する。
イメージのプロセスの起動コマンドを後から上書きできなくなるため、docker run
コマンドの引数として新しいコマンドを渡せずに、デバッグできないことがある。
# 上書きできず、失敗してしまう。
$ docker run --rm -it <コンテナイメージ名>:<バージョンタグ> /bin/bash
07. ENV¶
ENVとは¶
OS上のコマンド処理で展開できる変数を定義できる。
08. EXPOSE¶
EXPOSEとは¶
他のコンテナに対してコンテナポートを開放する。
また、コンテナイメージの利用者にとってのドキュメンテーション機能もあり、ポートマッピングを実行する時に使用できるコンテナポートとして保証する機能もある。
ホスト側からはアクセスできないことに注意する。
プロセスによるポート受信¶
コンテナのポートを開放するのみでは不十分である。
プロセス自体がリクエストを受信できるようにポートを設定する必要がある。
ただし、多くの場合デフォルトでこれが設定されている。
例えば、PHP-FPMでは、/usr/local/etc/www.conf.default
ファイルと/usr/local/etc/php-fpm.d/www.conf
ファイルには、listen
オプションの値に127.0.0.1:9000
が割り当てられている。
09. FROM¶
FROMとは¶
ベースのコンテナイメージを、コンテナにインストールする。
FROM python:latest-slim
イメージレジストリの指定¶
指定できるイメージレジストリの例と記法は以下の通りである。
▼ DockerHub¶
PHP-FPMをインストールする場合は、php:8.0-fpm
である。
▼ クラウドプロバイダー (パブリック)¶
パブリックなAWS ECR、Google Container Registry、Google Cloud Artifact Registry、RedHat Quay、からイメージをプルする。
ECRパブリックギャラリーからPHP-FPMをインストールする場合は、public.ecr.aws/bitnami/php-fpm:latest
である。
▼ クラウドプロバイダー (プライベート)¶
プライベートなAWS ECR、Google Container Registry、Google Cloud Artifact Registry、RedHat Quay、からイメージをプルする。
ECRプライベートレジストリからPHP-FPMをインストールする場合は、<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/private-foo-php-repository:latest
である。
バージョンの指定¶
タグ¶
FROM python:latest
ダイジェスト値¶
ダイジェスト値 (イメージの識別子) を指定する/
FROM python@sha256:*****
レートリミット¶
▼ DockerHub¶
DockerHubのレートリミットは、匿名アカウントであれば100
プル/6
時間、無料アカウントであれば200
プル/6
時間、である。
CIパイプライン上でコンテナイメージをビルドしていると、これにひっかかりやすい。
クラウドプロバイダーのレートリミットの方が寛容なため、クラウドプロバイダー (パブリック/プライベート) からプルする方法もよい。
▼ crane¶
crane
コマンドを使用すると、イメージレジストリ間のコンテナイメージの移動を簡素化できる。
# AWS ECRにログインする
$ crane auth login --username AWS --password-stdin <AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com
# DockerHubからAWS ECRにコンテナイメージをコピーする例
$ crane copy nginx:<バージョン> *****.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:<バージョン>
▼ krane¶
crane auth
コマンドを簡略化したコマンド
CPUアーキテクチャの指定¶
イメージの対応するCPUアーキテクチャ (例:Intel、AMD、ARM) を設定する。
ただし、DockerがホストのOSを認識して、自動的に選んでくれるため、ユーザーが設定する必要はない。
FROM --platform=linux/amd64 python:latest-slim
10. RUN¶
RUNとは¶
ベースイメージ上に、ソフトウェアをインストールする。
11. VOLUME¶
VOLUMEとは¶
ボリュームマウントを実行する。
12. WORKDIR¶
WORKDIRとは¶
ビルド中の各命令の作業ディレクトリを絶対パスで指定する。
また、コンテナ接続時の最初のディレクトリも定義できる。