太长不读版: 案例地址:https://github.com/gholly/docker-scaffold.gitjava
1. Dockerfile是什么?git
Dockerfile是Docker用来构建镜像的文本文件,包含自定义的指令和格式。能够经过docker build命令从Dockerfile中构建镜像.
2. 镜像构建过程github
Dockerfile描述了组装镜像的步骤,其中每条指令都是单独执行的。除了FROM指令,其余每一条指令都会在上一条指令所生成镜像的基础上执行,执行完后会生成一个新的镜像层,新的镜像层覆盖原来的镜像之上从而造成了新的镜像,Dockerfile所生成的最终镜像就是在基础镜像上面叠加一层层的镜像层组建的。spring
3. Dockerfile指令docker
在Dockerfile中,指令(INSTRUMENT)不区分大小写,可是为了与参数区分,推荐为大写。Docker会顺序执行Dockerfile中的指令,第一条指令必须为FROM指令,它用于制定构建镜像的基础镜像。在Dockerfile中以#开头的行为注释,而在其余位置的#会被当成参数。shell
指令的格式以下:json
# comments INSTRUMENT argument
Dockerfile的指令有FROM,MAINTAINER,RUN,CMD,EXPOSE,ENV,ADD,COPY,ENTRYPOINT,VOLUMN,USER,WORKDIR,ONBUILD等数组
格式: ENV <key> <value> 或 ENV <key>=<value>
ENV 指令能够为镜像建立出来的容器声明环境变量,而且在Dockerfile文件,ENV指令声明的环境变量会被后面的指定指令(即ENV,add,copy,workdir,expose,volume,user)解释使用。其余指令使用环境变量时,使用格式为$variable_name 或${variable_name}.在变量前下\能够转义,如$foo或者${foo},都会被转成$foo 和${foo},而不是环境变量所保存的值。另外,ONBUILD指令不支持环境替换。springboot
格式: FROM <image> 或 ENV <image>:<tag>
FROM指令的功能是为后面的指令提供基础镜像,所以一个有效的Dockerfile必须以FROM指令做为第一条非注释指令。基础镜像能够选取任何有效的镜像。在一个dockerfile文件中,From指令能够出现屡次,这样会构建多个镜像。在每个镜像建立完成后,docker命令行会输出该镜像的ID。若from指令中tag参数为空,则tag默认为lastest;若参数image或tag指定的镜像不存在,则返回错误。网络
从公共镜像库拉取镜像很容易?example中的镜像来源是?
格式: COPY <src> <dest>
COPY指令复制<src>所指向的文件或目录,将它添加到新镜像中,复制的文件或目录在镜像中的路径是<dest>.
格式: ADD <src> <dest>
add和copy指令功能类似,都支持复制本地文件到镜像的功能,但add指令还支持其余功能。<src>能够是一个指向一个网络文件的url,<dest>指向一个目录,则url必须是彻底路径,这样能够获取该网络文件的filename.
ADD http://example.com/foofile / #会建立文件/foofile
<src>还能够指向一个本地压缩归档文件,该文件在复制到容器中时会被解压提取,如:
ADD example.tar.xz / #则建立example文件
但若网络文件url中的文件是压缩文件,则不会被解压提取。 ADD和copy指令虽然功能类似,推荐使用copy,由于copy只支持本地文件,相比add更透明。
格式: RUN <command> #shell格式 RUN ["executable","param1","param2"] #exec格式,推荐格式
RUN指令会在前一条命令建立出的镜像的基础上建立一个容器,并在容器中运行命令,在命令结束后提交容器为新镜像,新镜像被dockerfie中的下一条指令使用。
当使用exec格式时,命令是直接运行的,容器不调用shell 程序,即容器中没有shell程序。exec格式中的参数会被当成json数组被docker解析,因此要使用双引号。若但愿运行shell程序,指令须要写成这样 CMD [ "sh", "-c", "echo" , "$HOME"]
格式: CMD <command> #shell格式 CMD ["executable","param1","param2"]#exec格式,推荐格式 CMD [param1","param2"]
CMD指令提供容器运行时的默认值,这些默认值能够为一条指令,也能够是参数。一个dockerfie文件中能够有多个cmd指令,只有最后一条生效。
CMD指令在构建镜像时不执行任何指令,而是在容器启动时默认将cmd的指令做为第一条执行的命令。若是docker run命令时指定了命令参数,则会覆盖cmd指令中的命令。
格式: ENTRYPOINT <command> #shell格式 ENTRYPOINT ["executable","param1","param2"]#exec格式,推荐格式
ENTRYPOINT指令与cmd命令类似,均可以让容器在每次启动的时候执行相同的命令。最后一条ENTRYPOINT生效。
当为shell格式时,ENTRYPOINT会忽略掉任何cmd指令和docker run命令的参数,因此推荐exec格式。
使用exec格式时,docker run会覆盖cmd的内容,而且附加到ENTRYPOINT的指令的参数中。
4. 根据以上指令实践一下:尝试把一个简单的springboot项目打包成一个镜像 Dcokerfile文件
# openjdk:lastest 可从https://hub.docker.com/官方镜像仓库去查找你想要的镜像 FROM openjdk:latest COPY ./build/libs/scaffold-1.0-SNAPSHOT.jar docker-scaffold.jar #JAVA_OPTS 是用来设置JVM相关运行参数的变量 ENV JAVA_OPTS="" EXPOSE 8080 ENTRYPOINT ["java", "-jar", "docker-scaffold.jar"]
docker build -f ./Dockerfile . -t scaffold docker run scaffold #启动镜像 docker exec -it container-id sh 或者 docker exec -it container-id sh #进入到容器中 curl -i http://localhost:8080/hi
返回200,说明此时成功了。