zoukankan      html  css  js  c++  java
  • Docker-基础004-DockerFile的编写

    学习内容总结来自B站UP主"遇见狂神说"的Docker教学视频: https://www.bilibili.com/video/BV1og4y1q7M4

    DockerFile

    dockerfile是用来构建docker镜像的文件, 是一个命令参数脚本

    构建步骤:

    • 编写dockerfile文件
    • docker build 构建成一个镜像
    • docker run 运行镜像创建容器
    • docker push 发布镜像

    创建dockerfile

    创建规则

    • 每个保留关键字必须时大写字母

    • 命令从上往下依次执行

    • 每执行一个命令都会创建提交一个新的镜像层

    • # 表示注释

    常用命令关键字

    • FROM 指定基础镜像, 可以理解为继承的父类
    • MAINTAINER 维护者/作者信息, 一般格式为姓名加邮箱
    • RUN 创建镜像时会运行的命令
    • ADD 添加需要的压缩文件, 创建时会自动解压, 如tomcat压缩包
    • WORKDIR 工作目录, 设置进入容器时所在的路径
    • VOLUME 挂载容器卷
    • EXPOSE 指定对外暴露的端口
    • CMD 指定容器启动时会运行的命令, 只有最后一个命令会生效, 且会被docker run后面的命令替代
    • ENTRYPOINT 指定容器启动时会运行的命令, 只有最后一个命令会生效, 但不会被docker run后面的命令替代, 而是会拼接上后面的命令
    • ONBUILD 一个触发器, 当该dockerfile构建的镜像A被其他dockerfile构建的镜像B继承时, 那么在构建B的过程中, 首先会执行这个ONBUILD命令, 且只会对子镜像生效, 对孙子镜像不会生效
    • COPY 类似ADD命令, 将文件拷贝到镜像中
    • ENV 构建镜像时设置环境变量

    简单测试

    Docker Hub中大部分镜像都是继承了 scratch 这个基础镜像 FROM scratch然后配置需要的软件和配置来进行构建

    1.编写dockerfile创建自己的centos

    • 官方的centos中缺少一些常用命令, 如 vim/ifconfig等, 我们加上这些指令
    • 官方的centos的工作目录为根目录/, 我们改成/usr/local
    FROM centos
    MAINTAINER alex<g1242556827@163.com>
    
    RUN yum -y install vim
    RUN yum -y install net-tools
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    VOLUME /home/test
    
    EXPOSE 80
    
    CMD echo "-----success-----"
    CMD echo $MYPATH
    CMD /bin/bash
    

    2.使用dockerfile构建镜像

    # docker build -f dockerfile路径 -t 镜像名:[tag] .
    docker build -f dockerfile02 -t alex/centos .
    
    # docker history 镜像名 查看镜像历史记录
    docker history alex/centos
    

    3.运行镜像创建容器

    docker run -it alex/centos
    

    可以看到进入容器终端端后的当前路径为dockerfile中设置的工作目录/usr/local

    ifconfig命令也可以使用

    CMD与ENTRYPOINT的异同

    先说结论:

    相同点:

    1. 两者都是在容器运行时会执行的命令
    2. 执行时两者优先级是等价的, 只有最后一条CMD命令或者最后一条ENTRYPOIN命令会被执行, 即:
      • 若只有两条CMD命令, 则最后一条CMD命令会被执行
      • 若只有两条ENTRYPOINT命令, 则最后一条ENTRYPOINT命令会被执行
      • 若有一条CMD命令, 有一条ENTRYPOINT命令, 则最后一条ENTRYPOINT命令会被执行, 反之亦然

    不同点:

    当在执行docker run 镜像名 额外命令时, 在后面添加了额外的命令, 那么:

    • 对于CMD来说, 这条额外命令会替换掉CMD的命令, 也就是说不会执行CMD命令了, 只会执行run 后额外的命令

    • 对于ENTRYPOINT来说, 这条额外的命令会追加到ENTRYPOINT后面, 最后执行的是两者拼接后的命令

    测试结论

    • 测试相同点:

    两条CMD命令

    # 编写dockerfile test01
    FROM centos
    CMD echo "11111111111"
    CMD echo "22222222222"
    
    # 构建镜像
    docker build -f test01 -t test01 .
    
    # 运行镜像
    (root@Aliyun-Alex:/home/test)# docker run test01
    22222222222
    
    # 发现只执行了最后一个命令
    

    两条ENTRYPOINT命令

    # 编写dockerfile test02
    FROM centos
    ENTRYPOINT echo "11111111111"
    ENTRYPOINT echo "22222222222"
    
    # 构建镜像
    docker build -f test02 -t test02 .
    
    # 运行镜像
    (root@Aliyun-Alex:/home/test)# docker run test02
    22222222222
    
    # 发现也只执行了最后一个命令
    

    一条CMD一条ENTRYPOINT命令

    # 编写dockerfile test03
    FROM centos
    CMD echo "11111111111"
    ENTRYPOINT echo "22222222222"
    
    # 构建镜像
    docker build -f test03 -t test03 .
    
    # 运行镜像
    (root@Aliyun-Alex:/home/test)# docker run test03
    22222222222
    
    # 发现也只执行了最后一个命令
    
    • 测试不同点

    CMD会被替换

    # 编写dockerfile test04
    FROM centos             
    CMD ["ls", "-a"]
    
    # 构建镜像
    docker build -f test04 -t test04 .
    
    # 运行镜像, 后面附加命令 echo "aa"
    (root@Aliyun-Alex:/home/test)# docker run test04 echo "aa"
    aa
    
    # 发现CMD的命令并没有执行, 而只执行了run后面的命令 echo "aa" 
    
    # 运行镜像, 后面附加命令 -l
    (root@Aliyun-Alex:/home/test)# docker run test04 -l
    docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: "-l": executable file not found in $PATH": unknown.
    
    # 发现CMD的命令并没有执行, 而只执行了run后面的命令 -l, 而 -l不是有效的命令
    

    ENTRYPOINT会拼接命令

    # 编写dockerfile test05
    FROM centos             
    ENTRYPOINT ["ls", "-a"]
    
    # 构建镜像
    docker build -f test05 -t test05 .
    
    # 运行镜像, 后面附加命令 -l
    (root@Aliyun-Alex:/home/test)# docker run test05 -l
    total 0
    drwxr-xr-x   1 root root   6 Jul 29 04:03 .
    drwxr-xr-x   1 root root   6 Jul 29 04:03 ..
    -rwxr-xr-x   1 root root   0 Jul 29 04:03 .dockerenv
    lrwxrwxrwx   1 root root   7 May 11  2019 bin -> usr/bin
    drwxr-xr-x   5 root root 340 Jul 29 04:03 dev
    drwxr-xr-x   1 root root  66 Jul 29 04:03 etc
    drwxr-xr-x   2 root root   6 May 11  2019 home
    lrwxrwxrwx   1 root root   7 May 11  2019 lib -> usr/lib
    lrwxrwxrwx   1 root root   9 May 11  2019 lib64 -> usr/lib64
    drwx------   2 root root   6 Jun 11 02:35 lost+found
    drwxr-xr-x   2 root root   6 May 11  2019 media
    drwxr-xr-x   2 root root   6 May 11  2019 mnt
    drwxr-xr-x   2 root root   6 May 11  2019 opt
    dr-xr-xr-x 135 root root   0 Jul 29 04:03 proc
    dr-xr-x---   2 root root 162 Jun 11 02:35 root
    drwxr-xr-x  11 root root 163 Jun 11 02:35 run
    lrwxrwxrwx   1 root root   8 May 11  2019 sbin -> usr/sbin
    drwxr-xr-x   2 root root   6 May 11  2019 srv
    dr-xr-xr-x  13 root root   0 Jul 29 04:03 sys
    drwxrwxrwt   7 root root 145 Jun 11 02:35 tmp
    drwxr-xr-x  12 root root 144 Jun 11 02:35 usr
    drwxr-xr-x  20 root root 262 Jun 11 02:35 var
    
    # 发现没有报错, -l被拼接到了ENTRYPOINT的命令后面, 最终执行的是 ls -a -l
    

    实战: Dockerfile制作tomcat镜像

    1.准备tomcat和jdk压缩包

    • apache-tomcat-9.0.37.tar.gz
    • jdk-8u261-linux-x64.tar.gz

    2.编写dockerfile

    推荐把dockerfile命令为Dockerfile(官方命名), 这样在build时可以不用写-f参数

    # 基础镜像
    FROM centos
    # 作者信息
    MAINTAINER alex<g1242556827@163.com>
    
    # 复制readme文件
    COPY readme.txt /usr/local/readme.txt
    # 添加需要的压缩文件
    ADD apache-tomcat-9.0.37.tar.gz /usr/local
    ADD jdk-8u261-linux-x64.tar.gz /usr/local
    
    # 安装一些命令
    RUN yum -y install vim
    RUN yum -y install net-tools
    
    # 设置工作目录
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    # 配置java环境变量
    ENV JAVA_HOME /usr/local/jdk1.8.0_261
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar;$JAVA_HOME/lib/tools.jar
    
    # 配置tomcat环境变量
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37
    ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.37
    
    # 配置PATH环境变量
    ENV PATH $PATH;$JAVA_HOME/bin;$CATALINA_HOME/lib;$CATALINA_HOME/bin
    
    # 暴露端口
    EXPOSE 8080
    
    # 运行容器时运行的命令
    CMD /usr/local/apache-tomcat-9.0.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.37/bin/logs/catalina.out
    

    3.运行镜像创建容器

    # 运行容器
    docker run -d -p 8000:8080 --name mytomcat01 -v /home/alex/docker/test/mytomcat/webapps/test:/usr/local/apache-tomcat-9.0.37/webapps/test -v /home/alex/docker/test/mytomcat/logs:/usr/local/apache-tomcat-9.0.37/logs mytomcat
    
    # 进入容器终端, 可以看到当前目录为/usr/local, 解压的tomcat和jdk都在这里
    (root@Aliyun-Alex:/home/alex)# docker exec -it mytomcat01 bash
    [root@b5f127b76459 local]# ls
    aegis                 etc      jdk1.8.0_261  libexec     share
    apache-tomcat-9.0.37  games    lib           readme.txt  src
    bin                   include  lib64         sbin
    
    # 进入tomcat的webapps目录, 可以看到默认的一些文件
    [root@b5f127b76459 apache-tomcat-9.0.37]# cd webapps/
    [root@b5f127b76459 webapps]# ls
    ROOT  docs  examples  host-manager  manager  test
    

    这里我有一个疑惑, 就是在前面运行容器时, 如果挂载的路径是 -v 主机/webapps:容器/webapps即只到webapps层, 那么进入容器后发现webapps下面是空的, 并没有ROOT docs examples host-manager manager这些文件, 浏览器访问8000端口也是404找不到页面

    但是如果挂载到webapps/test这一层, 就有了这些文件, 8000端口也能正常访问到tomcat网页, 对tomcat不是很熟, 不知道是不是因为webapps下面没有项目的原因.

    4.发布简单项目(由于做了卷挂载, 可以直接在本地编写项目)

    创建web.xml文件

    (root@Aliyun-Alex:/home/alex/docker/test/mytomcat)# cd test/
    (root@Aliyun-Alex:/home/alex/docker/test/mytomcat/test)# mkdir WEB-INF
    (root@Aliyun-Alex:/home/alex/docker/test/mytomcat/test)# cd WEB-INF/
    (root@Aliyun-Alex:/home/alex/docker/test/mytomcat/test/WEB-INF)# nvim web.xml
    
    # web.xml文件如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" 
        xmlns="http://java.sun.com/xml/ns/j2ee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
            http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    </web-app>
    

    创建index.jsp文件

    (root@Aliyun-Alex:/home/alex/docker/test/mytomcat/test/WEB-INF)# cd ..
    (root@Aliyun-Alex:/home/alex/docker/test/mytomcat/test)# nvim index.jsp
    
    # index.jsp文件如下:
    <html>
    <head><title>Hello World</title></head>
        <body>
            Hello World!<br/>
            <%
            System.out.println("---------my test web logs----------");
            %>
        </body>
    </html>
    

    测试

    访问http://47.102.114.90:8000/test/查看结果

    查看日志信息

    cd /home/alex/docker/test/mytomcat/logs
    vim catalina.out
    

    可以看到访问后打印出来的信息

    项目部署成功!

  • 相关阅读:
    复选框和文字对齐解决方案
    封装getElementsByClassName()
    原生js运动框架
    如何防止鼠标移出移入子元素触发mouseout和mouseover事件
    回调函数
    经验
    sublime text3函数追踪:ctags配置
    笔记
    编程经验NO.1 from月光博客
    概念
  • 原文地址:https://www.cnblogs.com/gcxblogs/p/13404121.html
Copyright © 2011-2022 走看看