Dockerfile详解:(每一个指令都会建立一层镜像,比如RUN多个命令,会在原来的基础上每运行一次新建一个镜像,多余很多编译环境,非常臃肿,增加构建时间)

简易解释:

FROM:指定基础镜像(必须)

RUN:执行command命令 Eg:Run apt-get update

COPY:将相对路径(Dockerfile所在位置)/   绝对路径 的文件或文件夹 复制到编译环境的指定路径

ADD:复制文件并且解压文件

ENV :设置环境变量(用于构建环境和运行环境里)

WORKDIR:指定工作目录,相当于cd

CMD:docker run命令运行镜像时要执行的命令,但是docker run后面有运行命令时这个命令将会失效

ENTRYPOINT:和cmd一样,docker run后拼接的命令会在 这个后执行

ONBUILD:当本镜像作为基础镜像被其他Dockerfile用FROM指令引用时,在所有其他指令执行之前先执行这些指令

VOLUME:创建卷,挂载在主机上,而不是容器里

实践参考:https://www.cnblogs.com/jsonhc/p/7767669.html

 

 

 

FROM:指定基础镜像

例如(nginx,mysql,mongo),空白镜像(scratch)

格式:FROM <image> [:<tag>][AS <name>]

name 是别名,可用于后面构建

 

RUN : 执行命令,定制镜像

有2种常用格式

shell:RUN <命令>

exec:RUN <"可执行文件","参数1","参数2">

eg:

FROM debian:jessie 
RUN buildDeps='gcc libc6-dev make' \ 
&& apt-get update \ 
&& apt-get install -y $buildDeps \ 
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \ 
&& mkdir -p /usr/src/redis \ 
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \ 
&& make -C /usr/src/redis \ && make -C /usr/src/redis install \ 
&& rm -rf /var/lib/apt/lists/* \
&& rm redis.tar.gz \
&& rm -r /usr/src/redis \
&& apt-get purge -y --auto-remove $buildDeps

用&&连接所有命令,用\换行,行首#进行注释

注:可以看到这一组命令的最后添加了清理工作的命令,删除了为了编译构建所需要的软件,清理了所有下载、展开的文件,并且还清理了 apt 缓存文件。这是很重要的一步,之前有说过,镜像是多层存储,每一层的东西并不会在下一层被删除,会一直跟随着镜像。因此镜像构建时,一定要确保每一层只添加真正需要添加的东西,任何无关的东西都应该清理掉
 

构建镜像:

$ docker build -t nginx:v3 . 
Sending build context to Docker daemon 2.048 kB 
Step 1 : FROM nginx ---> e43d811ce2f4 
Step 2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html 
---> Running in 9cdc27646c7b 
---> 44aa4490ce2c
Removing intermediate container 9cdc27646c7b 
Successfully built 44aa4490ce2c

从命令的输出结果中,我们可以清晰的看到镜像的构建过程。在 Step 2 中,如同我们之前所说的那样, RUN 指令启动了一个容器 9cdc27646c7b ,执行了所要求的命令,并最后提交了这一层 44aa4490ce2c ,随后删除了所用到的这个容器 9cdc27646c7b 

这里我们使用了 docker build 命令进行镜像构建。其格式为:

docker build [选项] <上下文路径/URL/->
 

docker build -t nginx:v3 .

这里niginx 是镜像名称 v3是版本号 .是在 指定上下文的目录 ,表示将该目录下的内容打包给Docker引擎(在执行copy 目录到docker 引擎 时的相对路径,比如 COPY /opt/xxxx /app,这个目录就是相对于上下文目录的)

 

COPY 复制文件

COPY <源路径> <目标路径>

COPY package.json /usr/src/app/

 

ADD高级复制,会自动解压缩,适合于需要自动解压缩的场合)

 

CMD (docker 不是虚拟机,而是进程,在启动容器的时候,需要指定所运行的程序及参数),指定容器启动程序及参数

2种格式:

shell格式:CMD <命令> 

exec格式: CMD ["可执行文件","参数1","参数2"]

一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD

 

ENTRYPOINT:类似于cmd,但当在docker run 命令最后加上参数,这个参数会加在ENTRYPOINT后面,拼接好一起运行

 

ENV 设置环境变量,可在构建环境和运行环境里使用

ENV <key> <value> 或 ENV <key1>=<value1>

eg:
# 设置java环境变量
ENV JAVA_HOME /home/jdk1.8.0_51
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
# 设置语言环境变量
ENV LANG zh_CN.UTF-8
ENV LANGUAGE zh_CN:zh

 

ARG 设置的构建环境的环境变量

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

EG: ARG name=tom

 

VOLUME 定义匿名卷(挂载)

VOLUME <路径>

容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,

VOLUME /data

这里的 /data 目录就会在运行时自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化,我们可以使用docker inspect命令找到Volume在主机上的存储位置:

docker inspect -f {{.Volumes}} container-test

只有-v参数能够做到而Dockerfile是做不到的事情就是在容器上挂载指定的主机目录。例如:

$ docker run -v /home/adrian/data:/data debian ls /data

注意: 镜像目录下任何文件不会复制到Volume中,但Volume中文件会复制到镜像目录

只有运行docker rm -v  该volume才会随着容器一起删除

 

 

 

EXPOSE 声明端口

声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务

目的 是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;

另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口

-p <宿主端口>:<容器端口>

 

WORKDIR 指定工作目录

切换目录用,可以多次切换(相当于cd命令),使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),为RUN、CMD、ENTRYPOINT指令配置工作目录,如该目录不存在, WORKDIR 会帮你建立目录

比如:

RUN cd /app

RUN echo "hello" > world.txt 

如果不指定 WORKDIR app ,那这个文件是不会在app/world.txt 的,而直接是根目录下

 

USER 指定当前用户

 

HEALTHCHECK 健康检查

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

interval=<间隔> :两次健康检查的间隔,默认为 30 秒;
timeout=<时长> :健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
retries=<次数> :当连续失败指定次数后,则将容器状态视为 unhealthy ,默认 3 次。
 

ONBUILD

用法:ONBUILD [INSTRUCTION]

说明:配置当前所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。意思就是,这个镜像创建后,如果其它镜像以这个镜像为基础,会先执行这个镜像的ONBUILD命令

 

安装tomcat:

FROM centos

MAINTAINER nobody "xx@qq.com"

RUN mkdir -p /opt/jdk/

RUN mkdir -p /opt/tomcat/

ADD jdk1.7.0_79 /opt/jdk/

ADD tomcat  /opt/tomcat/

ENV CATALINA_HOME /opt/tomcat

ENV JAVA_HOME /opt/jdk

EXPOSE 8080

ENV PATH $PATH:$JAVA_HOME/bin

CMD ["/opt/tomcat/bin/catalina.sh","run"]

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐