- dockerfile常用指令
1、from 指明构建的新镜像是来自于哪个基础镜像,如果没有选择tag,那么默认值为latest
FROM centos:7
如果不以任何镜像为基础,那么写法为:FROM scratch镜像是一个空镜像,可以用于构建busybox等超小镜像,可以说是真正的从零开始构建属于自己的镜像
2、MAINTAINER(deprecated)
语法:MAINTAINER<name>
指明镜像维护者及其联系方式(一般是邮箱地址)。官方说明已过时,推荐使用LABEL
MAINTAINER mrhelloworld <mrhelloworld126.com>
3、LABEL
语法:LABEL <key>=<value> <key>=<value> <key>=<value>....
功能是为镜像指定标签,也可以使用LABEL来指定镜像作者
LABEL maintainer="ladfjajfaljfjaljdl"
4、run
语法:RUN <command>
构建镜像时运行的shell命令。比如构建的新镜像中我们想在/usr/local目录下创建一个java目录
RUN mkdir -p /usr/local/java
5、ADD
语法:ADD <src>....<dest>
拷贝文件或目录到镜像中,src可以是一个本地文件或者是一个本地压缩文件,压缩文件会自动解压。还可以是一个url,如果把src写成一个url,那么ADD就类似于wget命令,然后自动下载和解压
ADD jdk-11.0.6_linux_bin.tar.gz /usr/local/java
6、copy
语法:copy <src>....<dest>
拷贝文件或目录到镜像中,用法同add,只是不支持自动下载和解压
copy jdk-11.0.6.linux_bin.tar.gz /usr/local/java
7、expose
语法:expose <port> [<port>/<protocal>]
暴露容器运行时的监听端口给外部,可以指定端口是监听TCP还是UDP,如果未指定协议,则默认是TCP
expose 80 443 8080/tcp
如果想使得容器与宿主机的端口有映射关系,必须在容器启动的时候加上-p参数
8、ENV
语法:ENV <key> <value>添加单个,ENV <key><value>....添加多个
设置容器内环境变量
ENV JAVA_HOME /usr/local/java/jdk-11.0.6/
9、cmd
语法:
cmd ["executable","param1","param2"],比如:cmd ["/usr/local/tomcat/bin/cataline.sh","run"]
cmd ["param1","param2"],比如:cmd ["echo","$JAVA_HOME"]
cmd command param1 param2,比如 cmd echo $JAVA_HOME
启动容器时执行的shell命令,在Dockerfile中只能有一条CMD指令。如果设置了多条cmd,只有最后一条cmd会生效
cmd ehco $JAVA_HOME
如果创建容器的时候指定了命令,则cmd命令会被替代,假如镜像叫centos:7,创建容器时命令是:docker run -it --name centos7 centos:7 echo "helloworld" 或者 docker run -it --name centos7 centos:7 /bin/bash,就不会输出$JAVA_HOME的环境变量了,因为CMD命令被echo "helloworld"、/bin/bash覆盖了
10、ENTRYPOINT
语法:ENTRYPOINT["execurable","param1","param2"],比如:ENTRYPOINT["/usr/local/tomcat/bin/catalina.sh","run"]
ENTRYPOINT command param1 param2,比如:ENTRYPOINT ehco $JAVA_HOME
启动容器时执行的shell命令,同CMD类似,不会被docker run命令行指定的参数所覆盖。在Dockerfile中只能有一条ENTRYPOINT指令。如果设置了多条ENTRYPOINT,只有最后一条ENTRYPOINT会生效
ENTRYPOINT ehco $JAVA_HOME
----如果在Dockerfile中同时写了ENTRYPOINT和cmd,并且cmd指令不是一个完整的可执行命令,那么cmd指定的内容将会作为ENTRYPOINT的参数:
----如果在Dokcerfile中同时写了ENTRYPOINT和cmd,并且cmd是一个完成的指令,那么它两会互相碰撞,谁在最后谁生效
11、workdir
语法:workdir /path/to/workdir
为run cmd entrypoint以及copy和and设置工作目录
workdir /usr/local
12、volume
指定容器挂载点到宿主机自动生成的目录或其他容器。一般的使用场景为需要持久化存储数据时。
#容器的/var/lib/mysql 目录会在运行时自动挂载为匿名卷,匿名卷在宿主机的/var/lib/docker/volumes 目录下
volume {"/var/lib/mysql"}
一般不会在Dockerfile中用到,更常见的还是在docker run的时候通过-v指定数据卷
- dockerfile实战
通过基础镜像centos:7,在该镜像中安装jdk和tomcat以后将其制作为一个新的镜像mycentos:7
创建目录:
mkdir -p /usr/local/Dockerfile
编写dockerfile文件
vi dockerfile
dockerfile文件内容
#指明构建的新镜像是来自于centos:7基础镜像
FROM centos:7
#通过镜像标签声明作者信息
LABEL maintainer="mrhelloworld.com"
#设置工作目录
WORKDIR /usr/local
#新镜像构建成功以后创建指定目录
RUN mkdir -p /usr/local/java && mkdir -p /usr/local/tomcat
#拷贝文件到镜像中并解压
ADD jdk-11.0.6_linux_bin.tar.gz /usr/local/java
ADD apache-tomcat-9.0.37.tar.gz /usr/local/tomcat
#暴露容器运行时的8080监听端口给外部
EXPOSE 8080
#设置容器内 JAVA_HOME 环境变量
ENV JAVA_HOME /usr/local/java/jdk-11.0.6/
ENV PATH $PATH:$JAVA_HOME/bin
#启动容器时启动tomcat
CMD["/usr/local/tomcat/apache-tomcat-9.0.37/bin/catalina.sh","run"]
- 构建镜像
#-f:指定dockerfile的文件路径 -t:指定镜像的名字或者标签,/root/:配合dockerfile文件中的add使用,指明需要加载的资源在哪里
docker build -f /usr/local/dockerfile/Dockerfile -t mycentos:7 /root/
我们在使用docker bulid命令来构建镜像时,往往会看到命令最后会有一个“.”号,它是做什么用的:Docker在运行时分为Docker引擎(服务端守护进程)和客户端工具,我们日常使用各种docker 命令,其实就是在使用客户端工具与docker引擎进行交互。当我们使用docker bulid名来构建镜像时,这个构建过程其实是在docker引擎中完成的,而不是在本机环境,如果在dockerfile中使用了一些ADD等指令来操作文件,如何让docker引擎获取到这些文件呢?
这里就有了一个镜像构建上下文的概念,当构建的时候,由用户指定构建镜像时的上下文路径,而docker build会将这个路径下所有的文件都打包上传给docker 引擎,引擎内部这些内容展开后,就能获取到上下文中的文件了
例如:我的宿主机jdk文件在/root目录下,Dockerfile文件在/usr/local/dockerfile目录下,文件内容如下:
ADD jdk-11.0.6_linux-x64_bin.tar.gz /usr/local/java
那么构建镜像时的命令就该这样写
docker build -f /usr/local/dockerfile/Dockerfile -t mycentos:7 /root
再例如:
我的宿主机jdk文件和Dockerfile文件都在/usr/local/dockerfile目录下,文件内容如下:
ADD jdk-11.0.6_linux-x64_bin.tar.gz /usr/local/java
那么构建镜像时的命令则这样写
docker build -f /user/local/dockerfile/Dockerfile -t mycentos:7