前回の記事で簡単なDockerfileを初めて作ってみました。
ですが、全くDockerfileの書き方について触れてなかった、というよりスルーしていたのでちょっとまとめてみたいと思います。
他にDockerfileの記事を書いている人はだいたいわかりにくい・・・
多分簡単です。慣れれば。
Dockerfileってなによ
簡単に言えば、「コンテナを作るときの説明書」および「手順書」のこと。
Dockerfileのおかげで以下
- dockerイメージを作成
- コンテナ内で行うコマンド操作
- 環境変数の設定
- コンテナ内で動作させるデーモン実行
をビルド時に実行してイメージを作成したりします。
ね!簡単でしょ?
Dockerfileの命令一覧
命令 | 説明 |
---|---|
FROM | ベースイメージの指定 |
MAINETAINER | Dockerfileの作成者情報 |
RUN | コマンド実行 |
VOLUME | ボリュームのマウント |
ADD | ファイル/ディレクトリの追加 |
COPY | ファイルのコピー |
CMD | デーモン実行 |
ENTRYPOINT | デーモン実行 |
LABEL | ラベルの設定 |
USER | ユーザの指定 |
EXPOSE | ポートのエクスポート |
WORKDIR | 作業ディレクトリの指定 |
ENV | 環境変数の設定 |
ONBUILD | ビルド完了後に実行される命令 |
上の表がDockerfileの命令です。 これを元にやっていきます。
今回はほんと簡単な命令しか書きません。
次回以降暇があれば記事にします。
実行環境
- ubuntu16.04.1(elementary OS 0.4.1 Loki)
- Docker version 17.12.0-ce
準備
わかりやすいようにディレクトリの準備をします。
$ cd ~ && mkdir docker-practice && cd !!$ && touch Dockerfile
homeディレクトリに移動してdocker-practiceディレクトリ作成&移動、Dockerfileを作成します。
FROM命令
DockerfileではコンテナはどのDockerイメージから生成するかという、「ベースイメージ」が必要なので、それをFROM命令で書いてあげます。
FROM イメージ名 or FROM イメージ名:タグ名 or FROM イメージ名@ダイジェスト
上記の形で書きます。
が、上2つだけ覚えておけばとりあえず大丈夫です。
たとえば、最新のubuntuイメージを取ってきたい場合は
FROM ubuntu:latest
でおk。超簡単。
試しにイメージを作ってみますか。
docker build -t <イメージ名> <Dockerfileのディレクトリ>
で実行してみる(<イメージ名>:<タグ名>でタグをつけることができます)。
# 作成したDockerfileと同じディレクトリにいるはずなので"."でおk $ docker build -t test . Sending build context to Docker daemon 2.048kB Step 1/1 : FROM ubuntu:latest latest: Pulling from library/ubuntu d3938036b19c: Pull complete a9b30c108bda: Pull complete 67de21feec18: Pull complete 817da545be2b: Pull complete d967c497ce23: Pull complete Digest: sha256:9ee3b83bcaa383e5e3b657f042f4034c92cdd50c03f73166c145c9ceaea9ba7c Status: Downloaded newer image for ubuntu:latest ---> c9d990395902 Successfully built c9d990395902 Successfully tagged test:latest
まあまあ時間かかりました。
ちゃんとDockerfileを元にイメージが作成されているか確認してみる。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE test latest c9d990395902 2 days ago 113MB ubuntu latest c9d990395902 2 days ago 113MB
できてますね。
他のディレクトリにあるDockerfileを指定する時は、ディレクトリパスをdocker buildの最後に書いてあげてください。
今書いたDockerfileを元に別のイメージ名にしてdocker buildしてみると、前よりかなり早くbuildが完了するはず。
これは、ubuntu:latest
のベースイメージがローカル環境にダウンロードされているためです。
同じイメージを使用するときはかなり早くbuildできます。
RUN命令
コンテナ上で実行するコマンドの命令です。
CentOS系のyumとUbuntu系のapt-getを元に検索かけていけばいいと思いますよ(多分)。
さっきのイメージを元にApache
を入れてみたいと思います。
FROM ubuntu:latest # apt-getパッケージ管理のupdateとapache2のインストール RUN apt-get update && apt-get install -y apache2
※ apt
コマンドは使えませんでした。
↑
いけたけど、WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
が出てあんま推奨されてないっぽい。
じゃあbuildしましょう。
# リビルドするときはタグ名を後ろにつけたらおk $ docker build -t test:latest . ・ ・ ・ Step 1/2 : FROM ubuntu:latest ---> c9d990395902 Step 2/2 : RUN apt-get update && apt-get install -y apache2 ---> Using cache ---> 5a2551cf2ad8 Successfully built 5a2551cf2ad8 Successfully tagged test:latest
ちょっと確認
本当に入っているかどうか、コンテナの中に入って確認してみます。
$ docker run -it c9d990395902 /bin/bash #
これでさっきのイメージIDを元にコンテナの中に入れます。
# apache2 -v Server version: Apache/2.4.18 (Ubuntu) Server built: 2017-09-18T15:09:02
ちゃんとApache入ってました\(^o^)/
ここでctrl + p + q
を押せばコンテナを起動したまま出ることができますが、今回はその必要もないのでexit
コマンドで出ます。
exit
だとコンテナ起動と終了を一緒にやってくれます。
ちなみに
直接コンテナに入ってから、apt-get
で何かパッケージをインスコした場合、exitで出てしまうとそのインスコはなかったことになります。
これは、imageがbuildした際の状態を保っているからです。
なので、「あれ〜この前インスコしたのになぁ〜」ってなったときはこの可能性が多いです。
要注意です。まじで。
CMD命令
デーモン実行。
イメージを元に生成したコンテナ内でコマンドを実行するために使うやつ。
ちなみにこいつはDockerfile内で一つしかかけない。複数書いた場合は、最後のだけが実行される。
さっきのDockerfileの最後に、Apacheサーバーを立てるコマンドを記載してみます。
FROM ubuntu:latest # apt-getパッケージ管理のupdateとapache2のインストール RUN apt-get update && apt-get install -y apache2 # デーモン起動 CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
ここでちょっと詰まったのですが、デーモン起動の際に/usr/sbin/apache2
では起動しませんでした。
要注意です。
CentOSの場合は/usr/sbin/httpd
です。
コンテナを起動
docker run
でポート指定(-p
オプション) & デタッチド(-d
オプション)で起動します。
$ docker run -d -p 80:80 test or $ docker run -p 80:80 -d test
長い文字列が出ると思います。
なにか問題があればメッセージが出るはず。
本当に起動してるか確認しましょー。
docker ps
コマンドで。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 78fe3aafeada test "/usr/sbin/apachectl…" 4 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp nervous_morse
動いてなければここで表示されないです。 今回はちゃんと表示されているので問題なしです。
特定のものだけ表示したい場合はフォーマットを指定すればおk。
例えばこんな感じ。
$ docker ps --format={{.Image}} {{.Command}} {{.Ports}}
こうすれば、イメージ名と実行したコマンド、ポートが表示されます。参考程度に。
画面の確認
ポートを80 -> 80
に開放しているので単純にlocalhostでアクセスできます。
問題なさげ!
終わり
次回はファイルの追加やボリュームの指定、ポートのエクスポート等を簡単なDockerfileを元に作成したいと思います。
みんなDockerfileかけるようになろう(自問自答)。