zoukankan      html  css  js  c++  java
  • 七、Dockerfile

    于2021年10月1日更新

    一、简介

    Dockerfile是一个文本格式的脚本文件,用来快速创建自定义的镜像。

    二、指令的两种格式

    1)shell格式

    RUN <命令行命令>

    <命令行命令> 等同于,在终端操作的 shell 命令。

    RUN echo "hello world!"
    

    2)exec格式(推荐使用)

    RUN ["可执行文件", "参数1", "参数2"]

    RUN ["./test.php", "dev", "offline"] 
    
    #等同于shell格式
    RUN ./test.php dev offline
    

    三、常用指令

    FROM

    指定基础镜像,我们定制的镜像都是基于基础镜像。

    语法:

    FROM <image>
    FROM <image>:<tag>
    FROM <image>:<digest> 
    
    :'
    三种写法,其中<tag>和<digest> 是可选项,如果没有选择,那么默认值为latest
    '
    

    案例:

    FROM centos
    FROM centos:latest
    

    我们下载的镜像,99%都是基于scratch镜像

    MAINTAINER

    指定作者信息

    语法:

    MAINTAINER <name>
    

    案例:

    MAINTAINER tz
    MAINTAINER tz<123456@qq.com>
    

    COPY

    复制命令

    :只能是本地文件

    :容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建

    语法:

    COPY <src>... <dest>
    COPY ["<src>",... "<dest>"]
    

    案例:

    COPY hom* /mydir/
    COPY ["home.txt","/mydir/"]
    

    ADD

    也是复制命令

    可以是一个本地文件或者是一个本地压缩文件,还可以是一个url

    在执行 为 tar 压缩文件的话,会自动解压到目标路径下。

    语法:

    ADD <src>... <dest>
    ADD ["<src>",... "<dest>"]
    

    案例:

    ADD home.tar /mydir/
    ADD ["https://xxx.com/home.tar","/mydir/"]
    

    ENY

    设置环境变量,变量可被后续的run指令使用,在镜像启动的容器中也会存在。

    语法:

    ENV <key>
    ENV <key>=<value>
    

    案例:

    ENV APP_VERSION=1.0.0
    ENV APP_HOME=/usr/local/app
    EVN PATH $PATH:/usr/local/bin
    

    EXPOSE

    声明容器服务端口

    注意:仅仅是声明,并不会做端口映射,端口映射还需要配合docker run -p使用

    在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

    语法:

    EXPOSE <端口1> [<端口2>...]
    

    案例:

    EXPOSE 80
    

    VOLUME

    定义匿名挂载数据卷。

    在启动容器时忘记使用-v挂载数据卷,会自动挂载该匿名卷。

    语法:

    VOLUME ["<路径1>", "<路径2>"...]
    VOLUME <路径>
    

    案例:

    VOLUME ["/var/log/"]
    VOLUME /var/log
    VOLUME /var/log /var/db
    

    在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

    WORKDIR

    指定工作目录,必须是提前创建好的

    语法:

    WORKDIR <工作目录路径>
    

    案例:

    WORKDIR /usr/local/
    

    RUN

    运行容器时指定的命令

    常用来在当前镜像基础上执行指定命令

    语法:

    RUN <command>
    RUN ["executable", "param1", "param2"]
    

    案例:

    #格式一
    RUN yum -y install vim
    && yum -y install httpd
    
    #格式二
    RUN ["/bin/bash", "-c", "echo hello tz"]
    

    注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层镜像,多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,同时还增加了构件部署的时间。

    CMD

    容器启动时要运行的命令

    该命令会在容器启动且docker run没有指定其他命令时运行

    如果指定了多条命令,只有最后一条会被执行

    会被docker run命令行参数指定的指令所覆盖

    语法:

    CMD command param1 param2
    CMD ["executable","param1","param2"]
    CMD ["param1","param2"]
    

    案例:

    CMD echo "hello tz"
    CMD [ "sh", "-c", "echo $HOME" ]
    CMD [ "echo", "$HOME" ]
    

    ENTRYPOINT

    类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖。

    docker run命令行参数会被当作参数送给 ENTRYPOINT 指令

    如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

    语法:

    ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
    

    案例:

    #构建nginx:test镜像
    vim Dockerfile
    FROM nginx
    
    ENTRYPOINT ["nginx", "-c"] # 定参
    CMD ["/etc/nginx/nginx.conf"] # 变参 
    
    #不传参数运行
    docker run  nginx:test
    
    :'
    不传参数运行解释
    docker run不传参数运行,CMD命令就会当作docker run的参数执行,但是因为指定了ENTRYPOINT指令,故CMD命令会被当成参数传给 ENTRYPOINT 指令
    最后相当于执行了`docker run --name n1 nginx -c /etc/nginx/nginx.conf`语句。
    '
    
    #传参数运行
    docker run  nginx:test -c /etc/nginx/new.conf
    #nginx -c /etc/nginx/new.conf
    
    :'
    传参数运行解释
    docker run传参数运行,CMD命令就会被覆盖,docker run的命令行参数会被带入ENTRYPOINT指令,结果就相当于执行了nginx -c /etc/nginx/new.conf
    '
    

    LABEL

    给生成的镜像添加一些元数据标签信息,这些信息可以用来辅助过滤出特定的镜像。

    格式为键值对的形式。

    语法:

    LABEL <key>=<value> <key>=<value> <key>=<value> ...
    

    案例:

    LABEL author="tz" 
    version="1.0" 
    description="xxxxxx"
    

    Build

    构建镜像指令

    语法:

    ocker build -t nginx:v3 .
    
    :'
    -t: 构建的镜像名加标签
    注意最后那个点,表示上下文
    镜像构建过程是在docker引擎下完成的,无法用到宿主机文件,这时需要使用上下文将Dockerfile 所在的位置打包发送给docker引擎。
    '
    

    其他选项解释

    -t, --tag list # 镜像名称
    -f, --file string # 指定Dockerfile文件位置
    - #表示通过STDIN给出Dockerfile或上下文
    
    :'
    示例
    docker build . # 默认找当前目录以Dockerfile为命名的文件
    docker build -t shykes/myapp .
    docker build -t shykes/myapp -f /path/Dockerfile .
    docker build -t shykes/myapp - < Dockerfile
    docker build -t shykes/myapp - < context.tar.gz
    docker build -t shykes/myapp http://www.example.com/Dockerfile
    docker build -f shykes/myapp http://www.example.com/contex.tar.gz
    '
    

    可参考:build命令详解build命令详解2

    四、命令总结

    4.1 常用指令速记图

    image

    4.2 RUN 、CMD 和 ENTRYPOINT 指令区别

    1. RUN在构建镜像时运行,可以写多条,常用于安装软件包。
    2. CMD和ENTRYPOINT在运行容器时运行,只能写一条,如果写多条,最后一条生效。
    3. CMD会被docker run命令行参数指定的指令所覆覆盖,ENTRYPOINT不会被覆盖,但可以指定--entrypoint被覆盖。

    四、案例

    4.1 构建PHP网站镜像

    因为centos6已经停止更新了,yum源大多已失效,这个案例已经无法实现其功能,写在这里了解Dockerfile使用即可。

    1)创建上下文目录

    mkdir /root/docker
    cd /root/docker
    

    2)编辑Dockerfile文件

    vim Dockerfile #必须以Dockerfile命名
    
    #基础镜像来源自centos:latest
    FROM sglim2/centos7 
    #维护者信息
    MAINTAINER tz
    #配置阿里源
    RUN yum -y install wget
    && wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-6.repo
    #构建镜像时运行的shell命令
    RUN yum install -y httpd php php-gd php-mysql mysql mysql-server
    #设置容器环境变量即mysql密码
    ENV MYSQL_ROOT_PASSWORD 123456
    RUN echo "<?php phpinfo()?>" > /var/www/html/index.php
    #拷贝脚本到镜像根目录下
    ADD start.sh /start.sh
    RUN chmod +x /start.sh
    ADD https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gz /var/www/html
    COPY wp-config.php /var/www/html/wordpress
    #将容器指定目录如mysql数据库目录挂载到宿主机自动生成的目录
    VOLUME ["/var/lib/mysql"]
    CMD /start.sh
    #申明容器运行开放的端口
    EXPOSE 80 3306
    

    3)编辑start.sh脚本

    vim start.sh
    service httpd start
    service mysqld start
    mysqladmin -uroot password $MYSQL_ROOT_PASSWORD
    #使用如下命令使容器一直运行,容器是linux的一个进程如果没有持续运行的事务就会退出
    tail -f
    

    4)使用build构建镜像

    docker build -t wordpress:v1 .
    

    5)通过构建的镜像创建容器

    docker run -itd --name wordpress -p 80:80 wordpress:v1
    

    6)验证

    文件也拷贝进去了

    docker exec wordpress ls /var/www/html
    index.php
    wordpress
    

    访问拷贝进去的wordpress博客,自己动手安装

    http://宿主机ip:80/wordpress/
    

    登录容器里的数据库

    容器中$mysql -uroot -p$MYSQL_ROOT_PASSWORD
    

    目前centos6已经停止更新了,网上的yum源也大多已经失效,这里有一个可以用的。

    4.2 构建JAVA网站镜像

    1)创建上下文目录,上传jdk-8u221-linux-x64.tar.gzapache-tomcat-8.5.71.tar.gz到该目录下

    mkdir /root/docker
    cd /root/docker
    

    2)编写Dcokerfile文件

    vim Dockerfile
    FROM centos:6
    MAINTAINER tz
    ADD jdk-8u221-linux-x64.tar.gz /usr/local
    ENV JAVA_HOME /usr/local/jdk1.8.0_221
    ADD apache-tomcat-8.5.71.tar.gz /usr/local
    WORKDIR /usr/local/apache-tomcat-8.5.71
    ENTRYPOINT ["bin/catalina.sh", "run"]
    EXPOSE 8080
    

    3)使用build构建镜像

    -f指定上下文路径

    docker build -t tomcat:v1 -f /root/docker/Dockerfile .
    

    4)通过构建的镜像创建容器

    docker run -itd --name tomcat -p 8080:8080  tomcat:v1
    

    如果创建失败及时查看日志找原因

    docker logs tomcat
    

    4.3 构建SSH服务镜像

    1)创建上下文目录

    mkdir /root/docker
    cd /root/docker
    

    2)编辑Dockerfile文件

    vim Dockerfile
    FROM sglim2/centos7 
    MAINTAINER tz
    ENV ROOT_PASSWORD 123456
    RUN yum install -y openssh-server && yum -y install passwd
    RUN echo $ROOT_PASSWORD |passwd --stdin root
    RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
    RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
    CMD ["/usr/sbin/sshd", "-D"]
    EXPOSE 22
    

    3)使用build构建镜像

    docker build -t ssh:v1 .
    

    4)通过构建的镜像创建容器

    docker run -itd --name ssh -p 2222:22 ssh:v1
    

    5)验证

    ssh 10.154.0.110 2222
    

    五、附录

    5.1 FROM指令补充

    登录dockerhub搜索centos镜像,点击如下

    image-20211002111037535

    可以看到centos镜像是基于FROM镜像创建的

    六、参考资料

    《每天5分钟玩转docker容器》第三章

    《docker技术入门与实战》第八章

    docker指令说明

    狂神说docker

    今天的学习是为了以后的工作更加的轻松!
  • 相关阅读:
    mysql 数据类型总结
    #微信小程序子传父 #小程序子组件向父组件传值 小程序子组件触发父组件中的事件
    #最近看到了一个写的很棒的系列文章专栏
    《MySQL45讲》读书笔记(四):索引
    《MySQL45讲》读书笔记(六):数据库事务概述
    《MySQL45讲》读书笔记(一):三大日志概述
    Java基础篇(05):函数式编程概念和应用
    数据采集组件:Flume基础用法和Kafka集成
    架构设计:数据服务系统0到1落地实现方案
    Java基础篇(04):日期与时间API用法详解
  • 原文地址:https://www.cnblogs.com/tz90/p/12237476.html
Copyright © 2011-2022 走看看