Dockerfileの書き方, 利用する命令, 作成手順

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

以下のように、ブラウザからアクセスできることを確認できます。
docker_ build_image_confirm.png

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
わくわくBank.
ソフトウェア開発で必要とされる技術、用語、概念を整理しています。