本記事は、Docker Advent Calendar 2015 の12月6日の記事になります。
概要
Dockerfile にCMD
とENTRYPOINT
ってあるけどなにが違うのか調査とそのメモ
環境
- OS : cent7.1
cat /etc/redhat-release
# CentOS Linux release 7.1.1503 (Core)
- docker : 1.9.0
[root@docker-engine /]# docker version
# Client:
# Version: 1.9.0
# API version: 1.21
# Go version: go1.4.2
# Git commit: 76d6bc9
# Built: Tue Nov 3 18:00:05 UTC 2015
# OS/Arch: linux/amd64
# Server:
# Version: 1.9.0
# API version: 1.21
# Go version: go1.4.2
# Git commit: 76d6bc9
# Built: Tue Nov 3 18:00:05 UTC 2015
# OS/Arch: linux/amd64
※ install はこちらを参照
Dockerfile
- 今回の主なDockerfile はこちらになります。
これにCMD
やENTRYPOINT
を追記して試します。
FROM ubuntu
MAINTAINER hihihiroro
CMD
とENTRYPOINT
- docker image からdocker container を実行するときに
CMD
やENTRYPOINT
の記述内容が実行されます。 - 1つのDockerfile に
CMD
、ENTRYPOINT
は1度のみ。
※ 複数記載されている場合、最後の1個が実行される。
agenda
- CMD について
- CMD ["command"]
- CMD command
- CMD 上書き
- ENTRYPOINT について
- ENTRYPOINT ["command"]
- ENTRYPOINT command
- ENTRYPOINT 上書き?
- CMD とENTRYPOINT の併用について
CMD
CMD ["command"]
FROM ubuntu
MAINTAINER hihihiroro
CMD ["ping","127.0.0.1","-c","100"]
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 37.89 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Using cache
# ---> 5b349e87daf9
# Step 3 : CMD ping 127.0.0.1 -c 100
# ---> Running in 401e07b7dca7
# ---> 0ac2c0ea0e28
# Removing intermediate container 401e07b7dca7
# Successfully built 0ac2c0ea0e28
run
[root@localhost ~]# docker run test
# PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
# 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.033 ms
# 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.040 ms
# 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.034 ms
# ...
プロセス確認
root@0b2a435c091b:/# ps auxf
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 6 0.6 0.0 18136 1864 ? Ss 06:00 0:00 /bin/bash
# root 19 0.0 0.0 15560 1104 ? R+ 06:00 0:00 \_ ps auxf
# root 1 0.2 0.0 6500 612 ? Ss 06:00 0:00 ping 127.0.0.1 -c 100
ping
が実行されていることが分かります。
シェルを介さずに実行されていることが分かります。
CMD command
FROM ubuntu
MAINTAINER hihihiroro
CMD ping 127.0.0.1 -c 100
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 37.89 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Running in 7d6a1adc76ee
# ---> 03615a451ecf
# Removing intermediate container 7d6a1adc76ee
# Step 3 : CMD ping 127.0.0.1 -c 100
# ---> Running in c304f24111ab
# ---> dea31bd0fe0f
# Removing intermediate container c304f24111ab
# Successfully built dea31bd0fe0f
run
[root@localhost ~]# docker run test
# PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
# 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.033 ms
# 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.040 ms
# 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.034 ms
# ...
プロセス確認
root@b86ea4cdcd54:/# ps auxf
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 7 0.4 0.0 18136 1860 ? Ss 06:04 0:00 /bin/bash
# root 20 0.0 0.0 15560 1100 ? R+ 06:04 0:00 \_ ps auxf
# root 1 0.2 0.0 4440 628 ? Ss 06:04 0:00 /bin/sh -c ping 127.0.0.1 -c 100
# root 6 0.0 0.0 6500 624 ? S 06:04 0:00 ping 127.0.0.1 -c 100
ping
が実行されていることが分かります。
/bin/sh -c
の引数としてコマンドが実行されていることが分かります。
CMD 上書き
FROM ubuntu
MAINTAINER hihihiroro
CMD ping 127.0.0.1 -c 100
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 37.89 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Running in 7d6a1adc76ee
# ---> 03615a451ecf
# Removing intermediate container 7d6a1adc76ee
# Step 3 : CMD ping 127.0.0.1 -c 100
# ---> Running in c304f24111ab
# ---> dea31bd0fe0f
# Removing intermediate container c304f24111ab
# Successfully built dea31bd0fe0f
run
[root@localhost ~]# docker run test cat /etc/lsb-release
# DISTRIB_ID=Ubuntu
# DISTRIB_RELEASE=14.04
# DISTRIB_CODENAME=trusty
# DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"
ping
ではなく、docker run
時につけた引数のcat /etc/lsb-release
が実行されていることが分かります。
CMD
はこのように、docker run
時にコマンドの上書きが可能になります。
ENTRYPOINT
ENTRYPOINT ["command"]
FROM ubuntu
MAINTAINER hihihiroro
ENTRYPOINT ["ping","127.0.0.1","-c","100"]
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 37.89 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Running in 4bd4f60f6a50
# ---> 2ffc6e2fdd8a
# Removing intermediate container 4bd4f60f6a50
# Step 3 : ENTRYPOINT ping 127.0.0.1 -c 100
# ---> Running in 173206d72cb6
# ---> e5b47e6740cd
# Removing intermediate container 173206d72cb6
# Successfully built e5b47e6740cd
run
[root@localhost ~]# docker run test
# PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
# 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.025 ms
# 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.034 ms
# 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.029 ms
# ...
プロセス確認
root@124425f5edd0:/# ps auxf
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 6 0.4 0.0 18136 1864 ? Ss 06:33 0:00 /bin/bash
# root 19 0.0 0.0 15560 1104 ? R+ 06:33 0:00 \_ ps auxf
# root 1 0.1 0.0 6500 604 ? Ss 06:33 0:00 ping 127.0.0.1 -c 100
ping
が実行されていることが分かります。
シェルを介さずに実行されていることが分かります。
ENTRYPOINT command
FROM ubuntu
MAINTAINER hihihiroro
ENTRYPOINT ping 127.0.0.1 -c 100
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 37.89 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Running in 8679d9b8120c
# ---> bdc1d6d8e004
# Removing intermediate container 8679d9b8120c
# Step 3 : ENTRYPOINT ping 127.0.0.1 -c 100
# ---> Running in ec29024e6074
# ---> 3963c62c7464
# Removing intermediate container ec29024e6074
# Successfully built 3963c62c7464
run
[root@localhost ~]# docker run test
# PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
# 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.030 ms
# 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.031 ms
# 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.028 ms
# ...
プロセス確認
root@7d8390b4e1f4:/# ps auxf
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 7 1.0 0.0 18136 1856 ? Ss 06:37 0:00 /bin/bash
# root 20 0.0 0.0 15560 1104 ? R+ 06:37 0:00 \_ ps auxf
# root 1 0.2 0.0 4440 632 ? Ss 06:37 0:00 /bin/sh -c ping 127.0.0.1 -c 100
# root 6 0.0 0.0 6500 632 ? S 06:37 0:00 ping 127.0.0.1 -c 100
ping
が実行されていることが分かります。
/bin/sh -c
の引数としてコマンドが実行されていることが分かります。
ENTRYPOINT 上書き?
FROM ubuntu
MAINTAINER hihihiroro
ENTRYPOINT ping 127.0.0.1 -c 100
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 37.89 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Running in 2f72cd03c162
# ---> dd99c6e04b1a
# Removing intermediate container 2f72cd03c162
# Step 3 : ENTRYPOINT ping 127.0.0.1 -c 100
# ---> Running in 449d1f1b2280
# ---> 61277c329249
# Removing intermediate container 449d1f1b2280
# Successfully built 61277c329249
run
[root@localhost ~]# docker run test cat /etc/lsb-release
# PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
# 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.028 ms
# 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.053 ms
# 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.032 ms
# ...
CMD
とは違い、docker run
時につけた引数のcat /etc/lsb-release
ではなく、ENTRYPOINT
で指定されているping
が実行されていることが分かります。
ENTRYPOINT
はCMD
と違い、docker run
時にコマンドの上書きができません。
※ docker run --entrypoint=""
で上書きはすることが可能です。
CMD とENTRYPOINT の併用について
引数なし
FROM ubuntu
MAINTAINER hihihiroro
ENTRYPOINT ["ping"]
CMD ["127.0.0.1", "-c", "50"]
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 39.42 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Running in 33a067cc7f3e
# ---> 57ff677a0cca
# Removing intermediate container 33a067cc7f3e
# Step 3 : ENTRYPOINT ping
# ---> Running in 2957c1b4f09e
# ---> 3c30112fe595
# Removing intermediate container 2957c1b4f09e
# Step 4 : CMD 127.0.0.1 -c 50
# ---> Running in 09f1cff264bd
# ---> c7160151ed57
# Removing intermediate container 09f1cff264bd
# Successfully built c7160151ed57
run
[root@localhost ~]# docker run test
# PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
# 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.024 ms
# 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.033 ms
# 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.031 ms
# ...
プロセス確認
root@23a769d5c382:/# ps auxf
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 6 1.0 0.0 18136 1860 ? Ss 07:16 0:00 /bin/bash
# root 19 0.0 0.0 15560 1100 ? R+ 07:16 0:00 \_ ps auxf
# root 1 0.2 0.0 6500 632 ? Ss 07:16 0:00 ping 127.0.0.1 -c 50
ENTRYPOINT
で指定したping
にCMD
で指定した127.0.0.1 -c 50
が引数として実行されています。
引数あり
FROM ubuntu
MAINTAINER hihihiroro
ENTRYPOINT ["ping"]
CMD ["127.0.0.1", "-c", "50"]
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 39.42 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Running in 33a067cc7f3e
# ---> 57ff677a0cca
# Removing intermediate container 33a067cc7f3e
# Step 3 : ENTRYPOINT ping
# ---> Running in 2957c1b4f09e
# ---> 3c30112fe595
# Removing intermediate container 2957c1b4f09e
# Step 4 : CMD 127.0.0.1 -c 50
# ---> Running in 09f1cff264bd
# ---> c7160151ed57
# Removing intermediate container 09f1cff264bd
# Successfully built c7160151ed57
run
[root@localhost ~]# docker run test localhost
# PING localhost (127.0.0.1) 56(84) bytes of data.
# 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.027 ms
# 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.037 ms
# 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.029 ms
# ...
プロセス確認
root@947cf9dfb3c1:/# ps auxf
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 6 1.3 0.0 18136 1864 ? Ss 07:26 0:00 /bin/bash
# root 19 0.0 0.0 15560 1104 ? R+ 07:26 0:00 \_ ps auxf
# root 1 0.3 0.0 8596 832 ? Ss 07:26 0:00 ping localhost
ENTRYPOINT
で指定したping
に引数のlocalhost
がCMD
で指定した127.0.0.1 -c 50
を上書きして実行しています。
まとめ
共通点
-
docker run
時に実行されるコマンドです。 -
docker run
時に引数を渡すとコマンドを上書きできます。
※ENTRYPOINT
は--entrypoint
オプションが必要です。
差分
-
CMD
はdocker run
時の引数でCMD command
、CMD ["command"]
のcommand
分をまるっと上書きして実行されます。 -
ENTRYPOINT
はdocker run
時の引数がENTRYPOINT ["command"]
のcommand
の引数として実行されます。
併用
-
ENTRYPOINT
とCMD
の両方が書いてある場合には、CMD
に書かれている内容が、ENTRYPOINT
に書いてあるcommand
のオプションとして実行されます。 -
docker run
時に引数をつけた場合、CMD
の内容が上書きされENTRYPOINT
に書いてあるcommand
が実行されます。
残作業
FROM ubuntu
MAINTAINER hihihiroro
ENTRYPOINT ping -c 50
build
[root@localhost ~]# docker build -t test .
# Sending build context to Docker daemon 39.42 kB
# Step 1 : FROM ubuntu
# ---> e9ae3c220b23
# Step 2 : MAINTAINER hihihiroro
# ---> Running in 403dff6b0a29
# ---> a3be8411fe60
# Removing intermediate container 403dff6b0a29
# Step 3 : ENTRYPOINT ping -c 50
# ---> Running in 98beb40ba98d
# ---> f7d65704e8bc
# Removing intermediate container 98beb40ba98d
# Successfully built f7d65704e8bc
run
[root@localhost ~]# docker run test 127.0.0.1
# Usage: ping [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
# [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
# [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
# [-w deadline] [-W timeout] [hop1 ...] destination
-
ENTRYPOINT ["command"]
の際にはdocker run
時の引数をcommand
の引数に付けて実行してくれるが、ENTRYPOINT command
の際には引数を付けてくれない。