Dockerfile 样本
FROM nginx:v1
MAINTAINER east_qiu@outlook.com
WORKDIR /usr/share/nginx/html
RUN echo '<h1>Hello, Docker!</h1>' > index.html
EXPOSE ['80', '443']
...
- 构建镜像
docker build nginx .
-f 指定具体的dockerfile
-t 指定镜像的tag,指定存储库和标记保存新映像,可以一次指定多个tag,生成多个镜像
docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
构建时docker会初步验证dockerfile,如果有语法错误,会提示
dockerfile每条指令都是独立运行的,并会创建一个新映像
Docker将重用中间映像(缓存),显著加快Docker构建过程。
dockerfile 必须从FROM开始
FROM
FROM 基础镜像
escape
escape指令用于指定dockerfile里面的转义字符, 默认是 \ , windows里面 `
escape定义在文件的最上方
# escape=`
FROM microsoft/nanoserver
COPY testfile.txt c:\
RUN dir c:\
ENV
ENV定义的环境变量在后续层次中才能够被应用
ENV abc=hello
ENV abc=bye def=$abc # def=hello
ENV ghi=$abc # ghi=bye
.dockerignore
COPY和ADD指令中用于忽略指定文件,加快构建速度
RUN
RUN <command>
RUN ["executable", "param1", "param2"]
linux 上默认上/bin/sh -c
windows上默认cmd /S /C
RUN命令在当前镜像上执行指令,构建出一个新的镜像,便于dockerfile下面的语句继续执行
RUN可以有多个
CMD
CMD一个dockerfile里只能有一个
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
如果指定ENTERPOINT, 用 CMD 指定具体的参数。
这里边包括参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。
RUN & CMD
RUN是构件容器时就运行的命令以及提交运行结果
CMD是容器启动时执行的命令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子
LABEL
label为镜像指定信息,用于docker inspect 查看相关信息
MAINTAINER
指定维护者,已经废弃
EXPOSE
EXPOSE用于指定容器运行时指定对外暴露的端口
但是EXPOSE并不会使容器访问主机的端口
如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P参数
ADD
ADD把文件复制到镜像中
ADD --chown=<user>:<group> src dist
chown 只有linux文件系统才有
src可以是文件,也可以是链接,也可以是目录(不建议,会复制目录和目录下的所有文件)
如果文件系统里/etc/passwd or /etc/group 里面没有chown指定的用户,构建会出错
- 增加的文件必须在镜像上下文相对的目录下,也就是镜像构建上下文的相对目录
- 如果是一个URL,并且没有结尾斜杠,那么从这个URL下载一个文件并复制到dist
COPY
单纯的复制文件,也是相对构建的镜像上下文
ENTRYPOINT
ENTRYPOINT 的格式和 RUN 指令格式一样,分为 exec 格式和 shell 格式
exec 形式
ENTRYPOINT [“executable”,”param1”,”param2"]
任何docker run设置的命令参数或者CMD指令的命令,都将作为ENTRYPOINT 指令的命令参数,追加到ENTRYPOINT指令之后。
ENTRYPOINT command param1 param2
这种格式禁止追加任何参数,即CMD指令或docker run后面的参数都将被忽略。采用shell格式,在容器中执行时,自动调用shell。
CMD&&ENTRYPOINT
- CMD可以为ENTRYPOINT提供参数,
ENTRYPOINT本身也可以包含参数,但是可以把需要变动的参数写到CMD里面,而不需要变动的参数写到ENTRYPOINT里面; - ENTRYPOINT使用第二种shell方式会屏蔽掉CMD里面的命令参数和docker run后面加的命令。
- 在Dockerfile中,ENTRYPOINT指定的参数比运行docker run时指定的参数更靠前。
- ENTRYPOINT/CMD中不能把一个有限执行的命令加到一个无限执行的命令后面。这会导致后面的有限执行的命令无法执行。因为无限命令一直在执行,永远都无法执行结束,所以会导致后面的有限执行命令阻塞。
- ENTRYPOINT/CMD中最后的一个命令必须要是无限执行的命令。
Dockerfile 中的每一行都产生一个新层;
下列代码每一行都又一个独立的id,而且下面产生的三层是只读的,一旦Image被运行时,会产生一个新层 container 层,这一层是可读可写的;
分层的优势在于,两个image可以共享一些层,降低了存储的压力
FROM alpine:latest
MAINTAINER cc
CMD echo "hello docker"