Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。 构建三步骤: 1. 编写dockerfile文件 2. docker build 3. docker run
在dockerhub网站上面以centos为例,查看其dockerfile的内容
FROM scratch ADD centos-7-x86_64-docker.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" \ 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-08-09 00:00:00+01:00" CMD ["/bin/bash"]Base镜像(scratch):Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的
Dockerfile基础知识
1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数2:指令按照从上到下,顺序执行3:#表示注释4:每条指令都会创建一个新的镜像层,并对镜像进行提交Docker执行Dockerfile的大致流程
1:docker从基础镜像运行一个容器2:执行一条指令并对容器作出修改3:执行类似docker commit的操作提交一个新的镜像层4:docker再基于刚提交的镜像运行一个新容器5:执行dockerfile中的下一条指令直到所有指令都执行完成DockerFile 、Docker镜像、Docker容器的关系:
Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;
Docker容器,容器是直接提供服务的。
背景:使用从dockerhub上面拉取的镜像是没有vim 和ifconfig 命令的,这里我们自定义一个镜像,使得我们的centos镜像创建容器时候就自带这两个命令
构建DockerFile文件
[root@bigdata01 mydocker]# cd /mydocker/ [root@bigdata01 mydocker]# vi dockerfile2 FROM centos MAINTAINER nice<xxx@163.com> ENV mypath /usr/local WORKDIR /tmp RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "success----ok" CMD /bin/bashBuild Dockerfile
[root@bigdata01 mydocker]# docker build -f /mydocker/dockerfile2 -t nice/mycentos:1.3 . Sending build context to Docker daemon 3.072kB Step 1/10 : FROM centos ---> 831691599b88 Step 2/10 : MAINTAINER nice<nicecloudcode@163.com> ---> Running in 1bfae7ed3784 Removing intermediate container 1bfae7ed3784 ---> 608ee480d3a5 Step 3/10 : ENV mypath /usr/local ---> Running in 5cde4bf46590 Removing intermediate container 5cde4bf46590 ---> 3eaa07e83274 Step 4/10 : WORKDIR /tmp ---> Running in 924295eb2a3c Removing intermediate container 924295eb2a3c ---> 33a0398d93d9 Step 5/10 : RUN yum -y install vim ---> Running in 623dedacee36 CentOS-8 - AppStream 669 kB/s | 5.8 MB 00:08 CentOS-8 - Base 329 kB/s | 2.2 MB 00:06 CentOS-8 - Extras 8.1 kB/s | 7.3 kB 00:00 Dependencies resolved. 、、、、、、 Total download size: 323 k Installed size: 1.0 M Downloading Packages: net-tools-2.0-0.51.20160912git.el8.x86_64.rpm 1.4 MB/s | 323 kB 00:00 -------------------------------------------------------------------------------- Total 395 kB/s | 323 kB 00:00 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : net-tools-2.0-0.51.20160912git.el8.x86_64 1/1 Running scriptlet: net-tools-2.0-0.51.20160912git.el8.x86_64 1/1 Verifying : net-tools-2.0-0.51.20160912git.el8.x86_64 1/1 Installed: net-tools-2.0-0.51.20160912git.el8.x86_64 Complete! Removing intermediate container 41b956ae87fe ---> 1a38831365ae Step 7/10 : EXPOSE 80 ---> Running in a8c44ccb84fa Removing intermediate container a8c44ccb84fa ---> 74743b39aa23 Step 8/10 : CMD echo $MYPATH ---> Running in 320eb480e5c8 Removing intermediate container 320eb480e5c8 ---> 6528ca7b7306 Step 9/10 : CMD echo "success----ok" ---> Running in 9f6bdf0a76c5 Removing intermediate container 9f6bdf0a76c5 ---> 58635bf5cf92 Step 10/10 : CMD /bin/bash ---> Running in 8fbcefef7924 Removing intermediate container 8fbcefef7924 ---> b9e08611155a Successfully built b9e08611155a Successfully tagged nice/mycentos:1.3 [root@bigdata01 mydocker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nice/mycentos 1.3 b9e08611155a 30 seconds ago 295MBrun docker 容器
[root@bigdata01 mydocker]# docker run -it b9e08611155a [root@d698b05d8ce9 tmp]# pwd /tmp以上可以知道,docker默认的工作目录是/tmp 目录,与我们设置的相同
使用docker history 命令查看镜像的构建历史
[root@bigdata01 mydocker]# docker history b9e08611155a IMAGE CREATED CREATED BY SIZE COMMENT b9e08611155a 3 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B 58635bf5cf92 3 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B 6528ca7b7306 3 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B 74743b39aa23 3 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B 1a38831365ae 3 minutes ago /bin/sh -c yum -y install net-tools 22.7MB c02d91a59e73 3 minutes ago /bin/sh -c yum -y install vim 57.2MB 33a0398d93d9 3 minutes ago /bin/sh -c #(nop) WORKDIR /tmp 0B 3eaa07e83274 3 minutes ago /bin/sh -c #(nop) ENV mypath=/usr/local 0B 608ee480d3a5 3 minutes ago /bin/sh -c #(nop) MAINTAINER nice<nicecloud… 0B 831691599b88 2 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 2 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 2 months ago /bin/sh -c #(nop) ADD file:84700c11fcc969ac0… 215MBCMD和ENTRYPOINT的区别?
相同点:CMD和ENTRYPOINT都是指定一个容器启动时要运行的命令
不同点:Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换,而ENTRYPOINT在docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
案例需求:构造两个镜像,一个基于CMD指令,另一个基于ENTRYPOINT指令,分别测试两个指令的区别与联系
编写两个dockerfile
# CMD FROM centos RUN yum install -y curl CMD [ "curl", "-s", "http://ip.cn" ] # ENTRYPOINT FROM centos RUN yum install -y curl ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]构建镜像:
# 构建CMD镜像 [root@bigdata01 mydocker]# docker build -f /mydocker/dockerfile-centos-cmd -t nice/centos-cmd:1.0 "docker build" requires exactly 1 argument. See 'docker build --help'. age: docker build [OPTIONS] PATH | URL | - Build an image from a Dockerfile [root@bigdata01 mydocker]# docker build -f /mydocker/dockerfile-centos-cmd -t nice/centos-cmd:1.0 . Sending build context to Docker daemon 5.12kB Step 1/3 : FROM centos ---> 831691599b88 Step 2/3 : RUN yum install -y curl ---> Running in 9a15d717941c CentOS-8 - AppStream 1.5 MB/s | 5.8 MB 00:03 CentOS-8 - Base 982 kB/s | 2.2 MB 00:02 CentOS-8 - Extras 4.1 kB/s | 7.3 kB 00:01 Package curl-7.61.1-12.el8.x86_64 is already installed. Dependencies resolved. Nothing to do. Complete! Removing intermediate container 9a15d717941c ---> 0e16c491ea85 Step 3/3 : CMD [ "curl", "-s", "http://ip.cn" ] ---> Running in 86fd8a2acbce Removing intermediate container 86fd8a2acbce ---> ad79bf05cf4b Successfully built ad79bf05cf4b Successfully tagged nice/centos-cmd:1.0 # 构建ENTRYPOINT镜像 [root@bigdata01 mydocker]# docker build -f /mydocker/dockerfile4 -t nice/centos-e:2.0 . Sending build context to Docker daemon 5.12kB Step 1/3 : FROM centos ---> 831691599b88 Step 2/3 : RUN yum install -y curl ---> Using cache ---> 0e16c491ea85 Step 3/3 : ENTRYPOINT [ "curl", "-s", "http://ip.cn" ] ---> Running in 7c33111bbca1 Removing intermediate container 7c33111bbca1 ---> 553ff57039a7 Successfully built 553ff57039a7 Successfully tagged nice/centos-e:2.0 [root@bigdata01 mydocker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nice/centos-e 2.0 553ff57039a7 17 seconds ago 235MB nice/centos-cmd 1.0 ad79bf05cf4b 11 minutes ago 235MB nice/mycentos 1.3 b9e08611155a 2 hours ago 295MB nice/centos latest 2da0623d0d63 2 weeks ago 215MB nice/mytomcat latest f183c09f98b7 3 weeks ago 652MB tomcat latest 2ae23eb477aa 4 weeks ago 647MB nginx latest 08393e824c32 4 weeks ago 132MB centos latest 831691599b88 2 months ago 215MB hello-world latest bf756fb1ae65 8 months ago 13.3kB进行测试:
[root@bigdata01 mydocker]# docker run -it ad79bf05cf4b -i docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-i\": executable file not found in $PATH": unknown. [root@bigdata01 mydocker]# docker run -it 553ff57039a7 -i HTTP/1.1 301 Moved Permanently Date: Thu, 03 Sep 2020 09:59:11 GMT Transfer-Encoding: chunked Connection: keep-alive Cache-Control: max-age=3600 Expires: Thu, 03 Sep 2020 10:59:11 GMT Location: https://ip.cn/ cf-request-id: 04f500fa8f0000930aa20c8200000001 Server: cloudflare CF-RAY: 5cce9dd74c8a930a-SJC alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400由以上可以看出使用CMD进行构建镜像的时候,在run容器的时候附加的命令会覆盖原来的CMD的命令,但是在使用ENTRYPOINT构建的进行,在run的时候附加的命令会追加到原来命令的后面组合成一个新的命令
目标:从centos构建一个tomcat镜像,安装JDK和tomcat ,配置共享目录,并使用案例进行测试
1.创建文件夹用于存放我们的文件2.上传tomcat 和JDK的压缩包3.编写DockerFile 文件4.创建c.txt 用于测试文件移动5.创建test 和tomcat-logs文件夹 mkdir -p /mydocker/mytomcat [root@bigdata01 mytomcat]# tree . ├── apache-tomcat-8.5.34.tar.gz ├── c.txt ├── Dockerfile ├── jdk-8u221-linux-x64.tar.gz └── test │ ├── hello.jsp │ └── WEB-INF │ └── web.xml └── tomcat-logsDockerfile 的内容如下:
FROM centos MAINTAINER nice<nice@126.com> #把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下 COPY c.txt /usr/local/cincontainer.txt #把java与tomcat添加到容器中 ADD jdk-8u221-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-8.5.34.tar.gz /usr/local/ #安装vim编辑器 RUN yum -y install vim #设置工作访问时候的WORKDIR路径,登录落脚点 ENV MYPATH /usr/localWORKDIR $MYPATH #配置java与tomcat环境变量 ENV JAVA_HOME /usr/local/jdk1.8.0_221 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.34 ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.34 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #容器运行时监听的端口 EXPOSE 8080 #启动时运行tomcat # ENTRYPOINT ["/usr/local/apache-tomcat-8.5.34/bin/startup.sh" ] # CMD ["/usr/local/apache-tomcat-8.5.34/bin/catalina.sh","run"] CMD /usr/local/apache-tomcat-8.5.34/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.34/bin/logs/catalina.out构建镜像
docker build -f /mydocker/mytomcat/Dockerfile -t nice/tomcat:1.0 .启动容器
docker run -d -p 8888:8080 --name tomcat2 \ -v /mydocker/mytomcat/test:/usr/local/apache-tomcat-8.5.34/webapps/test \ -v /mydocker/mytomcat/tomcat-logs/:/usr/local/apache-tomcat-8.5.34/logs \ --privileged=true \ f29ace801e39浏览器访问地址:http://192.168.52.50:8888/ 出现tomcat的猫图像 在test文件夹下面创建WEB-INF文件夹和hello.jsp,并且在WEB-INF里面创建web.xml 文件 hello.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>web.xml 的内容如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://www.example.org/web-app_2_5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd" version="2.5"> <display-name>test</display-name> </web-app>创建之后重启容器,因为在本机的目录创建的文件,这里是和容器内的目录共享,所以重启容器之后即可访问测试
docker restart containerID浏览器访问:http://192.168.52.50:8888/test/hello.jsp 访问成功