Dockerfile常用指令

一. Dockerfile

Dockerfile可以理解为是 “专门用于构建镜像的shell脚本”,用户可以通过自定义 Dockerfile 内容来快速构建镜像。

二. Dockerfile指令说明

指令说明使用
FROM指定基础镜像FROM centos
MAINTAINER作者及邮箱author、email
RUN镜像构建中需要运行的命令RUN yum -y install vim
ADD将本地文件拷贝到镜像中,可以访问网络资源。如果跟的是一个远程文件url的话就会自动下载该文件并将其添加进目标路径下;如果是tar类型文件就会自动解压(网络压缩资源比如远程的tar文件,就不会被解压)ADD apache-tomcat-9.0.22.tar.gz /usr/local/ # 将tomcat解压到/usr/local/目录下
COPY功能类似ADD,但是不会自动解压文件,也不能访问网络资源COPY . /webapp # 把当前本地目录下的文件复制到镜像中的webapp目录下
ENV设置环境变量,这个值将出现在构建阶段中所有后续指令的环境中ENV MYPATH /usr/local
WORKDIR镜像的工作目录(如果没有这个目录会自动创建),可以有多个WORKDIRWORKDIR $MYPATH
VOLUME挂载的目录VOLUME [“volume01”, “volume02”] # 将容器内的两个目录挂在到宿主机
EXPOSE暴露容器的端口配置EXPOSE 9090
CMD指定这个容器启动的时候要运行的命令(只有最后一个会生效)见下文
EMTRYPOINT指定这个容器启动的时候要运行的命令,可以追加命令见下文

三. Dockerfile之CMD、ENTRYPOINT

3.1 CMD

  CMD:指定该容器启动时要运行的命令,如果在Dockerfile中有多条CMD指令,那么最后一条CMD指令会将之前的所有CMD指令覆盖掉;如果在命令行追加新命令时,新命令会把旧命令覆盖掉,也只有最后一个会生效。
我们来测试下CMD指令。

# 构建dockerfile文件
cat dockerfile_cmd

FROM centos
CMD echo "dockerfile_cmd test"
CMD ["ls", "-a"]

# 构建镜像
# 如果dockerfile文件名就叫"dockerfile",那么构建镜像的命令就不用加 -f 指定文件名 参数了,直接docker build -t ...
docker build -f dockerfile_cmd -t dockerfile_cmd:1.0 .
docker images

REPOSITORY       TAG       IMAGE ID       CREATED          SIZE
dockerfile_cmd   1.0       054062dfdeea   22 minutes ago   231MB
centos           latest    5d0da3dc9764   5 months ago     231MB

运行该镜像后,只打印出CMD的【“ls”, “-a”】命令。

docker run dockerfile_cmd:1.0

.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

我们尝试着启动时再加一些命令及参数,结果我们只看到了第二次新添加的指令生效了,Dockerfile中的 ls -a 并没有生效,说明了CMD指令是以最后一次为准。

docker run dockerfile_cmd:1.0 ls -l

total 0
lrwxrwxrwx   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root 340 Feb 28 13:05 dev
drwxr-xr-x   1 root root  66 Feb 28 13:05 etc
drwxr-xr-x   2 root root   6 Nov  3  2020 home
lrwxrwxrwx   1 root root   7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root   6 Sep 15 14:17 lost+found
drwxr-xr-x   2 root root   6 Nov  3  2020 media
drwxr-xr-x   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x 151 root root   0 Feb 28 13:05 proc
dr-xr-x---   2 root root 162 Sep 15 14:17 root
drwxr-xr-x  11 root root 163 Sep 15 14:17 run
lrwxrwxrwx   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x  13 root root   0 Feb 28 13:05 sys
drwxrwxrwt   7 root root 171 Sep 15 14:17 tmp
drwxr-xr-x  12 root root 144 Sep 15 14:17 usr
drwxr-xr-x  20 root root 262 Sep 15 14:17 var

可以理解为run命令行添加的指令替换了原Dockerfile中的CMD,所以run命令行的指令必须得是指令+参数的形式(ls -l,不能单单加个参数 -l),否则报错。

docker run 054062dfdeea -l

docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.

3.2 ENTRYPOINT

  ENTRYPOINT:指定该容器启动时要运行的命令,新的 ENTRYPOINT 指令也会将旧的覆盖掉。可以在docker run命令行追加命令参数,新添加的参数会追加到原dockerfile的ENTRYPOINT命令里。
接着测一下ENTRYPOINT指令。

# 构建dockerfile文件
cat dockerfile_entrypoint

FROM centos
ENTRYPOINT ["echo", "dockerfile-entrypoint test"]
ENTRYPOINT ["ls", "-a"]

# 构建镜像
docker build -f dockerfile_entrypoint -t dockerfile_entrypoint:1.0 .
docker images

REPOSITORY              TAG       IMAGE ID       CREATED          SIZE
dockerfile_entrypoint   1.0       1ce43408e0d2   42 minutes ago   231MB
dockerfile_cmd          1.0       054062dfdeea   4 hours ago      231MB
centos                  latest    5d0da3dc9764   5 months ago     231MB

运行该镜像后,同样也是输出【“ls”, “-a”】命令。

docker run dockerfile_entrypoint:1.0 

.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

我们尝试着再加一些参数,比如 -l,相当于在Dockerfile的ENTRYPOINT里追加了 -l 的参数,即【ls -a -l】。

docker run 1ce43408e0d2 -l

total 0
drwxr-xr-x   1 root root   6 Feb 28 15:51 .
drwxr-xr-x   1 root root   6 Feb 28 15:51 ..
-rwxr-xr-x   1 root root   0 Feb 28 15:51 .dockerenv
lrwxrwxrwx   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root 340 Feb 28 15:51 dev
drwxr-xr-x   1 root root  66 Feb 28 15:51 etc
drwxr-xr-x   2 root root   6 Nov  3  2020 home
lrwxrwxrwx   1 root root   7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root   6 Sep 15 14:17 lost+found
drwxr-xr-x   2 root root   6 Nov  3  2020 media
drwxr-xr-x   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x 152 root root   0 Feb 28 15:51 proc
dr-xr-x---   2 root root 162 Sep 15 14:17 root
drwxr-xr-x  11 root root 163 Sep 15 14:17 run
lrwxrwxrwx   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x  13 root root   0 Feb 28 13:05 sys
drwxrwxrwt   7 root root 171 Sep 15 14:17 tmp
drwxr-xr-x  12 root root 144 Sep 15 14:17 usr
drwxr-xr-x  20 root root 262 Sep 15 14:17 var

# 这样追加是错误的
docker run 1ce43408e0d2 ls -l

ls: cannot access 'ls': No such file or directory

3.3 如何使用

一般情况下,ENTRYPOINT和CMD都是互相配合使用的,即:ENTRYPOINT填写固定的命令,CMD填写该固定命令对应的参数,CMD将这个参数传递给ENTRYPOINT命令。可以理解为CMD参数为默认值,如果项目中使用的不是CMD的默认值,就可以在启动docker容器时添加上真实的参数值,用来覆盖CMD的默认值。

python-flask项目:

cat Dockerfile

FROM python:3.7-alpine
WORKDIR /code
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
ENTRYPOINT ["python"]
CMD ["app.py"]

可能项目中的启动文件不叫app.py,叫start.py,那么启动容器时就可以更新该参数:

docker run flask_app:1.0 start.py

java项目:

...其他指令
ENTRYPOINT ["java", "-jar"]
CMD ["cms.jar"]

启动容器时更换成项目中的jar包:

docker run java_app:1.0 startcms.jar

四. 查看镜像的变更历史

docker history 镜像id

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值