FROM
構文
FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]
こんなふうにつかう
FROM alpine:3.10.2
-
<image>
はいつもDocker Hubで検索。 - いつも使うときは
[AS <name>]
alias指定しないが、以前つかったMulti Stage Build使うときなんかは有効につかえるのかもしれないです。 -
[@<digest>]
僕は使ったことないです -
[:<tag>]
ここでlatest
タグとかを指定してしまうと、予期せぬバージョンアップをしてしまう可能性があるので、3.10.2
みたいにちゃんと指定します。(僕は
$ docker build ./
[+] Building 3.6s (5/5) FINISHED
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 60B 0.0s
=> [internal] load metadata for docker.io/library/alpine:3.10.2 3.4s
=> [1/1] FROM docker.io/library/alpine:3.10.2@sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb 0.0s
=> => resolve docker.io/library/alpine:3.10.2@sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb 0.0s
=> exporting to image 0.0s
=> => exporting layers
RUN
構文
RUN <command>
こんなふうにつかう
RUN apt-get update -y \
&& apt-get upgrade -y
-
RUN
を何行も書くのではなくて、できるだけ&&
でつなげてRUN
を少なくします。 -
\
バックスラッシュで改行できます。
$ docker build ./
[+] Building 36.4s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 111B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:18.04 0.0s
=> CACHED [1/2] FROM docker.io/library/ubuntu:18.04 0.0s
=> [2/2] RUN apt-get update -y && apt-get upgrade -y 36.1s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:da252f0bce2992272e6081bb332b851ce7e3926034bc8b1d810fe6c25a3cc153
LABEL
構文
LABEL <key>=<value> <key>=<value> <key>=<value> ...
こんなふうにつかう
LABEL vender="SORICH" \
com.example.image-specs="{\"Description\":\"Dockerfileのいろいろ\", \"Version\":\"1.0.0-test\", \"Author\":\"yuya.sega\"}"
- 様々な用途で利用できるメタデータを追加することが可能です。
- json形式のデータも設定できます。
-
docker inspect
コマンドで設定内容を確認できる。 -
docker ps
で検索項目としても使えます。
inspectで確認
$ docker inspect dockertest
~~ 略 ~~
"Config": {
"Labels": {
"com.example.image-specs": "{\"Description\":\"Dockerfileのいろいろ\", \"Version\":\"1.0.0-test\", \"Author\":\"yuya.sega\"}",
"vendor": "SORICH"
}
~~ 略 ~~
filter使って絞り込み
$ docker ps -a --filter "label=vendor=SORICH"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1596b7d38241 dockertest "/bin/bash" 6 seconds ago Exited (0) 5 seconds ago dreamy_vaughan
ENV
構文
ENV <key> <value>
ENV <key>=<value> ...
こんなふうにつかう
ENV test=hoge
- Dockerfileからコンテナ内環境変数に値を設定できます。
$ docker run -it dockertest
root@9f53f8763f80:/# echo $test
hoge
root@9f53f8763f80:/#
ADD
構文
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
こんなふうにつかう
ADD test.txt .
ADD hoge/ .
ADD test.* ./test/
- ファイル、ディレクトリ、ネットワーク上のファイルをコピーして、イメージに追加できます。
- ワイルドカード
*
が利用できます。 - ファイルまたはディレクトリの所有者とグループを指定して追加できます。
-
src
にディレクトリを指定するとディレクトリはコピーされず、その中身だけをコピーしてイメージに追加します。
build時
$ docker build -f ./Dockerfile ./ -t dockertest
~~ 略 ~~
=> [3/5] ADD test.txt . 0.0s
=> [4/5] ADD hoge/ . 0.0s
=> [5/5] ADD test.* ./test/ 0.1s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:7306fd2eec1237542d214f7915cfdeade216bf09189add8c5659f8298c1be297 0.0s
=> => naming to docker.io/library/dockertest
ADDされたファイルをみる
$ docker run -it dockertest
root@6d7514db6073:/# ls -la
-rw-r--r-- 1 root root 0 Oct 2 07:57 fuga.txt
drwxr-xr-x 2 root root 4096 Oct 2 07:35 test
-rw-r--r-- 1 root root 8 Oct 2 07:33 test.txt
COPY
構文
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
こんなふうにつかう
COPY test.txt .
COPY hoge/ .
COPY test.* ./test/
- ファイル、ディレクトリをコピーしてイメージに追加できます。(ADDはリモートファイルをsrcに指定できますが、COPYはできません。)
- ワイルドカード
*
が利用できます。 - ファイルまたはディレクトリの所有者とグループを指定して追加できます。
-
src
にディレクトリを指定するとディレクトリはコピーされず、その中身だけをコピーしてイメージに追加します。
build時
~~ 略 ~~
=> [3/5] COPY test.txt . 0.1s
=> [4/5] COPY hoge/ . 0.1s
=> [5/5] COPY test.* ./test/ 0.1s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:82c9033b151ec5f88d0966bf4c54bba9f8714e9daea2f13f105fb142f6c2f66b 0.0s
=> => naming to docker.io/library/dockertest
COPYされたファイルをみる
$ docker run -it dockertest
root@0024967f1e8a:/# ls -la
-rw-r--r-- 1 root root 0 Oct 2 07:57 fuga.txt
drwxr-xr-x 2 root root 4096 Oct 2 08:14 test
-rw-r--r-- 1 root root 8 Oct 2 07:33 test.txt
EXPOSE
構文
EXPOSE <port> [<port>/<protocol>...]
こんなふうにつかう
EXPOSE 80/tcp
- コンテナーが実行時に指定されたネットワークポートでリッスンすることをDockerに通知します。
-
EXPOSE
は実際にはポートを公開しません。一種のドキュメントとして利用されます。 - 実際にポートを公開する場合は、
docker run -p 80:80/tcp
として、公開します。
$ docker run -it -p 80:80 dockertest
ENTRYPOINT
構文
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
こんなふうにつかう
ENTRYPOINT [ "ls", "-la" ]
- コンテナ内でコマンドの実行や、一つのプロセスを実行することが可能です。
- json形式で指定する方法だと、
/bin/sh -c
(シェル)を介さずにコマンドを実行する。 -
ENTRYPOINT command param1 param2
この形式で指定すると、/bin/sh -c
(シェル)を介してコマンドを実行する。 -
docker run --entrypoint
でENTRYPOINT
を上書きできる。 -
CMD
に渡されたコマンドを引数として実行できる。
runしてみる
$ docker run -it dockertest
total 72
drwxr-xr-x 1 root root 4096 Oct 2 09:11 .
drwxr-xr-x 1 root root 4096 Oct 2 09:11 ..
-rwxr-xr-x 1 root root 0 Oct 2 09:11 .dockerenv
drwxr-xr-x 1 root root 4096 Oct 2 08:30 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 boot
drwxr-xr-x 5 root root 360 Oct 2 09:11 dev
drwxr-xr-x 1 root root 4096 Oct 2 09:11 etc
drwxr-xr-x 2 root root 4096 Apr 24 2018 home
drwxr-xr-x 1 root root 4096 May 23 2017 lib
drwxr-xr-x 2 root root 4096 Sep 12 20:53 lib64
drwxr-xr-x 2 root root 4096 Sep 12 20:53 media
drwxr-xr-x 2 root root 4096 Sep 12 20:53 mnt
drwxr-xr-x 2 root root 4096 Sep 12 20:53 opt
dr-xr-xr-x 187 root root 0 Oct 2 09:11 proc
drwx------ 2 root root 4096 Sep 12 20:54 root
drwxr-xr-x 1 root root 4096 Sep 18 23:20 run
drwxr-xr-x 1 root root 4096 Oct 2 08:30 sbin
drwxr-xr-x 2 root root 4096 Sep 12 20:53 srv
dr-xr-xr-x 13 root root 0 Oct 2 07:48 sys
drwxrwxrwt 1 root root 4096 Oct 2 08:31 tmp
drwxr-xr-x 1 root root 4096 Sep 12 20:53 usr
drwxr-xr-x 1 root root 4096 Sep 12 20:54 var
$
docker docsにも木脚がありますが、実践的に考えると、以下のようにDockerfileを記述するケースが多いです。
FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
CMD
構文
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
こんなふうにつかう
CMD [ "ls", "-la" ]
- Dockerfileの中で1度しか命令することができません。
- やれることは
ENTRYPOINT
とほぼ一緒ですが、CMD
ではENTRYPOINT
に対してデフォルト引数を渡すことが可能です。 -
docker run
で引数を渡すとCMD
を上書きできます。docker run dockertest ls
のような感じ。
runしてみる
$ docker run -it dockertest
total 72
drwxr-xr-x 1 root root 4096 Oct 2 09:31 .
drwxr-xr-x 1 root root 4096 Oct 2 09:31 ..
-rwxr-xr-x 1 root root 0 Oct 2 09:31 .dockerenv
drwxr-xr-x 1 root root 4096 Oct 2 08:30 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 boot
drwxr-xr-x 5 root root 360 Oct 2 09:31 dev
drwxr-xr-x 1 root root 4096 Oct 2 09:31 etc
drwxr-xr-x 2 root root 4096 Apr 24 2018 home
drwxr-xr-x 1 root root 4096 May 23 2017 lib
drwxr-xr-x 2 root root 4096 Sep 12 20:53 lib64
drwxr-xr-x 2 root root 4096 Sep 12 20:53 media
drwxr-xr-x 2 root root 4096 Sep 12 20:53 mnt
drwxr-xr-x 2 root root 4096 Sep 12 20:53 opt
dr-xr-xr-x 184 root root 0 Oct 2 09:31 proc
drwx------ 2 root root 4096 Sep 12 20:54 root
drwxr-xr-x 1 root root 4096 Sep 18 23:20 run
drwxr-xr-x 1 root root 4096 Oct 2 08:30 sbin
drwxr-xr-x 2 root root 4096 Sep 12 20:53 srv
dr-xr-xr-x 13 root root 0 Oct 2 07:48 sys
drwxrwxrwt 1 root root 4096 Oct 2 08:31 tmp
drwxr-xr-x 1 root root 4096 Sep 12 20:53 usr
drwxr-xr-x 1 root root 4096 Sep 12 20:54 var
$
CMDを上書きします。
$ docker run -it dockertest ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
$
USER
構文
USER <user>[:<group>]
USER <UID>[:<GID>]
こんなふうにつかう
USER test
- イメージを実行するときに使用するユーザーを変更できます。
- Dockerfile内で
USER
以降にかかれている、RUN
命令等は、USER
で指定したユーザーを使用してコマンドなどが実行されます。 -
USER
に指定したユーザーがイメージ内に存在しない場合は、エラーでbuild
が失敗したり、run
に失敗したりします。
runしてみる
RUN useradd test
USER test
$ docker run -it dockertest
test@b1f6fcd27d9e:/$
test@
となってるので、testユーザーに変更されていると確認できました。
WORKDIR
構文
WORKDIR /path/to/workdir
こんなふうにつかう
WORKDIR /var/log
- 作業ディレクトリを変更します。
-
RUN
、CMD
、ENTRYPOINT
、COPY
、ADD
の命令は、WORKDIR
命令で指定されたディレクトリで実行されます。
build時
$ docker build ./ -t dockertest
~~ 略 ~~
=> [3/3] WORKDIR /var/log 0.1s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:3b2cce535d94fb8115593d73fc1eb830fd3ec431be0e94f053365b600a9e28d7 0.0s
=> => naming to docker.io/library/dockertest
runしてみる
$ docker run -it --rm dockertest
root@913f5e90261b:/var/log# pwd
/var/log
root@913f5e90261b:/var/log#
Tips
今回、動作検証していくうえで、docker
コマンドを多用したのですが、使えるコマンドがいくつもあったので、簡単にのせてきます。
docker run --rm
docker run
しまくってると、コンテナがいくつもできてしまっていちいちdocker rm
するのが面倒だったので、以下のように実行してました。
$ docker run -it --rm dockertest
docker image rm $(docker image ls --filter "dangling=true" -aq)
docker images
すると、のimageが多数できててディスク圧迫しちゃってたので、一括削除でこのコマンド使ってました。
docker image rm $(docker image ls --filter "dangling=true" -aq)
docker build ./ -t <名前:タグ>
docker build
時に名前を付けないと、run
したりするのが面倒だったので、-t
オプションで名前付けてました。
本記事内ではdocker build ./ -t dockertest
として実行しており、タグを省略してましたが、省略時はlatest
としてタグが作成されます。(docker build ./ -t dockertest:latest
とおなじになる)
さいごに
まだまだ、Docker Docsに記述があっても、かけてない命令がいくつかあるので、随時更新していこうと思っているので、宜しくお願いします。
また、これ以上にいい使い方や、裏技などあれば、是非コメントいただきたいです。