目录
一、Dockerfile基本结构
拿到Dockerfile(可以命名为其他名字,但是不推荐)后就可以通过docker build实现镜像的复制。在同一文件夹下存在多个Dockerfile的情况,可以修改Dockerfile文件名,如Dockerfile.first、Dockerfile.second,只需要在构建时加上-f参数即可。
1.1 Dockerfile书写规则
- 注释://
- 语法结构: 指令 参数
- 大小写问题: 官方允许小写的指令,但是为了代码的可读性,指令用大写
1.2 Dockerfile书写思想
- 注意自动化: 文件是否可以一直持续不断的运行下去,遇到交互节点时候可以自动应答
- Dockerfile顺序: Dockerfile构建是从上到下的,所以书写时需要考虑命令执行情况适当调整指令位置(例如软件依赖应在软件执行源命令前安装)
- 注意清理: 在构建完成后,清除构建过程中产生的临时文件(并不是删除文件后体积一定会减小),以保证镜像的体积节省资源
- 文件易读性: 例如,一条很长的命令,不要一行写到底,可以加\分隔
二、Dockerfile指令介绍
2.1 FROM
2.1.1 作用
指定基础镜像
2.1.2 语法
FROM <imageName:tag>
案例:
FROM aprine
2.2 MAINTAINER
2.2.1 作用
设置维护者信息
2.1.2 语法
MAINTAINER Name <Email>
2.3 RUN
2.3.1 作用
执行构建命令,RUN会在shell或者exec环境下执行命令
2.3.2 语法
shell指令会在当前命令顶层执行命令
2.3.2.1 shell格式案例
RUN echo Hello World
2.3.2.2 exec格式案例
exec使用JSON格式将程序名和所需参数组成一个字符串数组,如果参数中有引号等特殊字符,需要转义。使用exec的格式避免了调用/bin/sh的消耗,但是exec不会触发shell,所以$HOME等环境变量不能使用。但是他可以在没有shell的环境中执行,可以避免解析命令错误字符串
RUN ["程序名","参数1","参数2", ...]
2.4 ENV
2.4.1 作用
设置镜像环境变量指令
2.4.2 语法
ENV <key> <value>
案例:
ENV TARGET_DIR /app
// 使用环境变量
WORKDIR $TARGET_DIR
2.5 COPY
2.5.1 作用
复制文件
2.5.2 语法
ENV <文件原路径> <目标路径>
2.6 ADD
2.6.1 作用
添加文件,可以从一个URL地址下载内容复制到容器的文件系统中,还可以将压缩打包格式的文件解压后复制到指定位置
2.6.2 语法
ADD File /Images/Path/File
ADD Itaest.tar.gz /var/www/
注意: ADD构建镜像大小比COPY要大,如果只是赋值文件,建议COPY
注意2:
- ADD不能使用相对路径
- 如果目的路径不存在,会自动创建
- ADD指令会使得构建缓存无效
2.7 EXPOSE
2.6.1 作用
指定端口暴露。表明这个景象中的应用将会监听某个端口,并且希望这个端口映射到网络界面上。一般为了安装,docker run命令日过没有带上响应的端口映射参数,docker将不会安把端口映射出去
2.6.2 语法
EXPOSE <端口> [<端口> ···]
2.8 CMD
2.8.1 作用
设置镜像启动命令。Docherfile只允许使用一次CMD命令 ,使用多个CMD会低效之前所有的指令,只有最后一个执行生效。一般来说这是整个Dockerfile最后一条命令。
2.8.2 语法
CMD ["executable", "param1", "param2", ···]
案例:
ENV TARGET_DIR /app
// 使用环境变量
WORKDIR $TARGET_DIR
注意: docker run可以覆盖CMD命令。如果docker run 后面出现与CMD后相同的指令,那么CMD会被覆盖
案例
# 没有被覆盖案例
[root@localhost docker]# docker run hello
Hello World
# 被覆盖案例
[root@localhost docker]# docker run hello echo "这个指令被覆盖了"
这个指令被覆盖了
[root@localhost docker]#
2.8.3 CMD和RUN的区别
RUN是在build时就运行的,所以RUN只在创建镜像时执行一次,固化在image中,CMD在每次启动容器时都会执行。
2.9 ENTRYPORINT
2.9.1 作用
设置接入点
2.9.2 案例
Dockerfile内容
FROM ubuntu
ENTRYPORINT ["echo"]
使用
docker build -t test .
...
docker run test 'Hellp Docker'
2.10 VOLUME(后面有单独章节介绍)
2.10.1 作用
基于镜像创建容器添加数据卷,即在容器中设置一个挂载点,可以让其他容器挂载或让宿主机访问,以实现数据共享或对容器数据的备份、恢复或迁移。
2.10.2 VOLUME特点
- 数据卷可以在容器间共享和重用
- 数据卷的修改是立即生效的
- 数据卷的修改不会对更新镜像产生影响
- 数据卷会一直存在,知道容器没有使用它
2.10.3 VOLUME使用格式
VOLUME ["/data", "/data2"]
VOLUME /data
2.11 USER
2.11.1 作用
设置构建用户,这个命令可以通过docker run命令的-u选项来覆盖
2.11.2 VOLUME使用格式
USER user
USER user:group
User user:gid
2.12 WORKDIR
2.12.1 作用
指定RUN、CMD和ENTRYPOINT命令工作目录。若指定多次,后面的路径会覆盖前面的路径
2.12.2 WORKDIR使用格式
WORKDIR path
2.13 ONBUILD
2.13.1 作用
设置二次构建指令。ONBUILD指定在构建镜像时并不执行,而是在它的子镜像中执行。
2.13.2 ONBUILDE使用案例
# 父容器中Dockerfile内容
FROM busybox
ONBUILD RUN echo "第二次构建(子构建)才执行"
# 构建父镜像
docker build -t father .
# 构建过程中不会打印第二次构建(子构建)才执行
创建子容器
# 子容器中Dockerfile内容
FORM father
# 构建子镜像
docker build -t child .
# 构架过程中打印了第二次构建(子构建)才执行
2.14 LABEL
2.14.1 作用
设置元数据的LABEL。该指令添加元数据到镜像,每一个标签都会生成一个layer,所以精良使用一个LABEL标签
2.14.2 LABEL使用案例
LABEL multi.label1="value1" \
multi.label2="value2" \
multi.label3="value3"
2.15 ARG
2.15.1 作用
设置可以在构建时使用的变量,这个参数只会在构建时存在。效果同docker build --build-arg
2.16 STOPSIGNAL
2.16.1 作用
允许用户定制化docker stop时的信号
2.16.2 案例
STOPSINGAL SIGKILL
上述容器在停止时,会发送SIGKILL信号(一些不能接受正常退出信号的容器)
2.17 HEALTHCHECK
2.17.1 作用
检查健康状态。用来检查容器启动运行时是否正常,正常返回healthy,否则返回unhealthy
2.17.2 语法
HEALTHCHECK [OPTIONS] CMD command
''''
OPTIONS详解:
--interval=DURATION
设置在容器启动多长时间后开始检查容器状态,默认30s
--timeout=DURATION
设置超时时间,超过这个时间不返回信息,默认30s
--retries=N
设置重试次数,默认为3
'''
2.17.4 案例
HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost/ || exit 1
2.18 SHELL
2.18.1 作用
设置命令执行环境的SHELL命令。linux默认SHELL命令使用/bin/sh。windows默认使用cmd。如果要更换,使用这个命令
2.17.2 案例
# 在Windows下更换powershell为默认shell环境
SHELL ["powershell", "-command"]
三、实战案例
3.1 项目内容
构建pageKit CMS镜像
3.2 Dockerfile内容
// 填写镜像维护者信息
FROM ubuntu:trusty
MAINTAINER Username<email@email.com>
// 安装运行环境
RUN apt-get update && \
apt-get -y install \
nginx \
unzip \
wget \
ca-certification\
php5 php5-fpm php5-cli php5-json php5-mysql php5-curl
// 安装pagekit
ENV PAGEJIT_VERSION 1.0.2
RUN mkdir /pagekit
WORKDIR /pagekit
VOLUME ["/pagekit/storage", "/pagekit/app/cache"]
// 从GitHub上拉取相应版本的Pagekit包
RUN Wget https://github.como/pagekit/release/download/$PAGEJIT_VERSION/pagekit-$PAGEJIT_VERSION/zip -O /pagekit/pagekit.zip && \
unzip /pagekit/pagekit.zip && rm /pagekit/pagekit.zip
// 配置Nginx和清理镜像
ADD nginx.conf /etc/ngix/nginx.conf
RUN chown -R www-data: /pagekit && \
apt-get autoremove wget unzip -y && \
apy-get autoclean -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
CMD ["sh", "-c", "service php5-fpm" start && nginx]