• Docker(4):Dockerfile


    容器的生命周期:

    • 检查本地是否存在镜像,如果不存在即从远端仓库检索
    • 利用镜像启动容器
    • 分配一个文件系统,并在只读镜像层外挂载一层可读写层
    • 从宿主机配置的网桥接口中桥接一个虚拟接口到容器
    • 从地址池配置一个ip地址给容器
    • 执行用户指定的指令
    • 执行完毕后容器终止

    镜像制作的途径:

      1、 docker commit 

      2、Dockerfile

    Dockerfile is nothing but the source code for building Docker image. Docker can build images automatically by reading the instructions from Dockerfile.

    Dockerfile 规范:

    1、格式:

    • # 为注释
    • 指令大写,内容小写
    • 尽管指令是大小写不敏感的,但是,我们强烈建议指令用大写,内容用小写表示

    2、Dockerfile 是按顺序执行 Dockerfile 里的指令集合的(从上到下依次执行)

    3、每一个Dockerfile的第一个非注释指令,必须是“From” 指令,用于为镜像文件构建过程中,指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境中

    • 实践中,基准镜像可以是任何可用镜像文件,默认情况下,docker build 会在docker主机(本地)上查找指定的镜像文件,当其在本地不存在时,则会从 docker registry (远端)上拉取所需镜像文件

    4组核心的Dockerfile指令:

    • USER/WORKDIR 指令
    • ADD/EXPOSE 指令
    • RUN/ENV 指令
    • CMD/ENTRYPOINT 指令

    USER指令:指明pid=1的那个进程是用哪个用户跑的。 WORKDIR 是工作目录

    dockerfile]$ cat Dockerfile 
    FROM neomaple/nginx:v1.12.2-with_curl
    USER nginx
    WORKDIR /usr/share/nginx/html
    
    dockerfile]$ docker build . -t neomaple/nginx:v1.12.2_with_user_workdir  # build . 表示构建本目录下的 Dockerfile。-t 表示加一个 tag
    Sending build context to Docker daemon  2.048kB
    Step 1/3 : FROM neomaple/nginx:v1.12.2-with_curl
     ---> bed9d53d040f
    Step 2/3 : USER nginx
     ---> Running in 61ddd6262e79
    Removing intermediate container 61ddd6262e79
     ---> 913dfc82717b
    Step 3/3 : WORKDIR /usr/share/nginx/html
     ---> Running in 04f2d453b212
    Removing intermediate container 04f2d453b212
     ---> 7a452945f33f
    Successfully built 7a452945f33f
    Successfully tagged neomaple/nginx:v1.12.2_with_user_workdir
    
    dockerfile]$ docker run --rm -ti --name nginx123 neomaple/nginx:v1.12.2_with_user_workdir /bin/bash  # 加了 -ti 后面就需要加 /bin/sh 之类的交互式的方式
    nginx@ce0784f01a71:/usr/share/nginx/html$ 
    nginx@ce0784f01a71:/usr/share/nginx/html$ whoami
    nginx
    nginx@ce0784f01a71:/usr/share/nginx/html$ pwd
    /usr/share/nginx/html
    nginx@ce0784f01a71:/usr/share/nginx/html$ exit
    exit

    ADD/EXPOSE指令:

    ADD指令类似于  COPY指令,但ADD指令要比COPY指令要广一些,ADD也适用于 tar包和 url;EXPOSE指令定义容器内哪个端口被暴露出来。

    ADD指令的功能是将主机构建环境(上下文)目录中的文件和目录、以及一个URL标记的文件 拷贝到镜像中。 其格式是: ADD  源路径  目标路径

    dockerfile]$ cat Dockerfile
    FROM neomaple/nginx:v1.12.2-with_curl
    ADD index.html /usr/share/nginx/html/index.html
    EXPOSE 80
    
    dockerfile]$ docker build . -t neomaple/nginx:v1.12.2_with_add_expose
    Sending build context to Docker daemon   5.12kB
    Step 1/3 : FROM neomaple/nginx:v1.12.2-with_curl
     ---> bed9d53d040f
    Step 2/3 : ADD index.html /usr/share/nginx/html/index.html
     ---> 037d71199706
    Step 3/3 : EXPOSE 80
     ---> Running in 582258e6542d
    Removing intermediate container 582258e6542d
     ---> 9e04822eec13
    Successfully built 9e04822eec13
    Successfully tagged neomaple/nginx:v1.12.2_with_add_expose
    
    dockerfile]$ docker run -d -P neomaple/nginx:v1.12.2_with_add_expose    // -P 表示在宿主机上随机起一个端口把容器内的 80 端口暴露出来 
    31e492b1adfd764bfcf852cc62f5969332a6d466b7405228b09df4508e2b71a1
    [ec2-user@ip-172-31-47-18 dockerfile]$ docker ps -a
    CONTAINER ID   IMAGE                                    COMMAND                  CREATED         STATUS                   PORTS                   NAMES
    31e492b1adfd   neomaple/nginx:v1.12.2_with_add_expose   "nginx -g 'daemon of…"   4 seconds ago   Up 3 seconds             0.0.0.0:49153->80/tcp   jolly_fermi
    
     dockerfile]$ netstat -lntup
    (No info could be read for "-p": geteuid()=1000 but you should be root.)
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name   
    tcp        0      0 0.0.0.0:49153           0.0.0.0:*               LISTEN      -    

    RUN/ENV 指令:

    ENV 指令是 在制定docker镜像时指定环境变量;RUN 指令可以在构建镜像的时候去执行一些命令

     dockerfile]$ cat Dockerfile 
    FROM centos:7 
    ENV VER 9.11.4
    RUN yum install bind-$VER -y
    
     dockerfile]$ docker build . -t neomaple/bind:v9.11.4_with_env_run
     ...
     ...
    
    
     // 检验
     ~]$ docker images
    REPOSITORY        TAG                         IMAGE ID       CREATED         SIZE
    neomaple/bind     v9.11.4_with_env_run        c5b3e5c2ebeb   7 minutes ago   363MB
    
    ~]$ docker run -it --rm neomaple/bind:v9.11.4_with_env_run /bin/sh
    sh-4.2# cat /etc/redhat-release 
    CentOS Linux release 7.9.2009 (Core)
    sh-4.2# printenv | grep VER
    VER=9.11.4
    sh-4.2# rpm -qa bind
    bind-9.11.4-26.P2.el7_9.7.x86_64

    CMD/ENTRYPOINT指令:

    CMD 是在你启动容器的时候,帮你运行一些命令

    dockerfile]$ cat Dockerfile 
    FROM centos:7 
    RUN yum install httpd -y
    CMD ["httpd", "-D", "FOREGROUND"]
    
    dockerfile]$ docker build . -t neomaple/httpd:test
    
    dockerfile]$ docker images
    REPOSITORY        TAG                         IMAGE ID       CREATED          SIZE
    neomaple/httpd    test                        99666077880a   24 seconds ago   370MB
    
    dockerfile]$ docker run -d --name myhttpd -p83:80 neomaple/httpd:test
    
    dockerfile]$ docker ps -a
    CONTAINER ID   IMAGE                                    COMMAND                  CREATED         STATUS                    PORTS                NAMES
    056eef824390   neomaple/httpd:test                      "httpd -D FOREGROUND"    5 seconds ago   Up 5 seconds              0.0.0.0:83->80/tcp   myhttpd
    
    // 看 COMMAND 一栏是: httpd -D FOREGROUND

    每一个docker镜像都有一个默认的启动命令(默认的CMD命令),当你不指定CMD命令时,它默认执行根目录下的 entrypoint.sh 这个脚本(要有执行权限)

    dockerfile]$ cat Dockerfile 
    FROM centos:7 
    ADD entrypoint.sh /entrypoint.sh
    RUN yum install epel-release -q -y && yum install nginx -y
    ENTRYPOINT /entrypoint.sh
    
    dockerfile]$ cat entrypoint.sh 
    #!/bin/bash
    /sbin/nginx -g "daemon off;"
    
    dockerfile]$ chmod +x entrypoint.sh     // 给 entrypoint.sh 加上执行权限
    
     dockerfile]$ docker build . -t neomaple/nginx:mynginx_with_entrypoint
    
     dockerfile]$ docker images
    REPOSITORY        TAG                         IMAGE ID       CREATED              SIZE
    neomaple/nginx    mynginx_with_entrypoint     e08cb42d800b   About a minute ago   410MB
    
     dockerfile]$ docker run --rm -p84:80 neomaple/nginx:mynginx_with_entrypoint 
    // 终端将会 hang 住
    
    // 我们去另外一个窗口查看
    
    ~]$ docker ps -a
    CONTAINER ID   IMAGE                                    COMMAND                  CREATED              STATUS                   PORTS                NAMES
    34290b3d24e4   neomaple/nginx:mynginx_with_entrypoint   "/bin/sh -c /entrypo…"   About a minute ago   Up About a minute        0.0.0.0:84->80/tcp   ecstatic_lamarr
    
     ~]$ docker exec -it 34290b3d24e4 /bin/sh
     sh-4.2# cat entrypoint.sh 
    #!/bin/bash
    /sbin/nginx -g "daemon off;"

    综合实验

    目的:运行一个 docker 容器,在浏览器打开 demo.od.com 能访问到百度首页

    dockerfile]$ mkdir nginx
     dockerfile]$ cd nginx/
    [ec2-user@ip-172-31-47-18 nginx]$ wget www.baidu.com -O index.html
    
    nginx]$ cat demo.od.com.conf 
    server {
        listen 80;
        server_name demo.od.com;
    
        root /usr/share/nginx/html;
    }
    nginx]$ cd ..
    [ec2-user@ip-172-31-47-18 dockerfile]$ cat Dockerfile 
    FROM neomaple/nginx:v1.12.2
    USER root
    ENV WWW /usr/share/nginx/html
    ENV CONF /etc/nginx/conf.d
    RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&
        echo 'Asia/Shanghai' >/etc/timezone
    WORKDIR $WWW
    ADD nginx/index.html $WWW/index.html
    ADD nginx/demo.od.com.conf $CONF/demo.od.com.conf
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    
    dockerfile]$ docker build . -t neomaple/nginx:baidu
    dockerfile]$ docker run -d -p80:80 neomaple/nginx:baidu
    e30a12dc7f050878531de553f1e37889b2c99a26a6baaa6b705f355224b43260
    dockerfile]$ sudo vim /etc/hosts    // 在 hosts 文件中加上 127.0.0.1   demo.od.com
    dockerfile]$ curl demo.od.com
    <!DOCTYPE html>
    <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

    end ...

    Code your future.
  • 相关阅读:
    phpstorm 破解方法
    shell_exec
    数据库配置
    sprintf
    MySQL优化步 (InnoDB)
    Python小白需要知道的 20 个骚操作!
    Python常用库整理
    Python:什么是进阶,如何进阶?
    Python中标准模块importlib详解
    Python开发【Django】:中间件、CSRF
  • 原文地址:https://www.cnblogs.com/neozheng/p/15221447.html
Copyright © 2020-2023  润新知