菜单
本页目录

[TOC]

Dockerfile语法

FROM #指定基础镜像

注意:只能在Dockerfile中出现一次,且位于最上层

​ (后续也会出现有多个FROM的情况,镜像分层)

FROM centos:centos7.2.2009

MAINTAINER #指定镜像创建者

​ maintainer

MAINTAINER yq "yq@qq.com"

LABEL #将元数据添加到镜像

(标签的定义)

LABEL "www.yq.com"="YQ WEB"
LABEL version="1.0"
LABEL nginx-version="1.18.0" \
      key1=yq

拓展1:根据Dockerfile文件生成镜像

​ (注意:在当前目录下执行命令后,会将当前目录下所有作为镜像的原材料)

$ docker build -t label:v1 --no-cache

		-t	镜像名:版本			#指定镜像名,版本号
		--no-cache				#生成镜像过程中不建立缓存(建立缓存后,下一次生成不会再次执行详细步骤,直接使用缓存)

拓展2:Dockerfile原理

创容器、可写层中执行、所有层级保存为新镜像、删容器

​ 基于已存在的镜像中创建容器,将Dockerfile中的指令放入可写层执行,完成后将所有层级保存为一个新镜像,删除刚才创建的容器,基于此镜像再创建一个容器,将下一个指令放入可写层中执行,完成后将所有层级保存为一个新镜像,删除刚才创建的容器,循环往复,直到执行完Dockerfile中所有指令(每个关键字的执行都会创建一个容器,执行完毕保存层级后就会被删除

image-20221229215035372

拓展3:格式化处理,筛选容器中的 json 信息

$ docker image inspect label:v1 --format "{{json .Author}}" | jq
$ docker image inspect label:v1 --format "{{ json .ContainerConfig.Labels}}" | jq

拓展4:继承与重写(只要是元数据,都会符合这个特性)

​ 不仅发生在 label 指令中,也可以对:其他的镜像、启动命令、作者信息等指令使用

​ **继承:**新镜像不改变之前的指令

​ **重写:**新镜像先继承之前的指令,再根据需要,对指令进行修改

RUN #指定镜像中,需要执行的命令

​ 注意:每一个RUN指令,都会重新创建一个容器,进入执行命令时都在初始位置(执行的命令注意当前所在位置

注意:

1)将同一个应用服务的操作,放入一个指令中

​ Dockerfile的每一个指令都被封装在独立文件层级中

​ 镜像中,若层级的操作相同,时可以重用的:存储空间、过程

2)尽可能将容易变化的层级放入上层

从底层到上层,在镜像的重用过程中,若中间出现了变化,上层的操作虽然一样,但最后结果不一样

3)RUN 后的命令能否执行,取决于镜像环境能否执行

image-20221229235129920

RUN cd /tmp && curl -L 'http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.8/bin/apache-tomcat-7.0.8.tar.gz' | tar -xz 
RUN ["/bin/bash", "-c", "echo hello"]

USER #设置容器的用户

​ 如果不指定,默认为root

USER nginx

EXPOSE #指定容器需要映射到宿主机的端口(信息级别)

#可以映射多个端口
EXPOSE 80 3306

ENV #设置容器中的环境变量

(只能用此方法设置,在容器中 /etc/profile 设置的不会生效)

ENV NAME nginx

ARG #设置 Dockerfile 中的环境变量

ENV与ARG区别

​ 起作用的时机不同:

​ ARG:在 build 过程中,存在的环境变量,可以在Dockerfile中当作变量使用

​ ENV:是容器创建好后,在容器中生效的环境变量,不能在Dockerfile中当参数使用

案例:

# Dockerfile
FROM centos7:latest

LABEL maintainer="yq@qq.com"

ARG REDIS_SET_PASSWORD=developer

ENV REDIS_PASSWORD $(REDIS_SET_PASSWORD)

RUN echo $(REDIS_SET_PASSWORD) > /root/redis_password

RUN echo $(REDIS_SET_PASSWORD)

VOLUME /data

EXPOSE 6379

CMD ["sh", "-c", "exec redis-server --requirepass \"$REDIS_PASSWORD\""]

ADD #从 src 复制文件到 container 的 dest 路径

ADD <src> <dest>  
        <src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件 url;
        <dest> 是 container 中的绝对路径

​ src 可以是一个 URL,会自动下载

​ 如果 src 是一个压缩包,会自动解压

两个特性不能同时存在

COPY #从 src复制到 container 的 dest 路径

#注意:不支持 src 为URL、不支持自动解压(仅为一个单纯的拷贝关系)

COPY <src> <dest> 

VOLUME #指定挂载点

​ 设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是 AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在 Dockerfile中 使用该指令

FROM base
VOLUME ["/tmp/data"]

WORKDIR #切换目录

​ #设置进入容器后,所在的默认位置(可以写多个)

WORKDIR /usr/local/nginx

#结合 RUN ,可以实现 RUN 中的命令不用每次都指定切换路径

CMD #设置容器启动时,执行的操作

​ **注意:**设置多个时,谁在最后谁生效

​ 当镜像创建为容器时,CMD定义的命令会执行

​ 当容器从关闭状态到启动,CMD定义的命令会执行

拓展:容器如果需要正常运行,需要有一个前台进程

CMD touch /usr/local/nginx/logs/access.log && /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log

ENTRYPOINT #设置容器启动时,执行的操作

​ **注意:**设置多个时,谁在最后谁生效

​ 若结合CMD,且CMD为完整的可执行命令,谁在最后谁生效

CMD  touch /root/1.txt
ENTRYPOINT ls -l 

拓展:ENTRYPOINT 与CMD 结合

官方释义:https://docs.docker.com/engine/reference/builder/#cmd

Dockerfile:
        FROM centos7:latest 
        CMD ["p in cmd"]				#定义参数
        ENTRYPOINT ["echo"]				#定义命令


$ docker build -t env:v1 .

$ docker run --name test1  env:v1
p in cmd

$ docker run --name test2 env:v1  p in run
p in run

实验:启动容器时,实现不同命令启动不同服务

信息请点击👉CMD+ENTRYPOINT实现:选择服务启动镜像

Dockerfile 的层级是有行数限制的

​ Docker overlay

​ 128层

ONBUILD #在子镜像中执行

ONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行

**用途:**可以防止别人对此镜像再次封装

​ 可以在别人对此镜像封装时,自动删除不需要的数据

ONBUILD RUN sleep 86400
ONBUILD RUN rm -rf /root/*

STOPSIGNAL #指令设置将发送到容器以退出的系统调用信号

SIGHUP 1 A 终端挂起或者控制进程终止

SIGINT 2 A 键盘中断(如break键被按下)

SIGQUIT 3 C 键盘的退出键被按下

SIGILL 4 C 非法指令

SIGABRT 6 C 由abort(3)发出的退出指令

SIGFPE 8 C 浮点异常

SIGKILL 9 AEF Kill信号

SIGSEGV 11 C 无效的内存引用

SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道

SIGALRM 14 A 由alarm(2)发出的信号

SIGTERM 15 A 终止信号

SIGUSR1 30,10,16 A 用户自定义信号1

SIGUSR2 31,12,17 A 用户自定义信号2

SIGCHLD 20,17,18 B 子进程结束信号

SIGCONT 19,18,25 进程继续(曾被停止的进程)

SIGSTOP 17,19,23 DEF 终止进程

SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键

SIGTTIN 21,21,26 D 后台进程企图从控制终端读

SIGTTOU 22,22,27 D 后台进程企图从控制终端写

SHELL #修改容器的默认解释器

​ #不建议使用

SHELL ["/usr/local/python"]
RUN /root/a.py


RUN /usr/local/python /root/a.py		(√)建议使用

HEALTHCHECK #容器健康状况检查 (废弃,由k8s完美替代)

注意

HEALTHCHECK 命令只能出现一次,如果出现了多次,只有最后一个生效

模板

HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1

查看容器的健康状态

$ docker inspect –format ‘{{json .State.Health.Status}}’ cID

更多详细信息请点击👉Dockerfile 语法详解-课件