镜像的构建实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
自定义nginx镜像
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义Dockerfile</title>
</head>
<body>
自定义Dockerfile
</body>
</html>

FROM nginx:latest
COPY index.html /usr/share/nginx/html/
构建镜像
docker build -t nginx:v3 .
启动容器
docker run --name ng -itd -p 81:80 nginx:v3
指定构建的dockerfile
docker build -t nginx:v4 -f xxx_dockerfile .
Dockerfile相关命令
FROM
FROM指定一个基础镜像, 一般情况下一个可用的 Dockerfile一定是 FROM 为第一个指令。至于image则可以是任何合理存在的image镜像。 FROM 一定是首个非注释指令 Dockerfile. FROM 可以在一个 Dockerfile 中出现多次,以便于创建混合的images。 如果没有指定 tag ,latest 将会被指定为要使用的基础镜像版本。
ENV 设置环境常量
简单的说,它就是一个全局常量,被设置后,进入容器内部,在任意位置都可以访问这个常量的值,比如# echo $var_bl。 好比本地设置了JAVA_HOME环境变量一样,在CMD窗口任意目录,都可以打印/获取该常量。
ENV WORKPATH /tmp
ENV http_proxy ""
ENV JAVA_HOME /usr/local/openjdk8
ENV test=mayun-xiaoma
ENV mycat=mimi
RUN $JAVA_HOME/bin/java-jar test.jar
ENV指令可以用于为docker容器设置环境变量 ENV设置的环境变量,可以使用 docker inspect命令来查看。同时还可以使用docker run --env =来修改环境变量。
USER USER
用来切换运行属主身份的。Docker 默认是使用 root,但若不需要,建议切换使用者身分,毕竟 root 权限太大了,使用上有安全的风险。
Dockerfile指定USER用户后, 后续的命令 RUN、CMD、ENTRYPOINT 都将使用该用户
WORKDIR 设置工作目录
WORKDIR 设置的,目录需要是绝对路径,如果不存在,会自动创建。
在Dockerfile最外层首次出现,则是指明通过docker exec -it 进入容器内部后,默认进入的工作目录(无需再用cd命令切换)。
如果Dockerfile中命令比较多,需要来回切换工作目录,则可以随时再次定义新的WORKDIR
WORKDIR /usr/local
WORKDIR /usr/local/newdir #如果不存在会被自动创建,尽量使用绝对路径
ADD & COPY 将宿主机的文件上传到镜像中
add除了复制,还具备添加远程文件功能(文件以http://开头),类似于linux的wget
add是增强版的copy,add自带解压,copy不带解压。两者都支持目录中有空格。
1、ADD指令不支持认证,从远程获取资源如果需要认证(交互),则只能使用RUN wget或RUN curl替代。 2、如果不是需要解压,优先使用COPY命令,效率更高、更节省资源。
ADD hello / #把hello从宿主机复制到容器内部的根路径
ADD test.tar.gz / #把压缩包从宿主机添加到容器的根目录后,自动解压
ADD hello . #把hello文件复制到当前workdir工作目录的根目录
COPY test.txt /etc/nginx #仅从宿主机复制文件到容器内部的指定目录
ADD demo.tar.gz /usr/share/nginx/html #复制文件,并自动解压到指定目录
RUN & CMD & ENTRYPOINT 运行指令
三者都是执行命令,但是它们的执行时机是不同的
RUN 仅在Build构建时执行的命令
CMD 用来设置容器启动后默认执行的命令(参数),它可被docker run后面的命令参数替换;
ENTRYPOINT 容器run启动时执行的命令
RUN 在生成镜像时需要执行的命令
#示例,演示run命令的两种不同写法
RUN yum install -y vim #Shell命令格式
RUN ["yum "," install" ,"-y","vim"] #Exec命令格式
Dockerfile中的RUN命令,只有在docker build 命令构建镜像时会自动运行,docker run的时候,并不会运行(注意,部分精简版的镜像,本身只提供最基础的linux命令比如vi,不自带vim)。
CMD用来设置容器启动后默认执行的命令(参数)
作用:可以单独使用,但不一定会被执行,也可作为其他命令的补充参数使用
dockerfile 中如果存在多个CMD指令,仅能保证最后一个生效。
在dockerfile 文件中,RUN后面可以包含CMD命令,此时它前面的CMD可能会被忽略。
ENTRYPOINT 容器启动时需要执行的命令
如果有ENTRYPOINT,则不会执行cmd
命令执行的顺序
FROM nginx:latest
RUN echo "run的命令1"
RUN echo "run的命令2"
CMD ["echo", "cmd命令1"]
CMD ["echo", "cmd命令2"]
构建时,输出结果
run的命令1
run的命令2
docker run 的输出结果
docker run xxx
cmd命令2
docker run xxx echo "xxx"
xxx
EXPOSE 指令指定在docker允许时指定的端口进行转发。
EXPOSE参数在Dockerfile中是可以不写(docker run -p时依然可以指定暴露端口),
为了规范化Dockerfile,让读者对其外暴露的端口一目了然,建议还是要写。
#docker run -d -p 8000:8080
8080 就是容器内对外暴露的端口,-p 极具灵活性。