Dockerfile详解与镜像发布
2021/9/22 6:11:05
本文主要是介绍Dockerfile详解与镜像发布,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1. Dockerfile介绍
Dockerfile是用来构建Docker镜像的文件,它是一个文本文件,也可以说是命令参数脚本。Dcoker根据该文件生成二进制的image文件。
Docker镜像发布的步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 镜像
4、docker push 镜像(发布镜像到DockerHub、阿里云镜像仓库)
示例一个镜像的结构图:
2. Dockerfile指令说明
指令 | 说明 |
---|---|
FROM | 指定基础镜像 |
MAINTAINER | 镜像是谁写的,姓名+邮箱 |
RUN | 镜像构建的时候需要运行的命令 |
ADD | 添加构建步骤,如添加一个tomcat镜像 |
WORKDIR | 镜像的工作目录 |
VOLUME | 挂载的目录 |
EXPOSE | 保留端口配置 |
CMD | 指定这个容器启动的时候要运行的命令(只有最后一个会生效) |
EMTRYPOINT | 指定这个容器启动的时候要运行的命令,可以追加命令 |
ONBUILD | 当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令,触发指令 |
COPY | 类似于ADD ,将我们文件拷贝到镜像中 |
ENV | 构建的时候设置环境变量 |
一个形象的解释各个指令作用的图:
关于DockerFile文件的脚本注意点有:
1、每个保留关键字(指令)都必须是大写字母
2、文件中的指令从上到下顺序执行
3、# 号表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!
3. 制作Centos镜像
下面通过编写Dockerfile文件来制作Centos镜像,并在官方镜像的基础上添加vim和net-tools工具。首先在/home/dockfile 目录下新建文件mydockerfile-centos。然后使用上述指令编写该文件。
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# cat mydockerfile-centos FROM centos MAINTAINER ethan<1258398543@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "---end---" CMD /bin/bash
逐行解释该Dockerfile文件的指令:
- FROM centos:该image文件继承官方的centos,后面加冒号如centos:7,用于指定镜像的版本
- ENV MYPATH /usr/local:设置环境变量MYPATH ,后面有用到
- WORKDIR $MYPATH:直接使用上面设置的环境变量,指定/usr/local为工作目录
- RUN yum -y install vim和RUN yum -y install net-tools:在/usr/local目录下,运行yum -y install vim和yum -y install net-tools命令安装工具,注意安装后的所有依赖和工具都会打包到image文件中
- EXPOSE 80:将容器80端口暴露出来,允许外部连接这个端口
- CMD:指定容器启动的时候运行命令
通过这个dockerfile构建镜像,构建镜像命令:docker build -f dockerfile文件路径 -t 镜像名[:版本号] .
(这里有个小点.)
上面命令中,-t
参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。
下面执行build命令生成image文件,如果执行成功,可以通过docker images来查看新生成的镜像文件。
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker build -f mydockerfile-centos -t mycentos:1.0 . Sending build context to Docker daemon 2.048kB Step 1/10 : FROM centos ---> 300e315adb2f Step 2/10 : MAINTAINER ethan<1258398543@qq.com> ---> Running in bbfd1a4949e1 Removing intermediate container bbfd1a4949e1 ---> b2b6851e55fa Step 3/10 : ENV MYPATH /usr/local ---> Running in 7cd8c84a5b70 Removing intermediate container 7cd8c84a5b70 ---> e27a56b5247b Step 4/10 : WORKDIR ${MYPATH} ---> Running in 770e175260c4 Removing intermediate container 770e175260c4 ---> 7d46880ef0fd Step 5/10 : RUN yum -y install vim Step 7/10 : EXPOSE 80 ---> Running in 24cfcfa56460 Removing intermediate container 24cfcfa56460 ---> 2064c1540e8e Step 8/10 : CMD echo ${MYPATH} ---> Running in 83dd9766da3c Removing intermediate container 83dd9766da3c ---> 9b8661c812c4 Step 9/10 : CMD echo "---end---" ---> Running in 974afa805b27 Removing intermediate container 974afa805b27 ---> 83459c404586 Step 10/10 : CMD /bin/bash ---> Running in 4fba3174f9d8 Removing intermediate container 4fba3174f9d8 ---> 1185a46e3a12 Successfully built 1185a46e3a12 Successfully tagged mycentos:1.0 [root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 1.0 1185a46e3a12 4 minutes ago 291MB
下面生成容器,测试相关命令,查看默认工作目录是否设置成功,vim和net-tools工具是否下载成功。
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run -it mycentos:1.0 [root@e548efe82b30 local]# pwd /usr/local #net-tools工具提供ifconfig命令 [root@e548efe82b30 local]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@e548efe82b30 local]# vi test.txt [root@e548efe82b30 local]# cat test.txt Hello world!
另外,我们通过docker history 容器id
命令来查看镜像的构建步骤
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker history 1185a46e3a12 IMAGE CREATED CREATED BY SIZE COMMENT 1185a46e3a12 13 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B 83459c404586 13 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B 9b8661c812c4 13 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B 2064c1540e8e 13 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B 1b15d4a1fd5e 13 minutes ago /bin/sh -c yum -y install net-tools 23.3MB 9336c20f0b6d 13 minutes ago /bin/sh -c yum -y install vim 58MB 7d46880ef0fd 14 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B e27a56b5247b 14 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B b2b6851e55fa 14 minutes ago /bin/sh -c #(nop) MAINTAINER ethan<12583985… 0B 300e315adb2f 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 3 weeks ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
4. RUN,CMD和ENTRYPOINT的区别
RUN命令与CMD命令的区别在哪里?
简单说,RUN命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个RUN命令,但是只能有一个CMD命令。
注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。
CMD和ENTRYPOINT的区别在哪里?
-
CMD :指定容器启动的时候要运行的命令,只有最后一个会生效
-
ENTRYPOINT :指定容器启动的时候要运行的命令,命令可以追加
首先是使用CMD指令
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# cat dockerfile-cmd-test FROM centos CMD ["ls","-a"] [root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest:1.0 . Sending build context to Docker daemon 3.072kB Step 1/2 : FROM centos ---> 300e315adb2f Step 2/2 : CMD ["ls","-a"] ---> Running in 6d4d0112322f Removing intermediate container 6d4d0112322f ---> b6ec5224d2ac Successfully built b6ec5224d2ac Successfully tagged cmdtest:1.0 [root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run cmdtest:1.0 . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var #由于使用的是 CMD指令,命令无追加,-l取代了原本的ls -a,而-l命令不存在所以报错。 [root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run cmdtest:1.0 -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
可以看到追加命令-l 出现了报错。
下面使用ENTRYPOINT来构建一个镜像
#1.修改dockerfile文件 [root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# cat dockerfile-cmd-test FROM centos ENTRYPOINT ["ls","-a"] #2.构建镜像 [root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest:2.0 . Sending build context to Docker daemon 3.072kB Step 1/2 : FROM centos ---> 300e315adb2f Step 2/2 : ENTRYPOINT ["ls","-a"] ---> Running in 61389c0c1967 Removing intermediate container 61389c0c1967 ---> ac7b7e83ff88 Successfully built ac7b7e83ff88 Successfully tagged cmdtest:2.0 #3.运行镜像 [root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run cmdtest:2.0 . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var #4.追加镜像再次运行 [root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run cmdtest:2.0 -l total 56 drwxr-xr-x 1 root root 4096 Jan 1 03:55 . drwxr-xr-x 1 root root 4096 Jan 1 03:55 .. -rwxr-xr-x 1 root root 0 Jan 1 03:55 .dockerenv lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin drwxr-xr-x 5 root root 340 Jan 1 03:55 dev drwxr-xr-x 1 root root 4096 Jan 1 03:55 etc drwxr-xr-x 2 root root 4096 Nov 3 15:22 home lrwxrwxrwx 1 root root 7 Nov 3 15:22 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64 drwx------ 2 root root 4096 Dec 4 17:37 lost+found drwxr-xr-x 2 root root 4096 Nov 3 15:22 media drwxr-xr-x 2 root root 4096 Nov 3 15:22 mnt drwxr-xr-x 2 root root 4096 Nov 3 15:22 opt dr-xr-xr-x 106 root root 0 Jan 1 03:55 proc dr-xr-x--- 2 root root 4096 Dec 4 17:37 root drwxr-xr-x 11 root root 4096 Dec 4 17:37 run lrwxrwxrwx 1 root root 8 Nov 3 15:22 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 3 15:22 srv dr-xr-xr-x 13 root root 0 Dec 29 15:41 sys drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
5. 制作Tomcat镜像并发布镜像
5.1 制作Tomcat镜像
1.准备镜像文件tomcat、jdk压缩包
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# vi readme.txt [root@iZwz99sm8v95sckz8bd2c4Z tomcat]# ll total 200700 -rw-r--r-- 1 root root 10371538 Jan 1 16:11 apache-tomcat-8.5.55.tar.gz -rw-r--r-- 1 root root 195132576 Jan 1 16:13 jdk-8u251-linux-x64.tar.gz -rw-r--r-- 1 root root 20 Jan 1 16:14 readme.txt
2.编写dockerfile文件,文件名使用官方命名:Dockerfile ,build的时候会默认寻找当前目录下的文件,不需要使用-f参数指定
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# vim Dockerfile [root@iZwz99sm8v95sckz8bd2c4Z tomcat]# cat Dockerfile FROM centos MAINTAINER ethan<1258398543@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u251-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-8.5.55.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_251 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55 ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.55 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-8.5.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.55/bin/logs/catalina.out
3.使用该Dockerfile构建镜像
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# docker build -t diytomcat:1.0 .
4.启动生成的镜像,构建Tomcat容器.
这里设置了数据卷,宿主机的/home/dockerfile/tomcat/test对应该容器的/usr/local/apache-tomcat-8.5.55/webapps/test。这样关于test项目的修复只需要在宿主机上修改就可以了,不需要进入到容器中修改。
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# docker run -d -p 8088:8080 --name diytomcat -v /home/dockerfile/tomcat/test:/usr/local/apache-tomcat-8.5.55/webapps/test diytomcat:1.0
5.在/home/dockerfile/tomcat/test的目录下,新建index.html 测试Tomcat是否能正常使用。
因为设置了卷挂载所以可以直接在宿主机中进行操作。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>这是个标题</title> </head> <body> <h1>这是一个一个简单的HTML</h1> <p>Hello World!</p> </body> </html>
6.访问测试,浏览器访问查看是否能正常访问
如果页面显示乱码,就需要修改tomcat的server.xml文件
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
这里是添加了一个属性:URIEncoding,将该属性值设置为UTF-8,即可让Tomcat(默认ISO-8859-1编码)以UTF-8的编码处理get请求。
5.2 发布镜像到DockerHub
1.登录https://hub.docker.com/ DockerHub官网进行注册
2.进行登录,docker login -u 用户名
登录命令
[root@iZwz99sm8v95sckz8bd2c4Z test]# docker login --help Usage: docker login [OPTIONS] [SERVER] Log in to a Docker registry. If no server is specified, the default is defined by the daemon. Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Usernames
3.使用docker push
命令推送镜像到DockerHub上的仓库
[root@iZwz99sm8v95sckz8bd2c4Z test]# docker tag 0975df661526 ethanhuang824/diytomcat:1.0 [root@iZwz99sm8v95sckz8bd2c4Z test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE diytomcat 1.0 0975df661526 About an hour ago 688MB ethanhuang824/diytomcat 1.0 0975df661526 About an hour ago 688MB cmdtest 2.0 ac7b7e83ff88 6 hours ago 209MB cmdtest 1.0 b6ec5224d2ac 6 hours ago 209MB ethan/centos 1.0 1df90e6fd790 2 days ago 209MB mytomcat 1.0 f189aac861de 3 days ago 653MB mysql 5.7 f07dfa83b528 10 days ago 448MB tomcat latest feba8d001e3f 2 weeks ago 649MB nginx latest ae2feff98a0c 2 weeks ago 133MB centos latest 300e315adb2f 3 weeks ago 209MB elasticsearch 7.6.2 f29a1ee41030 9 months ago 791MB [root@iZwz99sm8v95sckz8bd2c4Z test]# docker push ethanhuang824/diytomcat:1.0
因为push的时候,镜像名前面需要加上用户名(ethanhuang824是我的用户名。如果用户名不是当前登录用户则会拒绝push请求),所以需要使用命令docker tag 镜像名 新的镜像名
复制出一份镜像重新打个Tag。
5.3 发布镜像到阿里云容器服务
1.登录阿里云,找到容器镜像服务
2.创建命名空间
4.与上面DockerHub的操作类似,按官方提供的操作指南操作即可。
.
这篇关于Dockerfile详解与镜像发布的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-20Docker部署资料:新手入门教程
- 2024-12-19Docker部署实战:新手入门教程
- 2024-12-19Docker部署教程:新手入门详解
- 2024-12-09云原生周刊:在Docker上部署大语言模型
- 2024-12-05Docker教程:新手快速入门指南
- 2024-12-05Docker项目实战:新手教程与案例解析
- 2024-12-04Docker入门教程:快速掌握基础操作
- 2024-12-04Docker入门教程:轻松搭建你的第一个容器化应用
- 2024-12-04Docker-Compose 入门教程:全面解析基础命令与应用场景
- 2024-12-04Docker入门:新手必读的简单教程