前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2022年01月 Docker容器 Dockerfile详解

【愚公系列】2022年01月 Docker容器 Dockerfile详解

作者头像
愚公搬代码
发布2022-12-01 09:50:44
6490
发布2022-12-01 09:50:44
举报
文章被收录于专栏:历史专栏

文章目录


前言

Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。

docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。

例:

代码语言:javascript
复制
docker build -f /path/to/a/Dockerfile

一、Dockerfile的基本结构

Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。

二、Dockerfile文件指令说明

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

1.使用 Dockerfile 定制镜像

1、下面以定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)

在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:

代码语言:javascript
复制
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html

2、FROM 和 RUN 指令的作用

FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。 RUN:用于执行后面跟着的命令行命令。有以下俩种格式: shell 格式:

代码语言:javascript
复制
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。

exec 格式:

代码语言:javascript
复制
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

代码语言:javascript
复制
FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

代码语言:javascript
复制
FROM centos
RUN yum install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

开始构建镜像 在 Dockerfile 文件的存放目录下,执行构建动作。

以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。

代码语言:javascript
复制
$ docker build -t nginx:v3 .

三、其他命令详解

1:ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

格式:

代码语言:javascript
复制
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过$NODE_VERSION 引用:

代码语言:javascript
复制
ENV NODE_VERSION 7.2.0

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"

2:COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

格式:

代码语言:javascript
复制
COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]

[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。

<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

代码语言:javascript
复制
COPY hom* /mydir/
COPY hom?.txt /mydir/

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

3:ADD

格式:ADD

代码语言:javascript
复制
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径

示例:

代码语言:javascript
复制
ADD hom* /mydir/          # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/      # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/     # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/

4:EXPOSE

格式:

代码语言:javascript
复制
EXPOSE <port> [<port>...]

示例:

代码语言:javascript
复制
EXPOSE 80 443
EXPOSE 8080    
EXPOSE 11211/tcp 11211/udp

注:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口

5:USER

格式:

代码语言:javascript
复制
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group

示例:

代码语言:javascript
复制
USER www

注:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。

6:WORKDIR

格式:

代码语言:javascript
复制
WORKDIR /path/to/workdir

示例:

代码语言:javascript
复制
WORKDIR /a  (这时工作目录为/a)
WORKDIR b  (这时工作目录为/a/b)
WORKDIR c  (这时工作目录为/a/b/c)

注:通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

7:RUN

RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:

7.1 shell执行

格式:

代码语言:javascript
复制
RUN <command>

7.2 exec执行

格式:

代码语言:javascript
复制
RUN ["executable", "param1", "param2"]

示例:

代码语言:javascript
复制
 RUN ["executable", "param1", "param2"]
 RUN apk update
 RUN ["/etc/execfile", "arg1", "arg1"]

注:RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定–no-cache参数,如:docker build --no-cache

8:CMD

格式:

代码语言:javascript
复制
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)

示例:

代码语言:javascript
复制
CMD echo "This is a test." | wc -
CMD ["/usr/bin/wc","--help"]

注:CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。

9:ENTRYPOINT

格式:

代码语言:javascript
复制
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)

示例:

代码语言:javascript
复制
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

注:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。

总结

关键字

作用

FROM

指定基础镜像

MAINTAINER

作者的信息

RUN

执行什么命令

EXPOSE

容器对外暴露的端口

WORKDIR

进入到容器后进入到哪个目录

ENV

配置环境变量

ADD

将文件拷贝到镜像中并解压

COPY

将文件拷贝到镜像中

VOLUME

配置数据卷

CMD

容器启动时候执行的命令

ENTRYPOINT

容器启动时候执行的命令

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 前言
  • 一、Dockerfile的基本结构
  • 二、Dockerfile文件指令说明
    • 1.使用 Dockerfile 定制镜像
    • 三、其他命令详解
      • 1:ENV
        • 2:COPY
          • 3:ADD
            • 4:EXPOSE
              • 5:USER
                • 6:WORKDIR
                  • 7:RUN
                    • 7.1 shell执行
                    • 7.2 exec执行
                  • 8:CMD
                    • 9:ENTRYPOINT
                    • 总结
                    相关产品与服务
                    容器服务
                    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档