是什么
Dockerfile 是用来构建 Docker 镜像的构建文件,是由一系列命令和参数构成的脚本。
构建三步骤
- 编写 Dockerfile 文件
- docker build
- docker run
文件什么样???
以我们熟悉的 CentOS 为例
DockerFile 构建过程解析
Dockerfile内容基础知识
- 1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 2:指令按照从上到下,顺序执行
- 3:# 表示注释
- 4:每条指令都会创建一个新的镜像层,并对镜像进行提交
Docker 执行 Dockerfile 的大致流程
类似千层饼,一层包一层 ,每一层都是一个镜像。
(1)docker 从基础镜像运行一个容器
(2)执行一条指令并对容器作出修改
(3)执行类似 docker commit 的操作提交一个新的镜像层
(4)docker 再基于刚提交的镜像运行一个新容器
(5)执行 dockerfile 中的下一条指令直到所有指令都执行完成
小总结
从应用软件的角度来看,Dockerfile、Docker 镜像与 Docker 容器分别代表软件的三个不同段,
- Dockerfile 是软件的原材料
- Docker 镜像是软件的交付品
- Docker 容器则可以认为是软件的运行态。
Dockerfile 面向开发,Docker 镜像成为交付标准,Docker 容器则涉及部署与运维,三者缺一不可,合力充当 Docker 体系的基石。
1、Dockerfile,需要定义一个Dockerfile,Dockerfile 定义了进程需要的一切东西。Dockerfile 涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
2 、Docker 镜像,在用 Dockerfile 定义一个文件之后,docker build 时会产生一个Docker 镜像,当运行 Docker 镜像时,会真正开始提供服务;
3、 Docker 容器,容器是直接提供服务的。
DockerFile 体系结构(保留字指令)
FROM 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER 镜像维护者的姓名和邮箱地址
RUN 容器构建时需要运行的命令
EXPOSE 当前容器对外暴露出的端口
WORKDIR 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点[进入容器时,默认的目录位置]
ENV 用来在构建镜像过程中设置环境变量
ENV MY_PATH /usr/mytest
这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;
也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH
ADD 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY 类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
COPY src dest
COPY ["src", "dest"]
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD 指定一个容器启动时要运行的命令
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
ENTRYPOINT 指定一个容器启动时要运行的命令
但docker run之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
ONBUILD 当构建一个被继承的 Dockerfile 时运行命令,父镜像在被子继承后父镜像的 onbuild 被触发
小总结
案例
Base镜像(scratch)
Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的
自定义镜像 mycentos
1、编写
(1)Hub 默认CentOS 镜像什么情况
自定义 mycentos 目的 使我们自己的镜像具备如下:
- 登陆后的默认路径
- vim 编辑器
- 查看网络配置 ifconfig 支持
(2)准备编写 DockerFile 文件
(3)myCentOS 内容 DockerFile
FROM centos
MAINTAINER zzyy<zzyy167@126.com>
# 默认路径
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 构建时需要运行的指令
RUN yum -y install vim
RUN yum -y install net-tools
# mycentos 暴露的端口
EXPOSE 80
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash
2、构建
docker build 命令最后有一个 . . 表示当前目录
docker build -t 新镜像名字:TAG .
3、运行
docker run -it 新镜像名字:TAG
可以看到,我们自己的新镜像已经支持 vim / ifconfig 命令,扩展成功了。
4、列出镜像的变更历史
docker history 镜像名
CMD / ENTRYPOINT 镜像案例
都是指定一个容器启动时要运行的命令
CMD
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换!!!
案例:
tomcat 的讲解演示
docker run -it -p 8888:8080 tomcat ls -l
ENTRYPOINT
docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
案例:
制作 CMD 版可以查询 IP 信息的容器
FROM centos
RUN yum install -y curl
CMD [ "curl", "-s", "http://ip.cn" ]
crul 命令解释:
curl 命令可以用来执行下载、发送各种HTTP请求,指定 HTTP 头部等操作。
如果系统没有 curl 可以使用 yum install curl 安装,也可以下载安装。
curl 是将下载文件输出到 stdout
使用命令:curl http://www.baidu.com
执行后,www.baidu.com 的 html 就会显示在屏幕上了
这是最简单的使用方法。用这个命令获得了http://curl.haxx.se指向的页面,同样,如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地。如果下载的是HTML文档,那么缺省的将只显示文件头部,即HTML文档的header。要全部显示,请加参数 -i
问题
如果我们希望显示 HTTP 头信息,就需要加上 -i 参数
WHY
我们可以看到可执行文件找不到的报错,executable file not found。之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。
因此这里的 -i 替换了原来的 CMD,而不是添加在原来的 curl -s http://ip.cn 后面。而 -i 根本不是命令,所以自然找不到。
那么如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令:
docker run myip curl -s http://ip.cn -i
制作 ENTRYPOINT 版查询 IP 信息的容器
FROM centos
RUN yum install -y curl
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
自定义镜像 Tomcat9
1、
mkdir -p /zzyyuse/mydockerfile/tomcat9
2、在上述目录下 touch c.txt
3、将 jdk 和 tomcat 安装的压缩包拷贝进上一步目录
apache-tomcat-9.0.8.tar.gz
jdk-8u171-linux-x64.tar.gz
4、
在 /zzyyuse/mydockerfile/tomcat9 目录下新建 Dockerfile 文件
FROM centos
MAINTAINER zzyy<zzyybs@126.com>
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.8.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out
此时,目录内容
5、构建
6、run
运行且和主机之间建立数据卷
docker run -d -p 9080:8080 --name myt9
-v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test
-v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs
--privileged=true
zzyytomcat9
备注:Docker 挂载主机目录 Docker 访问出现 cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个 --privileged=true 参数即可
7、验证
8、
结合前述的容器卷将测试的 web 服务 tes t发布
总体概述
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi: schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>test</display-name>
</web-app>
a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
-----------welcome------------
<%="i am in docker tomcat self "%>
<br>
<br>
<% System.out.println("=============docker tomcat self");%>
</body>
</html>
测试
自定义 dockerFile 镜像
自定义 centos7 镜像
使用官方的镜像,我们发现没有没有 ifconfig ,vim 等功能,我们可以在官方的镜像基础上进行自定义,构建我们希望的镜像,然后运行容器
需求:
-
默认登录路径为 /usr
-
可以使用 vim
步骤:
- 定义父镜像:FROM centos:7
- 定义作者信息:MAINTAINER xj0927 xj0927@lxs.cn
- 执行安装 vim 命令: RUN yum install -y vim
- 定义默认的工作目录:WORKDIR /usr
- 定义容器启动执行的命令:CMD /bin/bash
- 通过 dockerfile 构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本 .
现在开始构建 dockerFile 文件:
mkdir ~/docker-files
cd ~/docker-files
vim centos_dockerfile
FROM centos:7
MAINTAINER xj0927 xj0927@lxs.cn
RUN yum install -y vim
WORKDIR /usr
CMD /bin/bash
构建:
docker build -f ./centos_dockerfile -t mycentos:1 .
- -f:镜像文件
- -t:新镜像名
- . 寻址路径
查看镜像:
docker images
运行容器:
docker run -it --name=mycentos mycentos:1
发布 springboot 项目
Spring Boot 项目:
使用 maven 打包项目:
windows 下,使用 cmd 运行 jar 包:
浏览器便可以访问:http://localhost/test
现在,把 jar 放在docker 环境中,使用 dockerFile 进行构建成镜像,然后运行容器,进行访问
Spring Boot 项目依赖 java 8,所以需要先拉取 Java 8 的镜像
docker pull java:8
现在开始构建 dockerFile 文件
vim springboot
步骤:
- 定义父镜像:FROM java:8
- 定义作者信息:MAINTAINER xj0927 xj0927@163.com
- 将 jar 包添加到容器并重命名: ADD springboot.jar app.jar
- 定义容器启动执行的命令:CMD [“java”,"-jar",“app.jar”]
- 通过 dockerfile 构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本 .
FROM java:8
MAINTAINER xj0927 xj0927@163.com
ADD springboot.jar app.jar
CMD ["java","-jar","app.jar"]
构建:
docker bulid –f ./springboot –t app .
查看镜像:
docker images
启动容器 :
docker run -id -p 9090:80 --name=springboot app
访问测试: http://192.168.77.138:9090/test
此时,便可以在别的主机上[ 这里使用的windows ]访问 Linux 上的 9090端口的宿主机,因为进行了端口映射,便可以访问到 启动的 springboot 容器