naichi's lab

3日後の自分(他人)への書き置き

Docker for Windows、Dockerfileを試してみる

f:id:naichilab:20180114003948p:plain

概要

前回Dockerの基本コマンドを触ってみました。

blog.naichilab.com

これだけでも十分に便利そうなんですが、コンテナを作ってから docker attachdocker exec で構築していくので、何をやったかメモっておかないとあとでよく分からなくなります。

Dockerfile っていうものを使うと、あらかじめどういう構成にするかをファイルとして記載し、コマンド一つでイメージを作成できるようです。

簡単に as a Code が実現できそうですね。

今回はこの Dockerfile を試してみます。

プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化

Dockerfileを試す

Dockerfileを作ってみる

# ベースイメージの指定
FROM centos:latest

# 作者情報
MAINTAINER naichilab naichilab@live.jp
  • # でコメントが書ける
  • FROM でベースイメージを指定
  • MAINTAINER で作者情報を記載

ビルドしてみる

Dockerfileのあるフォルダで、 docker build .

. は出力先パスなので現在のフォルダ(になるのか分かんないけど . 書いてみた)。

> docker build -t naichilab/centos1 .
Step 1/2 : FROM centos:latest
Step 2/2 : MAINTAINER naichilab naichilab@live.jp
Successfully built 31d545ec16b2
Successfully tagged naichilab/centos1:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

なんか警告出てるけど成功したっぽい。

Dockerfileのフォルダ以下にあるものは docker build 時にすべて転送されるらしい。無駄に転送すると遅いので、空のフォルダにDockerfileを作ることが推奨されてた。また、 .dockerignore ファイルを作れば個別に転送しないように設定できるようで、 .git フォルダ等は除外すべきとも書かれていた。

確認

> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
naichilab/centos1   latest              31d545ec16b2        25 minutes ago      207MB
<none>              <none>              01ea307b634a        2 days ago          919MB
centos              latest              ff426288ea90        7 days ago          207MB

ちゃんと追加されてる。

Dockerfileにいろいろ書いてみる

コマンド実行 RUN

  • イメージを作成するために実行するコマンド
FROM centos:latest
RUN echo こんにちはShell形式です
RUN ["echo", "こんにちはExec形式です"]
RUN ["/bin/bash", "-c", "echo", "こんにちはExec形式+bashです"]
> docker build -t sample1 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos:latest
 ---> ff426288ea90
Step 2/4 : RUN echo �����ɂ���Shell�`���ł�
 ---> Running in de4126f46191
/bin/sh: -c: line 0: unexpected EOF while looking for matching ``'
/bin/sh: -c: line 1: syntax error: unexpected end of file
The command '/bin/sh -c echo �����ɂ���Shell�`���ł�' returned a non-zero code: 1

DockerfileがSJISだと文字化けした・・・

UTF-8にしてやり直し

> docker build -t sample1 .
Step 1/4 : FROM centos:latest
Step 2/4 : RUN echo こんにちはShell形式です
こんにちはShell形式です
Step 3/4 : RUN ["echo", "こんにちはExec形式です"]
こんにちはExec形式です
Step 4/4 : RUN ["/bin/bash", "-c", "echo", "こんにちはExec形式+bashです"]

ん~最後の出てないな・・・

  • Shell形式だと /bin/sh で実行されるらしい
  • Exec形式だとシェルを介さず直接実行されるらしい
  • 別のシェルを使いたいときとかはシェルのパスを指定して実行する
# httpdをインストール (Shell形式)
RUN yum -y install httpd

# httpdをインストール (Exec形式)
RUN ["/bin/bash", "-c", "yum -y install httpd"]
  • shで実行したいときだけShell形式。
  • あとはExec形式でいい。
  • らしいけど sh とか bash とかよく分からん
イメージ内の構成確認 docker history
> docker history sample1
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
6465a7fdc94d        6 minutes ago       /bin/bash -c echo こんにちはExec形式+bashで…            0B
00a0d6b8d1aa        6 minutes ago       echo こんにちはExec形式です                              0B
4cdeb8f7f413        6 minutes ago       /bin/sh -c echo こんにちはShell形式です                  0B

指定イメージがどのように構成されたかのログが見れる?見方よくわからん。

デーモンの実行 CMD

  • コンテナ内でコマンドを実行する。
  • Dockerfile には一つだけ CMD を記載できる。
    • RUN で httpd をインストールし、
    • CMD で httpd をデーモンとして起動
    • みたいな。
# httpd 実行 (Shell形式)
CMD /usr/sbin/httpd -D FOREGROUND

# httpd 実行 (Exec形式)
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
CMD の代わりに ENTRYPOINT を使うこともできる
  • CMD を使うと、 docker run の引数で渡されたコマンドの方が優先されるため、イメージ作成者の意図と違うデーモンが実行されることがある
  • ENTRYPOINT を使うと、 docker run の引数にコマンドを渡されても無視して ENTRYPOINT で定義したコマンドが実行される

ビルド完了後に実行 ONBUILD

  • ちょっと説明読んでもよく分からなかった・・・
  • そのうち理解できたら追記しよう

環境変数の設定 ENV

ENV key value
  • コンテナ内に環境変数を設定する
  • docker run 時に env オプションをつければ上書きすることができる

作業ディレクトリの指定 WORKDIR

  • 作業ディレクトリを指定する
  • RUN / CMD / ENTRYPOINT / COPY / ADD 等のコマンドに影響する
FROM centos:latest
ENV DIRPATH /first
ENV DIRNAME second
WORKDIR $DIRPATH/$DIRNAME
RUN ["pwd"]
> docker build -t sample2 .
Step 1/5 : FROM centos:latest
Step 2/5 : ENV DIRPATH /first
Step 3/5 : ENV DIRNAME second
Step 4/5 : WORKDIR $DIRPATH/$DIRNAME
Step 5/5 : RUN ["pwd"]
/first/second

ユーザーの指定 USER

  • 実行ユーザを指定する
  • RUN / CMD / ENTRYPOINT に影響する
FROM centos:latest
RUN ["adduser", "naichi"]
RUN ["whoami"]
USER naichi
RUN ["whoami"]
> docker build -t sample3 .
Step 1/5 : FROM centos:latest
Step 2/5 : RUN ["adduser", "naichi"]
Step 3/5 : RUN ["whoami"]
root
Step 4/5 : USER naichi
Step 5/5 : RUN ["whoami"]
naichi

ポートの設定 EXPOSE

  • コンテナの公開するポートを指定する
EXPOSE 8080

ファイル/ディレクトリの追加 ADD

  • イメージにホスト上のファイルを追加する
ADD host_file_path docker_image_file_path
ADD ["host_file_path", "docker_image_file_path"]

# htmlファイルを追加する
ADD host.html /docker_dir/
  • コピー元ファイル名はURLでもいいらしい

ファイルのコピー COPY

COPY host_file_path docker_image_file_path
COPY ["host_file_path", "docker_image_file_path"]
  • ADDと違い、リモートファイルの追加はできない
  • 単純にファイルコピーを行う場合はこっちを使う

ボリュームのマウント VOLUME

  • イメージにボリュームを割り当てることができる
  • ホストやその他コンテナからボリュームの外部マウントを行うことができる
ログとWebサーバを別コンテナで構成する例
ログ用コンテナ
FROM centos:latest
RUN ["mkdir", "/var/log/httpd"]
VOLUME /var/log/httpd
> docker build -t log-image .
Step 1/3 : FROM centos:latest
Step 2/3 : RUN ["mkdir", "/var/log/httpd"]
Step 3/3 : VOLUME /var/log/httpd
docker run -it --name log-container log-image
Webサーバーコンテナ
FROM centos:latest
RUN ["yum", "-y", "install", "httpd"]
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
> docker build -t web-image .
Step 1/3 : FROM centos:latest
Step 2/3 : RUN ["yum", "-y", "install", "httpd"]
Complete!
Step 3/3 : CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
> docker run -d --name web-container -p 80:80 --volumes-from log-container web-image
Kitematicで見たところ。

f:id:naichilab:20180117010208p:plain:w320

2つのコンテナが起動し、デフォルトのサイトが表示されている

けどうまくログが書かれない・・・!なんでや。

また今度調べよ。

まとめ

  • Dockerfileを使うと構成がテキストファイルとして管理できて便利!
  • コンテナ間の連携はまだよく分からん!

プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化