之前简单学过Docker,当时是为了快速部署一个项目,过的很快,对于Dockerfile文件的编写,有些显的陌生。
所以就写了这篇文章。希望能够帮助到大家哦!!!
Dockerfile是用来构建Docker镜像的构建文件,由一系列命令和参数构成的脚本
FROM scratch #真正的基础镜像,
ADD centos-7-x86_64-docker.tar.xz /
# label 说明的意思
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20201113" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-11-13 00:00:00+00:00"
CMD ["/bin/bash"] #最后一行执行的命令
在哪找到的勒,在hub.docker.com上找到滴:centos。
我们不会,但是可以先去看看人家怎么写的,抄作业这事,我想大家都熟悉吧。俗称CV大法😂。
FROM scratch #真正的基础镜像,
ADD centos-7-x86_64-docker.tar.xz /
#这就是注释
后文有案例,结合案例回过来看更容易理解。
小小番外:
在现阶段,我们将Dockerfile、Docker镜像和Docker容器看待为软件的三个不同阶段。
Dockerfile面向开发—>Docker镜像成为交付标准—>Docker容器则涉及部署与运维
Dockerfiel保留字指令大致有以下:
基础镜像,即当前新镜像是基于哪个镜像创建的。
#基于openjdk:8 创建镜像
FROM openjdk:8
镜像维护者的姓名和邮箱地址
MAINTAINER 宁在春<crush@163.com>
容器构建时需要运行的指令
RUN mkdir -p /conf/my.cn
当前容器对外暴露的端口
#暴露出MyCat的所需端口
EXPOSE 8066 9066
指定在创建容器后,终端默认登录的进来工作目录
#容器数据卷,用于数据保存和持久化工作
WORKDIR /usr/local/mycat
用来在构建镜像过程中设置环境变量
#用来在构建镜像过程中设置环境变量ENV MYCAT_HOME=/usr/local/mycat
这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量。
如:
RUN $MYCAT_HOME/mycat
ADD:
将宿主机目录下的文件拷贝进镜像,并且ADD命令会自动处理URL和解压tar压缩包
ADD centos-6-docker.tar.xz /
COPY:
类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
COPY src destCOPY ["src" "dest"]
容器数据卷,用于数据持久化和数据保存。
#将mycat的配置文件的地址暴露出映射地址,启动时直接映射宿主机的文件夹VOLUME /usr/local/mycat
CMD
CMD的指令和RUN相似,也是两种格式:
Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。
ENTRYPOINT
指定一个容器启动时要运行的命令。
ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。
区别:
在这里先简单说明一下区别,你可以将CMD理解为覆盖
CMD cat /conf/my.cnfCMD /bin/bash
这两条指令都写在Dockerfile文件中,只会执行CMD /bin/bash ,而不会执行CMD cat /conf/my.cnf,因为CMD /bin/bash把上一条直接覆盖掉了。
而ENTRYPOINT则不同,你可以将ENTRYPOINT简单理解为追加。
主要体现在docker run上,如果使用dockerfile文件中最后是CMD结尾,则在运行时不能够额外追加命令,否则会覆盖掉Dockerfile中的CMD命令。
而Dockerfile文件中最后一行为ENTRYPOINT结尾时,你可以在docker run命令后追加一些命令.
当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后,父镜像的onbuild被触发。
我们先从阿里云上拉取一个centos看看,看看有哪些问题,然后我们再进行自定义。
docker pull centos # 拉取镜像docker run -it centos #运行镜像# ===== 测试====vim ceshi.txtifconfig pwd
为什么会这样?因为docker仓库中的Centos是精简版,其只有内核,没有其它的东西。
要求自定义的Centos能够解决上述问题。
为我们自定义的Centos 编写Dockerfile文件
FROM centosMAINTAINER 宁在春<crush@163.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80 CMD echo $MYPATHCMD echo "success"CMD /bin/bash #只会运行最后一个
然后把这个复制进去即可。
mkdir -p /usr/local/docker/mycentos # 自己创建存放的位置vim Dockerfile
docker build -f /usr/local/docker/mycentos/Dockerfile -t mycentos:1.1 .
解释:
docker build -f Dockerfile文件 -t 镜像名:tag .
docker build -t 镜像名:tag .docker build -t mycentos:1.1 .
执行:
看到最后的这个就是代表成功了。
docker images查看全部镜像:
docker run -it mycentos:1.3pwdifconfig
之所以我们进去容器的目录会从/切换到/usr/local是因为在dockerfile文件中已经写明。
ENV MYPATH /usr/localWORKDIR $MYPATH
docker history mycentos:1.1
在这里也可以看出来,镜像它是由Dockerfile文件中的指令,一层一层构建出来的。
编写dockerfile文件,命名为dockerfile2
FROM centosRUN yum -y install curlONBUILD RUN echo "我被子镜像继承了,输出此条语句"CMD ["crul", "-s","http://ip.cn"]
docker build -f /usr/local/docker/mycentos/Dockerfile2 -t my_father_centos .
编写dockerfile文件,命名为dockerfile3哈
FROM my_father_centosRUN yum -y install curlCMD ["crul", "-s","http://ip.cn"]
docker build -f /usr/local/docker/mycentos/Dockerfile3 -t my_son_centos .
可以看到父镜像中的语句被输出了。