[docker]八、Dockerfile指令详解

目录

1、详解Dockerfile制作镜像之——命令讲解

2、RUN和FROM

2.1、set 

3、CMD

3.1、ENTRYPOINT

3.2.、ENTRYPONIT和CMD的区别

3.3、HEALTHCHECK

4、VOLUME

5、ENV

5.1、ARG(argument)

 6、STOPSIGNAL

7、制作镜像练习


1、详解Dockerfile制作镜像之——命令讲解

参考资料:

Dockerfile reference | Docker Documentation

Docker run 命令 | 菜鸟教程

当查找Dockerfile文件的时候,若是我们不在那个路径当中,我们可以使用"docker run -f /path/tp/a/Dockerfile .",使用绝对路径找到那个Dockerfile。

2、RUN和FROM

FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

RUN:用于执行后面跟着的命令行命令。有以下俩种格式:

  • shell 格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
  • exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos
RUN yum -y install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

注意:在shell编程中,若是使用"\"执行命令的时候,不管前边命令执行与否都会执行后边的。"&&"则不是这样的,若是前边命令执行失败,后边的命令就不会执行了。

2.0.1、会增加层数的命令

  • RUN
  • COPY
  • ADD

2.1、set 

我们注意到RUN的时候,会出现set这个命令,那么这个命令是用来干什么的呢?

语法:

set [+-abCdefhHklmnpPtuvx]

部分参数说明:

  • -e  若指令传回值不等于0,则立即退出shell。
  • -u  当执行时使用到未定义过的变量,则显示错误信息。
  • -x  执行指令后,会先显示该指令及所下的参数。

[演示]

# -e,若指令传回值不等于0,则立即退出shell。
[root@centos7-docker ~]# set -e
[root@centos7-docker ~]# ls
anaconda-ks.cfg  getting-started  lianxi
[root@centos7-docker ~]# dfjlsk  # 这个命令出错了,就直接退出了shell
-bash: dfjlsk: 未找到命令

Connection closed.

Disconnected from remote host(centos7-docker) at 10:54:59.

Type `help' to learn how to use Xshell prompt.
[C:\~]$ 

# 所以set -e,就是为了弥补\的机制,即前边的命令执行失败,后边的命令还是会执行。使用了之后,命令执行失败就直接退出shell

# -x,执行指令后,会先显示该指令及所下的参数。
[root@centos7-docker ~]# set -ex
++ printf '\033]0;%s@%s:%s\007' root centos7-docker '~'
[root@centos7-docker ~]# ls
+ ls --color=auto
anaconda-ks.cfg  getting-started  lianxi
++ printf '\033]0;%s@%s:%s\007' root centos7-docker '~'

# -u,当执行时使用到未定义过的变量,则显示错误信息。
[root@centos7-docker ~]# set -eux
++ printf '\033]0;%s@%s:%s\007' root centos7-docker '~'
[root@centos7-docker ~]# echo $fan
-bash: fan: 为绑定变量

Connection closed.

Disconnected from remote host(centos7-docker) at 11:00:15.

Type `help' to learn how to use Xshell prompt.
[C:\~]$ 

3、CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

  • CMD 在docker run 时运行。镜像制作完成,启动容器使用镜像的时候执行的,容器启动后执行的命令。
  • RUN 是在 docker build。在制作镜像的过程中执行的,可以RUN很多命令。但是能用一个RUN就用一个RUN,避免增加不必要的层数。

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

格式:

CMD <shell 命令> 
CMD ["<可执行文件或命令>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]  # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。

3.1、ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

格式1:Theexecform, which is the preferred form,推荐使用的格式

ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

格式2:Theshellform:

ENTRYPOINT command param1 param2

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。

示例:

假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 

1、不传参运行

$ docker run  nginx:test

容器内会默认运行以下命令,启动主进程。

nginx -c /etc/nginx/nginx.conf

2、传参运行

$ docker run  nginx:test -c /etc/nginx/new.conf

容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)

nginx -c /etc/nginx/new.conf

3.2.、ENTRYPONIT和CMD的区别

  •  docker run 启动容器的时候,可以传递参数进来给ENTRYPOINT里边的命令

  • 当两者都存在的时候,CMD里的内容会变成ENTRYPOINT的参数,例如:

ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306 33060
CMD ["mysqld"]


# 相当于  "docker-entrypoint.sh mysqld"

3.3、HEALTHCHECK

用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

格式:

HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。

The options that can appear before CMD are(选项):

  • --interval=DURATION(default:30s)
  • --timeout-DURATION(default:30s)
  • --start-period=DURATION(default:0s)
  • --retries-N(default:3)

例子:

# timeout(等待时间为3s);interval(时间距离为5m)
HEALTHCHECK --interval=5m --timeout=3s\
    CMD curl -f http://localhost/ || exit 1
# 用"curl -f http://localhost/ || exit 1 " 检查容器是否可以运行。在k8s中,这个叫做探针

4、VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

作用:

  • 避免重要的数据,因容器重启而丢失,这是非常致命的。
  • 避免容器不断变大。
  • 就是将容器里的某个路径挂载到宿主机的卷上

格式:

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点

在Dockerfile中有"VOLUME /myvol"这条命令的时候,这条命令是在容器里执行的。例如:若是在容器中执行了这条命令,那么他就会在宿主机的"/var/lib/docker/volume"文件夹下边自动生成一个与容器绑定(mount)的卷,假如这个卷的名字叫做"abcd"。那么,当我们在容器的/myvol里边新建一个sc.txt文件的时候,对应的也会在宿主机的/var/lib/docker/volume文件下创建一个sc.txt。因为在这里(卷)创建的文件或者文件夹都会保存在宿主机里边。因为卷是实现容器和宿主机数据共享的。

[操作]

Dockerfile文件内容如下:

 

使用"docker container inspect zhengbo-1"查看这个容器对应的卷是哪个

无论我们在宿主机的卷中还是在容器里的卷中加入任何文件或者文件夹,这些文件或者文件夹都会在宿主机和容器之间共享。

5、ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

格式:

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:

ENV NODE_VERSION 7.2.0  # 将7.2.0赋值给NODE_VERSION

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"

5.1、ARG(argument)

构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

格式:

ARG <参数名>[=<默认值>]

[例子]

 6、STOPSIGNAL

 语法:

STOPSIGNAL signal

[演示阻止信号的例子]

STOPSIGNAL SIGQUIT  # 用来阻止信号的

[演示屏蔽信号的例子]

[root@centos7-docker lianxi]# cat for.sh 
# 这个是捕捉信号,若是捕捉到1、2、15这三种信号,那么就会输出"I am busy",且捕捉之后原来信号的作用会失效,除了-9强制执杀死信号不能被捕获的
trap "echo I am busy" 1 2 15
for i in {1..100}
do
	echo $1
	sleep 1
done

7、制作镜像练习

要求:

  1. 以centos7作为基础镜像 
  2. 在里边安装好ip、vim、ping命令
  3. 编译好nginx,使用我们指定的配置文件nginx.conf install_nginx.sh
  4. 启动容器的时候,就启动nginx
  5. 网页代码上传到容器里
    1. 直接做到镜像里
    2. 使用数据卷挂载使用

第一步:准备环境新建目录

[root@centos7-docker ~]# cd /mydocker/
[root@centos7-docker mydocker]# mkdir nginx
[root@centos7-docker mydocker]# cd nginx/
[root@centos7-docker nginx]# pwd
/mydocker/nginx

准备安装nginx的脚本和nginx的源码文件

#!/bin/bash

#解决软件的依赖关系,需要安装的软件包
yum install epel-release -y
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel gcc gcc-c++ autoconf automake make psmisc net-tools lsof vim geoip geoip-devel wget -y


#下载nginx软件
mkdir  /nginx -p
cd /nginx
#wget  https://nginx.org/download/nginx-1.21.4.tar.gz


#解压软件
tar xf nginx-1.21.6.tar.gz 
#进入解压后的文件夹
cd nginx-1.21.6

#编译前的配置
./configure --prefix=/usr/local/nginx1  --user=lilin --group=lilin  --with-http_ssl_module   --with-threads  --with-http_v2_module  --with-http_stub_status_module  --with-stream  --with-http_geoip_module --with-http_gunzip_module

这个nginx-1.21.6.tar.gz压缩包需要我们自己去nginx官网下载安装:nginx: download  这是下载地址

下载之后我们使用"rz"命令上传到linux里边

[root@centos7-docker nginx]# rz

[root@centos7-docker nginx]# ls
install_nginx.sh  nginx-1.21.6.tar.gz

或者我们可以使用这个命令

[root@centos7-docker nginx]# crul -O https://nginx.org/download/nginx-1.21.6.tar.gz
# 这个链接地址,我们只需要打开上面我分享的链接进去之后,选择版本之后,进入到一个新页面,点击压缩包的右键就能复制链接地址了
# 这是大o

第二步:编写Dockerfile

[root@centos7-docker nginx1]# cat Dockerfile 
FROM centos:7
ENV NGINX_VERSION 1.21.6
ENV AUTHOR FanMY_71
# 这个不写LABEL也无所谓,就是一个标签
LABEL maintainer="fan<111111@qq.com>"

# 这里若是没有这个目录的话。docker服务应该会给我们新建这个目录,但是为了规范起见,我们还是写上这个新建目录命令
RUN mkdir /nginx
WORKDIR /nginx
COPY . /nginx
1
RUN set -ex ; \
	bash install_nginx.sh ; \
	yum install vim iputils net-tools iproute -y 

EXPOSE 80

# 这个路径的sbin前边要和install_nginx.sh中的编译前配置工作的路径是一样的,prefix=/usr/local/nginx
# 一定要注意!不然会出现错误的!!
ENV PATH=/usr/local/nginx1/sbin:$PATH

STOPSIGNAL SIGQUIT
CMD ["nginx", "-g", "daemon off;"]

第三步:生成镜像

[root@centos7-docker nginx]# ls
Dockerfile  install_nginx.sh  nginx-1.21.6.tar.gz
[root@centos7-docker nginx]# docker build -t fan-nginx:1.0 .
[root@centos7-docker nginx]# docker images
REPOSITORY            TAG         IMAGE ID       CREATED         SIZE
fan-nginx             1.0         340d151ce5e4   3 minutes ago   593MB

第四步:启动容器

 

第五步:测试访问web服务

 curl + IP地址:端口号

或者去浏览器里输入这个地址

我们nginx容器的页面路径是放在/usr/local/bginx1/html里边的。我们使用数据卷实现第五个要求,

 容器使用宿主机的里网站数据,所以以后更新就直接修改宿主机里的文件就行

或者创建一个卷,并拷贝宿主机的/web到卷的路径里边

 

那么我们要是使用镜像解决第五个问题呢?

将网站的数据做到镜像里边去。

拷贝网站代码到镜像里的nginx的网页根目录

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Dockerfile 是用于构建 Docker 镜像的一种文本文件。它包含了一系列的指令,用于描述构建镜像的步骤和配置。 下面是 Dockerfile 的一些常见指令和解释: 1. FROM:指定基础镜像,用于构建当前镜像。例如,可以使用 `FROM ubuntu:latest` 表示基于最新版本的 Ubuntu 镜像构建。 2. RUN:在镜像中执行命令。可以使用多个 RUN 指令来执行多个命令,每个 RUN 指令都会在前一个指令的基础上创建新的镜像层。 3. COPY:将文件或目录从主机复制到镜像中。可以使用 `COPY <src> <dest>` 来指定源文件/目录和目标路径。 4. ADD:类似于 COPY,但功能更强大。它可以复制远程文件、解压缩文件等。尽量使用 COPY 来避免不必要的复杂性。 5. WORKDIR:设置工作目录,后续的命令都会在该目录下执行。可以使用 `WORKDIR /path/to/directory` 来指定工作目录。 6. ENV:设置环境变量。可以使用 `ENV <key>=<value>` 来设置环境变量的键值对。 7. EXPOSE:声明容器运行时需要监听的端口。例如,可以使用 `EXPOSE 80` 来声明容器将监听 80 端口。 8. CMD:指定容器启动时要执行的命令。可以使用多个 CMD 指令,但只有最后一个生效。如果在运行容器时提供了命令,则 CMD 中的命令会被覆盖。 以上是一些常见的 Dockerfile 指令,还有其他指令如 ENTRYPOINT、LABEL 等,可根据具体需求进行使用。编写一个 Dockerfile 可以根据应用的需求进行定制化配置和设置,最终可以通过 Dockerfile 构建出一个可执行的 Docker 镜像

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FanMY_71

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值