Dockerfileを作成し、Dockerイメージを生成するために必要な知識についてご紹介します。
Dockerfileの「基本的な書き方」「よく利用する命令」「効率の良い作成手順」など解説していきます。
作業の流れ
Dockerfile作成
Dockerfileを作成するための効率的な手順を下記記事で紹介してくださっています。
大まかな手順は以下の通りです。
- ベースイメージを決める
- ベースイメージのコンテナ内で作業しつつ、うまくいった処理をメモ
- 全て成功したらDockerfileを作成
短時間で正確にDockerfileを作成したい場合、参考になります。
Dockerfileからイメージを作成
docker image buildコマンド
を利用して、 Dockerfile
から Dockerイメージ
を作成します。
docker image build -t イメージ名[:タグ名] [Dockerfileが配置されているディレクトリパス]
docker image build -t xxxx/xxxx:latest .
-tオプション
でイメージ名を指定できます。
イメージ名を指定しないと管理が面倒になるため、必ず利用することをお勧めします。
名前の付け方
<account name>/<image name>:<tag>
- account name
- Docker Hubでのアカウント名を指定します。
- 任意です。
- image name
- イメージ名です。
- 必須です。
- tag
バージョン
、またはラベル
を設定します。- 設定しない場合、
latestタグ
が付けられます。 - 任意です。
イメージの確認
イメージが作成できたら、下記コマンドで確認できます。
docker image ls
Docker HubにPush
事前にDocker Hubでユーザー登録を済ませておく必要があります。
# Docker Hubにログイン
# ユーザ名, パスワード, メールアドレスが聞かれます
docker login
# Docker HubにPush
docker push イメージ名
簡単な例で動作確認
ベースイメージのコンテナ内で作業
今回は、 centos:7
をベースイメージにします。
docker container run -it centos:7 /bin/bash
を実行して、ベースイメージのコンテナ内で必要な作業が正しく動作するかを確認します。
$ docker container run -it centos:7 /bin/bash
Unable to find image 'centos:7' locally
7: Pulling from library/centos
256b176beaff: Pull complete
Digest: sha256:6f6d986d425aeabdc3a02cb61c02abb2e78e57357e92417d6d58332856024faf
Status: Downloaded newer image for centos:7
[root@863311f4f9ec /]#
[root@863311f4f9ec /]#
(以降、必要な作業が正しく動作することを確認する)
Dockerfile作成
作業が正しく動作することを確認できたらDockerfileを作成していきます。
$ vi Dockerfile
FROM centos:7
RUN echo "now building..."
RUN yum -y install httpd
RUN sed -i '/#ServerName/a ServerName www.example.com:80' /etc/httpd/conf/httpd.conf
ADD ./index.html /var/www/html/
EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
コンテナ内に追加する index.html
の中身は以下のようにしています。
hello
ファイル構成は以下のようになりました。
$ ls
Dockerfile index.html
Dockerfileからイメージを作成
作成した Dockerfile
をもとに Dockerイメージ
を作成します。
$ docker image build -t xxxx/sample:latest .
Sending build context to Docker daemon 3.072kB
Step 1/7 : FROM centos:7
---> 5182e96772bf
Step 2/7 : RUN echo "now building..."
---> Running in 0c54e86a8f21
now building...
Removing intermediate container 0c54e86a8f21
---> 0975764fc064
Step 3/7 : RUN yum -y install httpd
---> Running in 3c4a3c4fbf74
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: ftp.tsukuba.wide.ad.jp
* extras: ftp.tsukuba.wide.ad.jp
(省略)
Step 6/7 : EXPOSE 80
---> Running in 14f21d065988
Removing intermediate container 14f21d065988
---> 663d23b0e382
Step 7/7 : CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
---> Running in 16dfc8adf720
Removing intermediate container 16dfc8adf720
---> 405c0c2128b0
Successfully built 405c0c2128b0
Successfully tagged xxxx/sample:latest
以下のように、作成された Dockerイメージ
を確認できます。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
xxxx/sample latest 405c0c2128b0 40 seconds ago 326MB
centos 7 5182e96772bf 5 weeks ago 200MB
イメージをもとにコンテナ起動
作成したイメージでコンテナ起動してみます。
$ docker container run -d -p 10080:80 xxxx/sample
f0c031e89da5fa50f0a8c012e6f7e194f907daa938bb5b8b97d0cfef531eff22
$
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f0c031e89da5 xxxx/sample "/usr/sbin/httpd -D …" 7 seconds ago Up 6 seconds 0.0.0.0:10080->80/tcp keen_newton
以下のように、ブラウザからアクセスできることを確認できます。
Dockerfileで利用できる命令
Dockerfileで利用できる命令について紹介します。
FROM|ベースイメージを指定
Docker Hubで公開されているイメージを利用できます。
docker searchコマンド
でイメージを検索できます。
$ docker search --limit 5 elasticsearch
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
elasticsearch Elasticsearch is a powerful open source sear… 3030 [OK]
itzg/elasticsearch Provides an easily configurable Elasticsearc… 66 [OK]
lmenezes/elasticsearch-kopf elasticsearch kopf 17 [OK]
mesoscloud/elasticsearch [UNMAINTAINED] Elasticsearch 9 [OK]
centerforopenscience/elasticsearch Elasticsearch 3 [OK]
FROMの書式は以下の通りです。
FROM <イメージ>
FROM <イメージ>:<タグ>
FROM centos
FROM centos:7
FROM ubuntu:latest
FROM debian:stable
MAINTAINER|作成者情報
MAINTAINER <名前>
LABEL|metaデータ追加
LABEL <key>=<value>
LABEL description="xxxxxxxxxx"
RUN|コマンド実行
RUN <コマンド>
RUN ["実行バイナリ", "パラメータ1", "パラメータ2"]
RUN chown -R mysql:root /var/lib/mysql/
RUN apt-get update && apt-get install -y \
gimp \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
各コマンドごとにレイヤーが作成されます。レイヤーには上限があるため、まとめて実行するように記述すると良いです。
apt-getコマンドでは、 -yオプション
を付けて、インストールするかどうか聞かれないようにしています。
CMD|コンテナ実行時の実行コマンド
- Dockerfileで一度だけ指定できます。
- docker run時に実行されるコマンドを指定します。
- docker run時にコマンドを指定した場合、指定したコマンドが実行されます。
CMD <コマンド>
CMD ["実行バイナリ", "パラメータ1", "パラメータ2"]
CMD ["mysqld"]
CMD [ "npm", "start" ]
ENTRYPOINT|コンテナ実行時の実行コマンド
- Dockerfileで一度だけ指定できます。
- docker run時に実行されるコマンドを指定します。
- docker run時にコマンドを指定しても、ENTRYPOINTのコマンドがそのまま実行されます。
["command", "paramN"]形式
による引数付きコマンドで記述した場合、docker run時にparam部分だけ上書きすることができます。
ENTRYPOINT ["実行可能なもの", "パラメータ1", "パラメータ2"]
ENTRYPOINT コマンド パラメータ1 パラメータ2
ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/jenkins.sh"]
EXPOSE|ポートの解放
EXPOSE <port> [<port>...]
EXPOSE 3306
VOLUME|マウント
VOLUME ["/data"]
VOLUME /sessions
ADD|File/Directory追加
UIDとGIDが 0
として追加されます。そのため、root以外のユーザーで利用するにはパーミッションを変更する必要があります。
ADD <ソース>... <送信先>
ADD ["<ソース>", ... "<送信先>"]
ADD my.cnf /etc/mysql/conf.d/my.cnf
ADD nginx.conf /etc/nginx/
COPY|File/Directoryコピー
UIDとGIDが 0
として追加されます。そのため、root以外のユーザーで利用するにはパーミッションを変更する必要があります。
COPY <ソース>... <送信先>
COPY ["<ソース>",... "<送信先>"]
COPY . /usr/src/app
COPY jenkins.sh /usr/local/bin/jenkins.sh
USER|実行ユーザ指定
USER <ユーザ名>
USER root
WORKDIR|作業ディレクトリ指定
WORKDIR <ディレクトリパス>
WORKDIR /var/www
ENV|環境変数設定
ENV <key>=<value> ...
ENV CACHE_SIZE=128m \
BACKEND_HOST=localhost