百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

05-docker系列-使用dockerfile构建镜像

toyiye 2024-07-09 23:02 11 浏览 0 评论

声明:本文乃“运维家”原创,转载请注明出处,更多内容请关注公众号“运维家”。


主旨

上一篇文章介绍了使用commit方式来构建自定义镜像,那么本文来介绍下主流方式,如何使用dockerfile来构建镜像。


环境

linux环境
docker环境


概念

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。


下载镜像

本文使用nginx镜像来做示范,故而需要先下载一个nginx镜像;

[yunweijia@localhost ~]$ sudo docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
5eb5b503b376: Pull complete 
1ae07ab881bd: Pull complete 
78091884b7be: Pull complete 
091c283c6a66: Pull complete 
55de5851019b: Pull complete 
b559bad762be: Pull complete 
Digest: sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[yunweijia@localhost ~]$ sudo docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
centos        ceshi     adeae577d8b3   4 hours ago    359MB
nginx         latest    c316d5a335a5   2 weeks ago    142MB
hello-world   latest    feb5d9fea6a5   4 months ago   13.3kB
centos        7         eeb6ee3f44bd   4 months ago   204MB
[yunweijia@localhost ~]$


FROM和RUN

文件名必须是Dockerfile,且该目录下不要存放无用的文件。

[yunweijia@localhost ~]$ mkdir -pv docker/nginx
mkdir: 已创建目录 "docker"
mkdir: 已创建目录 "docker/nginx"
[yunweijia@localhost ~]$ cd docker/nginx/
[yunweijia@localhost nginx]$ vim Dockerfile
FROM nginx
RUN echo "这是运维家进行测试的一个nginx镜像" > /usr/share/nginx/html/index.html
# 保存退出


参数解释:

FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。有以下两种格式:
  shell格式:RUN <命令行命令>
    # 命令行命令就是在终端shell中执行的命令
  exec格式:RUN [“可执行文件”,“参数1”,“参数2”]
    # RUN ["./test.sh","yunweijia","ls"] 等同于 RUN ./test.sh yunweijia ls

注意:Dockerfile的指令,每执行一次都会在docker上新建一层,这样子就会造成制作出来的镜像变的很大,我们争取能一行写完的内容,就不要写多行,这也是很多人制作完镜像之后发现自己的镜像特别大的原因所在。


构建镜像:

需要指定Dockerfile文件的目录。

语法:docker bulid -t 镜像:版本号 Dockerfile文件目录
[yunweijia@localhost nginx]$ sudo docker build -t nginx:yunweijia /home/yunweijia/docker/nginx/
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM nginx
 ---> c316d5a335a5
Step 2/2 : RUN echo "这是运维家进行测试的一个nginx镜像" > /usr/share/nginx/html/index.html
 ---> Running in 0904cf0d2196
Removing intermediate container 0904cf0d2196
 ---> 2c95163ff074
Successfully built 2c95163ff074
Successfully tagged nginx:yunweijia
[yunweijia@localhost nginx]$ sudo docker images
REPOSITORY    TAG         IMAGE ID       CREATED         SIZE
nginx         yunweijia   2c95163ff074   5 seconds ago   142MB
centos        ceshi       adeae577d8b3   22 hours ago    359MB
nginx         latest      c316d5a335a5   2 weeks ago     142MB
hello-world   latest      feb5d9fea6a5   4 months ago    13.3kB
centos        7           eeb6ee3f44bd   4 months ago    204MB
[yunweijia@localhost nginx]$


验证:

[yunweijia@localhost nginx]$ sudo docker run -d nginx:yunweijia
69f76ab38fb273a5ad7c423e5667b6e0c632fc3acbc057bd82c824957a5b6fe1
[yunweijia@localhost nginx]$ 
[yunweijia@localhost nginx]$ sudo docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS         PORTS     NAMES
69f76ab38fb2   nginx:yunweijia   "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds   80/tcp    musing_liskov
[yunweijia@localhost nginx]nbsp;
[yunweijia@localhost nginx]nbsp;sudo docker exec -it 69f76ab38fb2 /bin/bash
root@69f76ab38fb2:/# cd /usr/share/nginx/html/
root@69f76ab38fb2:/usr/share/nginx/html# cat index.html 
这是运维家进行测试的一个nginx镜像
root@69f76ab38fb2:/usr/share/nginx/html# exit
exit
[yunweijia@localhost nginx]$


COPY

复制文件,将宿主机的文件或者目录复制到容器指定目录中。

语法:COPY [--chown=<user>:<group>] <源路径> <目标路径>
  [--chown=<user>:<group>] :可选参数,用户改变复制到容器内文件的用户和组
  <目标路径>:不需要提前创建好,如果不存在,会自动创建
实例:
  COPY /home/yunweijia/test.sh /home/


CMD

类似于RUN命令,不同之处如下:

CMD:在docker run 时运行。
RUN:是在 docker build时运行。

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

注意:如果dockerfile中存在多个CMD指令,那么只有最后一个生效。

语法:
  CMD <shell 命令> 
  CMD ["<param1>","<param2>",...]


ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序,这句话什么意思呢,就是说你ENTRYPOINT指定的东西,如果需要参数,那么你用docker run的时候可以再指定。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果 dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

语法:
  ENTRYPOINT ["<executeable>","<param1>","<param2>",...]


可以搭配CMD命令使用,实例如下:

# 假设你通过以下Dockerfile文件,生成了一个nginx:ceshi镜像:
FROM nginx
ENTRYPOINT ["nginx","-c"]
CMD ["/usr/share/nginx/conf/nginx.conf]


# 不传参运行的时候
sudo docker run -d nginx:ceshi
# 容器中相当于执行了如下命令
nginx -c /usr/share/nginx/conf/nginx.conf


# 传参运行的时候
sudo docker run -d nginx:ceshi -c /home/nginx/nginx.conf
# 容器中相当于执行了如下命令
nginx -c /home/nginx/nginx.conf


ENV

设置环境变量

语法:
  ENV <key> <value>
  ENV <key1>=<value1> <key2>=<value2>...
实例:
  ENV yunweijia 1.1.0
  RUN echo "这个版本是$yunweijia" > /usr/share/nginx/html/index.html


ARG

构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对应 Dockerfile 内有效,也就是说只要有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

语法:
  ARG <参数名>[=<默认值>]


VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。这样子可以避免你把数据存放到docker容器里面,后面一不小心删除容器的情况。也可以避免容器随着数据的存放越来越大。

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

当然了,在启动容器的时候我们可以覆盖此项配置,使用 -v 参数即可修改挂载点。


EXPOSE

申明端口,帮助镜像使用者理解守护端口,以方便配置映射;在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

语法:
  EXPOSE <端口1> [<端口2>...]


WORKDIR

指定工作目录,即切换目录,且此目录必须是提前创建好的。

语法:
  WORKDIR <工作目录路径>


USER

用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

语法:
  USER <用户名>[:<用户组>]


HEALTHCHECK

用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

语法:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。


ONBUILD

用于延迟构建命令的执行。简单的来说,比如你此次创建的镜像A,使用了ONBUILD指定了一个命令,那么你在构建镜像A中是不会执行这个命令的;但是当有人用你的镜像A构建其他镜像的时候,就会执行ONBUILD指定的命令了。

语法:
  ONBUILD <其它指令>


LABEL

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式。

语法:
  LABEL <key>=<value> <key>=<value> <key>=<value> ...
实例:
  LABEL image.authors="运维家"


至此,使用dockerfile构建镜像结束。后面的文章中我们将使用dockerfile构建nginx、redis等镜像。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码