Dockerfile详解与镜像发布

发布时间:2022-07-05 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Dockerfile详解与镜像发布脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

1. dockerfile介绍

Dockerfile是用来构建Docker镜像的文件,它是一个文本文件,也可以说是命令参数脚本。Dcoker根据该文件生成二进制的image文件。

Docker镜像发布的步骤F1a; 1、编写一个dockerfile文件

2、docker build 构建成为一个镜像

3、docker run 镜像

4、docker push 镜像(发布镜像到DockerHub、阿里镜像仓库)

示例一个镜像的结构图:

Dockerfile详解与镜像发布

2. Dockerfile指令说明

指令说明
From指定基础镜像
MaiNTAINER镜像是谁写的,姓名+邮箱
RUN镜像构建的时候需要运行的命令
ADD添加构建步骤,如添加一个tomcat镜像
WORKDIR镜像的工作目录
VOLUME挂载的目录
ExpOSE保留端口配置
CMD指定这个容器启动的时候要运行的命令(只有最后一个会生效
EMTRYPOINT指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令,触发指令
COPY类似于ADD ,将我们文件拷贝到镜像中
env构建的时候设置环境变量

一个形象的解释各个指令作用的图:

Dockerfile详解与镜像发布

关于DockerFile文件的脚本注意点有:

1、每个保留关键字(指令)都必须是大写字母

2、文件中的指令从上到下顺序执行

3、# 号表示注释

4、每一个指令都会创建提交一个新的镜像层,并提交!

3. 制作Centos镜像

下面通过编写Dockerfile文件来制作Centos镜像,并在官方镜像的基础上添加vim和net-tools工具。首先在/home/dockfile 目录下新建文件mydockerfile-centos。然后使用上述指令编写该文件。

[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]@H_777_135@# cat mydockerfile-centos
From centos
MAINTAINER ethan<1258398543@QQ wangt.cc >

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文件的指令:

@H_512_165@
  • 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 wangt.cc >
     ---> 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 wangt.cc >
    
    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.访问测试,浏览器访问查看是否能正常访问

    Dockerfile详解与镜像发布

    如果页面显示乱码,就需要修改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 wangt.cc / 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.创建命名空间

    Dockerfile详解与镜像发布

    4.与上面DockerHub的操作类似,按官方提供的操作指南操作即可。

    Dockerfile详解与镜像发布

    .

    脚本宝典总结

    以上是脚本宝典为你收集整理的Dockerfile详解与镜像发布全部内容,希望文章能够帮你解决Dockerfile详解与镜像发布所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。