关于docker那点事儿——Dockerfile编写

2023-05-16

Dockerfile编写

  • 前言
  • 一、Dockerfile创建镜像
  • 二、Dockerfile常用指令
  • 三、示例
      • 1、Dockerfile构建nginx镜像
      • 2、Dockerfile构建微服务
  • 四、CMD与ENTRYPOINT比较


前言

Dockerfile 说白了就是构建镜像的一个文件。它里面描述了一条条的指令,每一条指令都会构建新的一层。当执行docker build时,docker会按照我们Dockefile里预编写好的指令,去一层层构建,从而构建出一个新的镜像。

一、Dockerfile创建镜像

  1. 创建目录
mkdir any_name
cd any_name
  1. 编写Dockerfile文件
vim Dockerfile

# This is a comment 
FROM daocloud.io/library/nginx
MAINTAINER liang liang@localhost.localdomain
RUN mkdir /test

*注: 如果文件中有执行失败的指令,那么创建出来的镜像名字和tag都为none
  1. 构建镜像
docker build -t liang/nginx:v1 .     # . 一定要有 表示Dockerfile在当前目录 如果文件名不是Dockerfile 使用 -f 指定文件

二、Dockerfile常用指令

1、FROM 拉取基础镜像

功能为指定基础镜像,并且必须是第一条指令。如果不以任何镜像为基础,那么写法为:FROM scratch。

语法:FROM <image>:<tag>   其中<tag>为可选项,默认为latest

2、RUN 构建容器时执行命令

RUN命令有两种格式

Ⅰ. RUN <command>                # shell方式

Ⅱ. RUN ["executable", "param1", "param2"]     # 类似于函数调用,可将executable理解成为可执行文件,后面就是两个参数

*注:多行命令不要写多个RUN,写在一个RUN里,原因是Dockerfile中每一个指令都会建立一层

3、MAINTAINER

MAINTAINER <name>     # 指定作者

4、CMD 容器启动时要运行的命令

语法:Ⅰ. CMD ["executable","param1","param2"]    # CMD [ "sh", "-c", "echo $HOME" ]

       Ⅱ. CMD ["param1","param2"]          # CMD [ "echo", "$HOME" ]

       Ⅲ. CMD command param1 param2         # shell形式

*注:Ⅰ和Ⅱ两种方式一定要用双引号,千万不能写成单引号

5、ENV 设置环境变量

语法:ENV <key>=<value> ...    # 可一次设置多个

6、ADD 复制命令 类似于scp,只是scp需要加用户名和密码的权限验证,而ADD不用

语法:Ⅰ. ADD <src>... <dest>

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

<dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径

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

7、COPY 复制命令

语法:Ⅰ. COPY <src>... <dest>

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

8、EXPOSE 暴露监听端口给外部

*注:EXPOSE并不会使容器访问主机的端口,如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上-p参数

9、WORKDIR 设置工作目录

语法:WORKDIR /path/to/workdir

对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次。

10、VOLUME 实现挂载功能,可以将本地文件夹或者其他容器中的文件夹挂在到这个容器

语法:VOLUME ["/data"]

*注:一般不会在Dockerfile中用到,更常见的还是在docker run的时候指定-v数据卷

三、示例

1、Dockerfile构建nginx镜像

FROM centos:7.2.1511
ENV TZ=Asia/Shanghai
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8

RUN yum -y install epel*  gcc openssl openssl-devel  pcre-devel zlib-devel

ADD nginx-1.14.0.tar.gz /opt/

WORKDIR /opt/nginx-1.14.0

RUN ./configure --prefix=/opt/nginx  --http-log-path=/opt/nginx/logs/access.log --error-log-path=/opt/nginx/logs/error.log --http-client-body-temp-path=/opt/nginx/client/  --http-proxy-temp-path=/opt/nginx/proxy/  --with-http_stub_status_module --with-file-aio --with-http_flv_module --with-http_gzip_static_module --with-stream --with-threads --user=www --group=www
RUN make && make install
RUN groupadd www && useradd -g www www
WORKDIR /opt/nginx
RUN rm -rf /opt/nginx-1.14.0

ENV NGINX_HOME=/opt/nginx
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/nginx/sbin

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

*注:此只是个例子,实际中如果没有满足需求的base image,如java程序使用java:8作为base image,可以使用Alpine镜像作为base image,轻量级且命令丰富,比centos镜像更适合做base image

2、Dockerfile构建微服务

#cat Dockerfile
FROM java:8
MAINTAINER liang_20210511
#ENV TZ=Asia/Shanghai
#ENV LANG=en_US.UTF-8
#ENV LANGUAGE=en_US:en
#ENV LC_ALL=en_US.UTF-8
ENV JAVA_OPTS="-Xms512m -Xmx512m"
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
ADD cmdb-server.tar /
WORKDIR /cmdb-server
EXPOSE 10013

#CMD ["java","-jar","cmdb-server.jar","-Dfile.encoding=utf-8"]
ENTRYPOINT ["/cmdb-server/entrypoint.sh"]

#cat entrypoint.sh 
#!/bin/sh
nohup java -server $JAVA_OPTS -jar cmdb-server.jar >/dev/null 2>&1 &
sleep 1
if [ $? -eq 0 ];then
tail -f logs/cmdb-server.log
fi

四、CMD与ENTRYPOINT比较

  cmd 和 entrypoint 指令都是用来指定容器启动时运行的命令。并且都有exec与shell两种模式。推荐使用exec模式,这样可以使容器接收的KILL信号,从而优雅的退出。这里牵扯到容器的daemon进程来管理容器的生命周期,以后有机会我们以后专门拿出来去探讨。

  cmd 指令

  cmd 指令的目的是:为容器提供默认的执行命令。

  cmd 指令有三种使用方式,其中的一种是为 entrypoint 提供默认的参数:

cmd ["param1","param2"]

  另外两种使用方式分别是 exec 模式和 shell 模式:

cmd ["executable","param1","param2"]

cmd command param1 param2

  注意命令行参数可以覆盖 cmd 指令的设置,但是只能是重写,却不能给 cmd 中的命令通过命令行传递参数。我们可以通过docker run参数的方式覆盖 cmd 指令提供的默认命令。

  entrypoint 指令

  entrypoint 指令的目的也是为容器指定默认执行的任务。

  entrypoint 指令有两种使用方式, exec 模式和 shell 模式:

entrypoint ["executable", "param1", "param2"] 

entrypoint command param1 param2

  在这里entrypoint 有一个特殊的用法,传参

  1、当我们使用exec模式时,docker run的指令可以作为参数传递给entrypoint 命令。比如:

from centos
entrypoint [ "top", "-n" ]

当我们执行docker run -- rm centos:test 1
此时容器里执行的命令:top -n 1

  2、cmd指令给entrypoint 传参,比如:

from centos
entrypoint [ "top", "-n" ]
cmd [ "1" ]

当我们执行docker run -- rm centos:test
此时容器里执行的命令:top -n -1

  3、docker run的指令覆盖cmd指令,传参给entrypoint

from centos
entrypoint [ "top", "-n" ]
cmd [ "1" ]

当我们执行docker run -- rm centos:test 3
此时容器里执行的命令:top -n -3

  其实cmd指令与entrypoint指令远比这些要复杂:

在这里插入图片描述
  当然,大家想深入了解的也可以参考官方给的解释自行实践对比一下:官方链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于docker那点事儿——Dockerfile编写 的相关文章

随机推荐

  • Chapter007-FPGA学习之IIC总线EEPROM读取

    IIC总线是嵌入式领域较为重要的器件间通信总线 xff0c 同样 xff0c FPGA也能通过模块的形式实现IIC的功能 xff0c 其原理和STM32的模拟IIC总线一致 xff0c 就是控制每个时间点的SCL SDA总线电平 IIC总线
  • 游戏化思维——核心驱动力

    游戏是一个令人着迷 xff0c 并且能够让人沉迷于此的东西 xff0c 而游戏之所以如此迷人 xff0c 不但是游戏的制作精良和剧情引人入胜 除此之外还有些其他原因 xff0c 激励人民玩游戏的原因是 xff1a 游戏能够触及到人性的核心驱
  • 从产品设计到用户设计

    从产品设计到用户设计 一说起产品设计 xff0c 人们往往想到两个方面 感官方面 功能方面 感官方面 xff1a 精心设计的产品能够给用户带来赏心悦目的感觉 xff0c 当然极大部分是属于触感方面 xff08 嗅觉和味觉因为局限问题无法在产
  • 十年寒窗,从高考到海盗,人的梦想是不会结束的

    其实这是讲述我是如何想要成为一名海盗的 又是一年高考时 我翻看着手机 xff0c 看着朋友圈里面各种高考热文一篇篇的出现 xff0c 心里难免有些感慨和一些自己的回忆 当年高考时也像现在一样 xff0c 看到了许多这样的文章 xff0c 看
  • 为体验设计——使用第一

    产品设计和用户体验设计有什么不同呢 xff1f 每个产品都是以用户是人类为前提而设计出来的 xff0c 而产品的每一次使用 xff0c 都会产生相应的体验 用户体验设计并完全不等同于产品设计 但是对于一个简单的情况下 xff0c 创建一个良
  • 用户体验和网站

    用户体验对于所有的产品和服务来讲 xff0c 都是至关重要的 现在讨论一种特殊产品的用户体验 xff1a 网站 xff08 这里的 网站 一词包括以内容为主的网站产品和以交互为主的网站应用 xff09 在网站上 xff0c 用户体验比任何一
  • UCOS II两个任务的模板

    芯片lm3s9b92 include lt includes h gt include 34 utils uartstdio h 34 Application tasks 优先级 define TASK2 PRIO 11 define ta
  • UCOSII 信号量和信号量集实例

    代码来自于书本光盘 嵌入式操作系统UCOSII原理及应用 实例1信号量 include 34 includes h 34 define TASK STK SIZE 512 任务堆栈长度 OS STK StartTaskStk TASK ST
  • 正点原子MiniFly V1.2学习笔记一

    之前看过原子哥的FreeRTOS开发手册 xff0c 但是对整个项目 怎么架构还不是很清楚 由于最近工作需要上FreeRTOS xff0c 所以决定通过MiniFly来学习一下FreeRTOS的架构 一 main 函数 int main s
  • 正点原子MiniFly V1.2学习笔记三---atkpRxAnlTask

    第5个任务 解析处理接收到的指令 xTaskCreate atkpRxAnlTask 34 ATKP RX ANL 34 300 NULL 6 NULL 上面第1个任务 xff0c 把串口接收到的数据解包后得到指令 xff0c 然后把指令发
  • 正点原子MiniFly V1.2学习笔记五---sensorsTask

    这里先学习第8个任务sensorsTask xff0c 2 xff0c 3 xff0c 6 xff0c 7任务后面再学 xff0c 先学重要的 xTaskCreate sensorsTask 34 SENSORS 34 450 NULL 4
  • 嵌入式项目管理学习——001重点明确和心态转换

    相信做嵌入式的码哥们在参与一定数量的产品设计和生产之后 xff0c 都会发现一个问题 xff0c 如果没有一个负责的产品经理 xff0c 就会陷入到产品延期 沟通缺失 目标不清晰 需求不明确等等的问题 xff0c 我目前也是达到了这样一个状
  • 正点原子MiniFly V1.2学习笔记六---stabilizerTask

    第9个任务 xff0c 优先级5 xTaskCreate stabilizerTask 34 STABILIZER 34 450 NULL 5 NULL 一 任务函数 使用绝对延时 xff0c 周期执行任务 二 传感器数据是怎么传到这个任务
  • 正点原子MiniFly V1.2学习笔记七---configParamTask

    第6个任务 xff0c 优先级1 xff0c 最低优先级 配置参数任务 xTaskCreate configParamTask 34 CONFIG TASK 34 150 NULL 1 NULL 一 全局参数configParam 1 参数
  • C++码农要读的经典

    刚大四 xff0c 还在忙着找工作 xff0c 读过的书不是很多 xff0c 还有一些好书在读 xff0c 还有一些书将来必读 C语言程序设计 谭浩强版本 这个版本一致被人说误导子弟 xff0c 当然还有很多人推崇 我觉得这本书不是什么好书
  • 解读gazebo_ros_control gazebo_ros

    本篇的目的是想解读gazebo ros control 以及 gazebo ros 因为gazebo本身是独立于ros的 通过教程Intermediate Control plugin 以及教程 Category Write a plugi
  • vtaskstartscheduler(); //开启任务调度语句不执行

    项目场景 xff1a FreeRTOS实时嵌入式操作系统开发 基于stm32 第一章移植代码 问题描述 xff1a 任务调度器执行到vtaskstartscheduler 开启任务调度语句不执行 span class token keywo
  • python3中定义类变量,并使用类函数修改类变量的值

    定义类变量的方式有两种 1 在 init 中定义self elements 其中self elements是类变量名 a是传入Difference类的参数名 xff0c 这里的 init 作用是定义了类变量名 xff0c 将外部参数a传给类
  • printf函数的内涵以及造成的严重内存问题

    问题的引出 xff1a 在某型号的核心网络交换机设备中 xff0c 为调试方便 xff0c 实现了一个把内存内容从终端打印的功能 xff0c 也就是dump memory xff0c 屏幕的左边显示十六进制 xff0c 右边以ASCII形式
  • 关于docker那点事儿——Dockerfile编写

    Dockerfile编写 前言一 Dockerfile创建镜像二 Dockerfile常用指令三 示例1 Dockerfile构建nginx镜像2 Dockerfile构建微服务 四 CMD与ENTRYPOINT比较 前言 Dockerfi