Dockerfile

一、基本结构

Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 快速创建自定义镜像。

Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。

Docker分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时默认要执行的指令

例如:

# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: seancheng
# Command format: Instruction [arguments / command] ...

# 第一行必须指定基于的基础镜像
FROM ubuntu

# 维护者信息
LABEL MAINTAINER='seancheng xianshangxian@126.com'

# 镜像操作指令
RUN echo "deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

# 容器启动时默认要执行的指令
CMD /usr/sbin/nginx

其中,一开始必须指明所基于的镜像名称,接下来一般会说明维护者信息。

后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一层,并提交。

最后是CMD指令来指定运行容器时的操作指令。

二、指令

指令的一般格式为INSTRUCTION arguments,指令包括:

指令名字 作用
FROM 基础镜像,一切从这里开始构建
MAINTAINER 镜像是谁写的,姓名+邮箱
RUN 镜像构建的时候需要运行的命
ADD 提供安装包位置
WORKDIR 镜像的工作目录
VOLUME 挂载的目录
EXPOSE 暴露端口配置
CMD 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD 当构建一个被继承 Dockerfile 这个时候就会运行ONBUILD 的指令
COPY 类似ADD,将我们文件拷贝到镜像中
ENV 构建的时候设置环境变量

2.1 FROM

格式为FROM <image>FROM <image>:<tag>

第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。

FROM centos:8(默认是最新版本)

2.2 LABEL MAINTAINER(维护者)

格式为LABEL MAINTAINER <name email_address>,指定维护者信息

用户名字+邮箱

LABEL MAINTAINER='amu 123@qq.com'

2.3 RUN

格式为RUN <command>RUN ["executable","param1","param2"]

前者将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行。指定使用其他终端可以通过第二种方式实现,例如:

[root@localhost ~]# mkdir test
[root@localhost ~]# cd test/
[root@localhost test]# cat Dockerfile 
FROM centos

RUN mkdir abc

[root@localhost test]# docker build -t test:v0.1 /root/test/
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : RUN mkdir abc
 ---> Running in 1cc3cd5aa69d
Removing intermediate container 1cc3cd5aa69d
 ---> 37ec05f5a1ac
Successfully built 37ec05f5a1ac
Successfully tagged test:v0.1

[root@localhost test]# docker run -it --rm test:v0.1
[root@95d5cf5be279 /]# ls
abc  etc   lib64       mnt   root  srv  usr
bin  home  lost+found  opt   run   sys  var
dev  lib   media       proc  sbin  tmp

[root@localhost test]# cat Dockerfile 
FROM centos

RUN ["/usr/bin/mkdir","-p","/hehe/xixi/haha"]

[root@localhost test]# docker build -t test:v0.2 /root/test/
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : RUN ["/usr/bin/mkdir","-p","/hehe/xixi/haha"]
 ---> Running in 36392aa44fb9
Removing intermediate container 36392aa44fb9
 ---> baf7fce2f1d7
Successfully built baf7fce2f1d7
Successfully tagged test:v0.2

[root@localhost test]# docker run -it --rm test:v0.2
[root@4d9d5dfddfc7 /]# ls
bin  hehe  lib64       mnt   root  srv  usr
dev  home  lost+found  opt   run   sys  var
etc  lib   media       proc  sbin  tmp
[root@4d9d5dfddfc7 /]# cd hehe/
[root@4d9d5dfddfc7 hehe]# ls xixi/
haha

每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行,例如:

[root@localhost test]# cat Dockerfile
FROM centos

RUN echo "hello world\nhello tom" > /tmp/abc && \
    cat /tmp/abc

2.4 CMD

CMD支持三种格式:

  • CMD ["executable","param1","param2"]使用exec执行,推荐方式
  • CMD command param1 param2在/bin/sh中执行,提供给需要交互的应用
  • CMD ["param1","param2"]提供给ENTRYPOINT的默认参数

CMD用于指定启动容器时默认要执行的命令,如果docker run没有指定任何的执行命令或者dockerfile里面也没有ENTRYPOINT,那么就会使用执行CMD指定的默认的命令

每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。

// 使用CMD第二种格式
[root@localhost test]# cat Dockerfile 
FROM centos

CMD sleep 600	// 当CMD只有这一条的时候就执行当前命令

[root@localhost test]# docker build -t test:v0.4 /root/test
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : CMD sleep 600
 ---> Running in c8334041d0d8
Removing intermediate container c8334041d0d8
 ---> 04b29b18007f
Successfully built 04b29b18007f
Successfully tagged test:v0.4

[root@localhost test]# docker run -itd --rm test:v0.4
e332f6d2b7e49bfd1b536ba8d4c2dd8fa2473b84b2fd33280ba5d503b493f429
[root@localhost test]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS     NAMES
e332f6d2b7e4   test:v0.4   "/bin/sh -c 'sleep 6…"   3 seconds ago   Up 2 seconds             trusting_chaplygin


[root@localhost test]# cat Dockerfile 
FROM centos

CMD sleep 600
CMD sleep 700
CMD sleep 800 		// 当CMD有三条的时候,只会执行最后一条命令

[root@localhost test]# docker build -t test:v0.5 /root/test/
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 5d0da3dc9764
Step 2/4 : CMD sleep 600
 ---> Using cache
 ---> 04b29b18007f
Step 3/4 : CMD sleep 700
 ---> Running in 0894d1cb0ee8
Removing intermediate container 0894d1cb0ee8
 ---> c8dc64c9276e
Step 4/4 : CMD sleep 800
 ---> Running in a8d504b7b9b1
Removing intermediate container a8d504b7b9b1
 ---> a1bb66d8c5d2
Successfully built a1bb66d8c5d2
Successfully tagged test:v0.5

[root@localhost test]# docker run -itd --rm test:v0.5
f95fb66e5c16a446984a2e88648a85465deb7569e82664997eebc7dad960064d
[root@localhost test]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS     NAMES
f95fb66e5c16   test:v0.5   "/bin/sh -c 'sleep 8…"   2 seconds ago   Up 2 seconds             vigorous_ritchie

如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。

[root@localhost test]# docker images
[root@localhost test]# cat Dockerfile 
FROM centos

CMD ["sleep","400"]
[root@localhost test]# docker build -t test:v0.8 /root/test/
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : CMD ["sleep","400"]
 ---> Running in faffd15f9944
Removing intermediate container faffd15f9944
 ---> 0c1864ac64c6
Successfully built 0c1864ac64c6
Successfully tagged test:v0.8

// 没有覆盖是这样的
[root@localhost test]# docker run -itd --rm test:v0.8
b4e6f4625d04b824cf7dc324c50ef603c31e3366464006bc067ba9b5a4a7288d
[root@localhost test]# docker ps
CONTAINER ID   IMAGE       COMMAND       CREATED         STATUS         PORTS     NAMES
b4e6f4625d04   test:v0.8   "sleep 400"   5 seconds ago   Up 4 seconds             strange_chandrasekhar
[root@localhost test]# docker rm -f b4e6f4625d04
b4e6f4625d04

// 覆盖之后 sleep 400 变成 /bin/bash
[root@localhost test]# docker run -itd --rm test:v0.8 /bin/bash
fbf0ec0e58fdf49358aca74efd2575464724fef5afa15890cc93193916016e65
[root@localhost test]# docker ps
CONTAINER ID   IMAGE       COMMAND       CREATED         STATUS         PORTS     NAMES
fbf0ec0e58fd   test:v0.8   "/bin/bash"   5 seconds ago   Up 4 seconds             naughty_albattani

使用CMD第一种格式在前台运行httpd(推荐使用这种格式)

[root@localhost test]# cat Dockerfile 
FROM centos

RUN ["/usr/bin/dnf","-y","install","httpd"]

CMD ["/usr/sbin/httpd","-D","FOREGROUND"]

[root@localhost test]# docker build -t test:v0.7 /root/test/
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 5d0da3dc9764
Step 2/3 : RUN ["/usr/bin/dnf","-y","install","httpd"]
 ---> Using cache
 ---> e044e1eda4ef
Step 3/3 :
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值