Docker(四) Dockerfile 详解
一、Dockerfile文件介绍
1.1 什么是Dockerfile
Dockerfile 是构建docker镜像的构建文件,是由一系列命令和参数构成的脚本,即构建镜像的脚本文件。如下为centos的镜像Dockerfile内容:
FROM scratch
ADD centos-8-x86_64.tar.xz /
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="20200809"
CMD ["/bin/bash"]
构建命令:docker build -t 名称:[版本] .
1.2 编写语法
Dockerfile文件中每一行为一条指令;
每条指令由Dockerfile 关键词开头 并跟随至少一个参数;
# 来表示行注释;
Dockerfile文件执行由上往下逐行执行,每条指令都会创建一个镜像层,并对镜像进行提交。
1.3 构建流程
以以上1.1部分的Dockerfile文件为例,有四条语句。执行流程为:
1,使用第一层的镜像 创建一个容器A;
2,使用第二句的命令在第一层的容器A中进行修改,然后将修改后的容器 commit为一个第二层的镜像;再然后运行第二层的新的镜像生成容器B;
3,使用第三句的命令修改第二层的容器B;然后将容器commit为一个第三个镜像;并根据当前层镜像运行出一个容器C;
4,使用第四句的命令在第三层的容器C中修改,然后在把修改后的容器commit为一个新的镜像(最终镜像)。
然后没有下一条语句,流程结束。如下为Dockerfile与Docker镜像和docker容器之间关系
二、Dockerfile文件关键字介绍
FROM 基础镜像,当前镜像是基于那个镜像的。docker 大觉多数的镜像中最基础镜像都是来自scratch
MAINTAINER 镜像维护者的姓名和邮箱。
RUN 容器构建时需要运行的命令
EXPOSE 容器对外暴露的端口。
WORKDIR 创建容器后,默认登录进来的终端目录。
ENV 用来在构建过程中设置的环境变量,定义变量。
ADD 将宿主机目录下的文件在build时拷贝进镜像,并会自动处理URL及解压tar包。
COPY 类似ADD,拷贝文件和目录到镜像中,语法COPY src dest 或COPY ["src","dest"]。
VOLUME 容器数据卷,用于数据保存和数据持久化工作。
CMD 启动一个容器时,需要运行的命令。格式:CMD <命令> ;CMD["可执行文件","参数1","参数2"]
Dockerfile文件中可以有多个CMD指令,但只要最后一个生效,CMD 会被docker run 之后的参数替换掉
ENTEYPONT 指定一个容器启动时要运行的程序。
ENTEYPONT 和 CMD的作业一样 都是指定容器启动时的程序及参数,docker run 后面的参数会追加拼接到 该命令上。
OBBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子镜像继承后触发父镜像的onbuild
CMD与ENTEYPONT 差异测试:
FROM centos
CMD ["ls","-a"]
使用CMD 结尾的Dockerfile 在运行其镜像时 run 末尾跟随的参数会进行覆盖 CMD 后的命令。
通过 ls -lh 完整命令覆盖 CMD中的命令正常执行。通过 -lh 使用则会出错。
FROM centos
ENTRYPOINT ["ls","-a"]
使用ENTRYPOINT结尾的Dockerfile 在运行其镜像时 run 末尾跟随的参数会追加到 ENTRYPOINT 命令后。
使用命令 docker run -it centos_ls:1.1 ls -lh 启动容器后 ,实际在容器中执行的完整命令为 ls -a ls -lh,他会将 第二个ls当做目录来执行 故会报错如下图:
使用命令 docker run -it centos_ls:1.1 -lh 启动容器后 ,实际在容器中执行的完整命令为 ls -a -lh,不会报错。
三、编写Dockerfile文件示例
3.1 自定义centos (编写一个带有vim命令工具的centos,默认的centos镜像没有vim)
#基于centos 镜像创建
FROM centos
#指定作者名称邮箱
MAINTAINER huizi<625322503@qq.com>
#声明变量
ENV MY_WORKDIR /usr/local
#指定工作目录,进入容器时默认的目录
WORKDIR $MY_WORKDIR
#执行安装 vim 工具 -y表示安装过程中全部选是
RUN yum -y install vim
#设置对外暴露的端口 纯提示作用
EXPOSE 80
#打开一个终端
CMD echo $MY_WORKDIR
CMD echo "success---------ok"
CMD /bin/bash
在当前Dockerfile文件目录中执行打包镜像。执行命令:docker build -t centos_vim:1.0 .
执行完成后我们通过 docker images 查看我们打包的镜像。并使用run 运行查看是否正常使用vim命令,以为我们指定的工作目录是否正确。如下都符合我们Dockerfile文件中编写。
通过 docker history 镜像id 可以查看该镜像构建过程中的镜像组成
在上面的Dockerfile文件中我们有9行命令行,所以在查看构建过程中的历史镜像中会有9层镜像。镜像列表我们从下往上看其中missing的为基础镜像centos镜像Dockerfile中的命令。然后第一个镜像 0d120b6ccaa8为我们FROM的 centos 基础镜像id,通过上图蓝色划线可以看到。 然后每层语句都会生成一个镜像,最终的镜像 1a50ff6d9922 为我们打包后的最终镜像id 与 通过 images 查看的一致,如绿色箭头所指。
cmd与entrypoint
3.2 基于centos制作一个自己的tomcat镜像
分析:自定义tomcat需要 tomcat 安装包、jdk环境,centos镜像中不包含jdk和tomcat。所以我们需要在打包镜像时上传 jdk 与tomcat ,上传解压后,配置jdk和tomcat环境变量,最后再暴露端口并启动tomcat。
首先我们创建Dockerfile文件以及jdk与tomcat的安装包存放的目录
然后准备好安装包
接下来创建并编写Dockerfile
#基于centos镜像
FROM centos
#注明作者和邮箱
MAINTAINER huizi<625322503@qq.com>
#声明tomcat工作目录变量
ENV MYPATH /usr/local/tomcat
#创建jdk的安装解压命令
RUN mkdir -p /usr/local/java
#添加tomcat压缩文件到/usr/local目录下
ADD apache-tomcat-7.0.106.tar.gz /usr/local/
#添加jdk到 usr/local目录下
ADD jdk-8u261-linux-x64.tar.gz /usr/local/java
#打印/usr/local目录
RUN ls -lh /usr/local
#修改tomcat目录名称
RUN mv /usr/local/apache-tomcat-7.0.106 /usr/local/tomcat
#设置工作目录
WORKDIR $MYPATH
#配置java和tomcat环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_261
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tool.jar
ENV CATALINA_HOME /usr/local/tomcat
ENV CATALINA_BASE /usr/local/tomcat
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#设置对外暴露的端口
EXPOSE 8080
#打开一个终端 当前目录路径为工作路径
CMD bin/startup.sh && tail -F logs/catalina.out
由于ADD 命令会将tar文件自动解压,所以不需要做解压工作,我们在后续使用操作tomcat和jdk的目录时需要用解压之后的目录名称,不能用原始压缩包名。在Dockerfile 文件结尾与上面自定义centos不同的是,我们后台启动tomcat后 一般使用的 docker run -d -p port:8080 镜像名称:[版本] ,直接后台启动,为了避免启动后没有阻塞线程 如 top、tail 等,容器会立马退出,所以我们在添加启动startup.sh 之后在使用了tail 打印log日志进行保持容器一直处于运行状态。
编写完毕后,进行打包镜像 docker build -t mytomcat:1.0 . 完成后查看打包后镜像
启动容器运行访问tomcat
四、将java jar包打包发布到镜像中
本地打包好jar包后测试无问题上传到我们的新建目录下,并创建Dockerfile文件
编写Dockerfile文件,我们基于openjdk的镜像进行编写。
#基于openjdk的镜像编写
FROM adoptopenjdk/openjdk8
#定于工作目录变量
ENV MYDIR /usr/local/java
#创建目录,如果不存在逐个创建目录层级
RUN mkdir -p $MYDIR
#上传jar包到工作目录下
ADD docker.jar /usr/local/java/
#设置工作目录
WORKDIR $MYDIR
#对外暴露端口
EXPOSE 8080
#执行启动jar包
CMD java -jar docker.jar
打包镜像 : docker build -t hello-docker:1.2 .
运行启动:docker run -d -p 9999:8080 hello-docker:1.2
测试访问 :
Docker(四) Dockerfile 详解相关推荐
- Docker(四)----Docker-Compose 详解
1. 什么是Docker-Compose Compose项目来源于之前的fig项目,使用python语言编写,与docker/swarm配合度很高. Compose 是 Docker 容器进行编排的工 ...
- Docker之Dockerfile详解
使用Dockerfile创建镜像 Dockerfile是一个文本格式的配置文件,我们可以利用Dockerfile来快速的创建一个自定义的镜像. 基本结构 Dockerfile由一行命令语句组成,并且支 ...
- docker实践(2)常用命令和DockerFile详解
<docker实践(1) 入门和springBoot实践部署> <docker实践(2)常用命令和DockerFile详解> <docker实践(3) 仓库registr ...
- Docker系列07—Dockerfile 详解
Docker系列07-Dockerfile 详解 1.认识Dockerfile 1.1 镜像的生成途径 基于容器制作 dockerfile,docker build 基于容器制作镜像,已经在上篇Do ...
- docker常用命令详解
docker常用命令详解 本文只记录docker命令在大部分情境下的使用,如果想了解每一个选项的细节,请参考官方文档,这里只作为自己以后的备忘记录下来. 根据自己的理解,总的来说分为以下几种: Doc ...
- 『中级篇』Dockerfile详解(17)
一般的,Dockerfile 分为四部分:基础镜像信息.维护者信息.镜像操作指令和容器启动时执行指令. ####官网学习 https://docs.docker.com/engine/referenc ...
- 附005.Docker Compose文件详解
一 Docker Compose文件简介 compose文件使用yml格式,主要分为了四个区域: version:用于指定当前docker-compose.yml语法遵循哪个版本 services:服 ...
- Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)
文章目录 1. Dockerfile介绍 2. Dockerfile指令说明 3. 制作Centos镜像 3.1 编写Dockerfile的文件 3.2 通过这个文件构建镜像(注意最后加个点!!!) ...
- Dockerfile详解超全
Dockerfile详解 环境介绍 指令介绍 FROM MAINTAINER LABEL ADD COPY EXPOSE ENV 在Dockerfile中使用变量的方式 RUN CMD RUN& ...
最新文章
- Web性能优化之雅虎军规
- python拿来干嘛-python可以用来干什么?
- C++ 自由存储区是否等价于堆?
- 2021-01-07 python opencv实现车牌识别 颜色定位
- [转]MyBatis中resultType与resultMap区别
- ASP.NET MVC 小小总结
- Python模块:配置文件解析器configparser
- Web渗透攻击实战(2)—获取网站后台登录用户名密码
- windows下Git连接使用
- windows终端终端_Windows终端机完整指南
- Postgresql-11 根据多字段创建分区表
- 【建议背诵】2022下半年软考「高项」100题(2)
- Latex引用参考文献-BibTex的使用
- 无人驾驶清扫车落地之路的技术解析
- 使用向量的方法来计算点到直线的距离
- CTF之crpto练习三
- Win10突然就不能连接网络了怎么办
- EmEditor注册码
- 计算机网络实验4--IP动态路由搭建
- C语言 不使用strcpy 函数实现字符串复制功能