「プログラマのためのDocker教科書」の感想・忘備録2の続き。
Dockerfile
Dockerfileはコンテナの構成情報を記述するためのテキストファイル。docker build
コマンドでDockerfileからイメージを生成する。
#以降はコメントとして扱われる。
# ベースイメージの指定
FROM centos
主な命令(小文字でも動くが、慣例的に大文字)
- FROM:ベースイメージの指定
- RUN:コマンド実行
- CMD:コンテナでコマンド実行
- ENV:環境変数
- COPY:ファイルコピー
- EXPOSE:ポート開放
Visual Studio Code
Visual Studio Codeの拡張機能vscode-dockerを使うと、Ctrl+スペースでスニペットが表示される。
また、Dockerfileだけでなくdocker-compose.yamlもサポートしている。
Visual Studio Codeのエクスプローラではイメージやコンテナの稼働状況も確認することができる。
Dockerfileからイメージの作成
docker build -t イメージ名[:タグ名] Dockerfileの格納ディレクトリ
例)docker build -t sample /home/hoge/
中間イメージ
Dockerはイメージをビルドする際、自動的に中間イメージを生成する。
中間イメージは、他のイメージをビルドする際に内部的に再利用される。これによってビルドが高速化する。
イメージを再利用しているときは、ビルドログにUsing cacheと表示される。
イメージのレイヤー構造
Dockerfileの命令ごとにイメージが作成される。
FROM ubuntu
RUN apt-get update && apt-get install -y -q nginx
とすると2つイメージが作成される。
busybox
基本的なLinuxコマンド群をまとめたイメージ。
必要最小限のシェル環境を提供する場合に利用されている。
RUN命令は1行で書く
RUN yum -y install httpd php phpmbstring
とすると内部イメージが1つだけできる。
RUN yum -y install httpd
RUN yum -y install php
RUN yum -y install phpmbstring
とすると内部イメージが3つ作られてしまう。
CMD命令
RUNはイメージ作成のためのコマンドであるのに対し、CMDは起動したコンテナ内で実行されるコマンド。
Dockerfileには1つだけCMD命令を書くことだできる。
例)CMD nginx -g 'deamon off;'
ENTRYPOINT命令
docker container run
コマンドを実行した時に、ENTRYPOINTで指定したコマンドが実行される。
例)ENTRYPOINT nginx -g 'deamon off;'
CMDでコマンドを定義しても、docker container run
コマンド実行時に引数で新たなコマンドを指定した場合、そちらが優先実行される。
よって、ENTRYPOINTで指定したコマンドは必ずコンテナで実行されることになる。
コマンド引数を指定したいときはCMDと組み合わせる必要があり、ENTRYPOINTでコマンドを指定し、CMDでその引数を指定する。
例)ENTRYPOINT top
CMD -d 10
と定義すると、コマンドを指定しない場合は-d 10となる。docker container run -it sample
docker container run -it sample -d 2
ONBUILD命令
次のビルド時に実行するコマンドを指定することができる。
ONBUILDを記述したDockerfileでビルドしたイメージは、他のDockerfileでベースイメージとして設定してビルドされたときに実行される。
イメージにONBUILDが設定されているかどうかはdocker image inspect イメージ名
ですることが確認できる。
FROM ubuntu
ONBUILD ADD site.tar /var/www/htm/
としたDockerfileでdocker build -t web .
でイメージ作成。FROM web
としたDockerfileでdocker build -t web2 .
とするとONBUILDで指定したコマンドが実行される
EXPOSE命令
公開するポート番号を指定。
例)EXPOSE 8080
EXPOSEしなくてもdocker run -p
オプションでポートを外部公開できるので必要ない。
EXPOSEの指定はdocker run -P
もしくはDockerのlink機能を使ってコンテナ間連携をするときだけ意味を持つ。
ADD命令
ホストのファイルやディレクトリをイメージ内に追加する。
ただし、COPY命令でも同じことができるので、COPY命令を使うようにする。
ADD命令はリモートファイルのダウンロードやアーカイブの解凍などの機能を持つが、COPYは持たない。
よって、単純にイメージ内にファイルを配置したいときはCOPY命令を使う。
(ADD命令を使うと、リモートファイルやアーカイブが使われていると思わせてしまう)
ビルド時のファイル転送
Dockerは、ビルドを実行したディレクトリ配下の全ファイルをDockerデーモンに転送する。docker build
コマンドはDockerfileが置かれたディレクトリ配下をすべて転送する。
Dockerfileは空ディレクトリに置くのがおすすめ。
除外したいファイルがある場合は、.dockerignoreに除外ファイルを記述する。
VOLUME命令
マウントポイントを作成し、ホストOSや他のコンテナからマウントできるようにする。
例)VOLUME /var/log
コンテナは永続データを保持するのに適していない。
VOLUME命令でホストOSにマウントするとよい。
Docker Compose
複数のコンテナをまとめて管理するためのツール。
docker-compose.ymlにコンテナ構成情報を定義し、docker-composeコマンドを実行することで、コンテナを一括管理できる。
docker-compose.yml
services, networks, volumesを定義する。
バージョンによって記述可能項目が異なるため、先頭でversionを指定する。
バージョン指定がないと1.0として動作する。
version: '3.3'
services:
webserver:
build: .
ports:
- "80:80"
depend_on:
- redis
redis:
image: redis
# YAMLで配列を使用するときは先頭にハイフンと半角スペースを付ける
image
イメージの指定
例)image: ubuntu
build
Dockerfileからイメージのビルド。
例)build .
links
コンテナを他のサービスにリンクする。
コンテナ内の/etc/hostsの中にサービス名が追加される。
links:
- db
とすると/etc/hostsに以下の内容が追記される。
172.17.2.186 db
ports
コンテナが公開するポートの指定。
YAMLは数字のxx:yy形式を時刻と解釈するので、”ホストのポート:コンテナのポート”のように必ずダブルクォーテーションで囲む。
例)ports: - "8000:8000"
environment
環境変数の指定。
配列形式、またはハッシュ形式での記述が可能。
# 配列形式
environment:
- HOGE=fuga
# ハッシュ形式
HOGE: fuga
volumes
コンテナにボリュームをマウントする。
– ホストのパス:コンテナのパス
を記述する。
volumes:
- cache:/tmp/cache
複数コンテナの生成&起動
docker-compose up
-d:バックグラウンド
フォアグラウンドで起動した場合は、Ctrl+Cでコンテナ停止。
複数コンテナの確認
docker-compose ps
Composeで起動したコンテナでコマンド実行
docker-compose run コンテナ名 コマンド
例)docker-compose run web /bin/bash
複数コンテナの起動
docker-compose start
複数コンテナの停止
docker-compose stop
複数コンテナ・イメージの停止&削除
docker-compose down
実行中のコンテナを停止し、コンテナとネットワークを削除する。