当前位置: 首页 > news >正文

Docker 镜像结构与相关核心知识总结

Docker 镜像结构与相关核心知识总结

Docker 镜像展开,从镜像与容器的关系、镜像分层结构、镜像构建方法及 Dockerfile 核心语法四个维度,系统阐述了 Docker 镜像的核心知识,旨在帮助使用者理解镜像本质、掌握镜像构建与定制技巧

一、镜像与容器的关系

1. 核心关联

  • 镜像为容器提供基础:Docker 镜像是容器运行的前提,无镜像则无法创建容器,这是 Docker 的核心设计原则。镜像属于静态内容,包含容器运行所需的文件系统(如代码、二进制文件、运行时、依赖等),但不包含 Linux 内核;容器是动态进程,运行时占用内存、CPU、虚拟网络设备,并通过镜像的文件系统层获取资源
  • 转化机制:镜像通过自身的json文件实现静态到动态的转化。Docker 守护进程(Docker Daemon)解析json文件,获取容器需运行的进程、环境变量配置,为容器分配资源并启动进程,最终创建容器。容器启动后,json文件失效,镜像仅作为文件系统供容器进程访问

2. 本质区别

维度Docker 镜像Docker 容器
状态静态(文件集合)动态(运行进程)
核心作用提供文件系统和运行配置执行应用进程,占用系统资源
生命周期构建后固定,可重复使用启动后存在,停止后可删除

二、镜像的分层结构

1. 基础概念:Base 镜像

Base 镜像是分层结构的根基,具备两层核心含义:

  • 不依赖其他镜像,从空白镜像scratch构建
  • 可作为基础,供其他镜像扩展(如 CentOS、Ubuntu 等 Linux 发行版镜像)

不同 Linux 发行版 Base 镜像的区别主要在用户空间(rootfs),如 CentOS 7 用systemd管理服务、yum管理软件,Ubuntu 14.04 用upstartapt,而内核空间(Kernel)依赖 Docker 主机(Docker Host)的内核,容器无法修改内核

2. 分层机制

  • 镜像层:绝大多数镜像基于其他镜像构建,每一步操作(如安装软件、创建目录)生成一个新的镜像层,所有镜像层联合组成统一文件系统。若不同层有相同路径文件(如/galaxy),上层文件会覆盖下层,用户仅能访问上层文件
  • 容器层:容器启动时,镜像顶部加载一个可写的容器层,容器层之下均为只读的镜像层。容器运行中的文件修改(如创建、删除文件)仅发生在容器层,不会影响镜像层,确保镜像可重复使用

三、Docker 镜像构建方法

Docker 提供三种镜像构建方式,各有适用场景与优缺点,具体对比如下:

构建方法核心操作优点缺点适用场景
docker commit 命令1. 基于基础镜像启动容器;2. 在容器内安装软件 / 配置环境;3. 用docker commit <容器名> <新镜像名>打包容器为镜像操作直观,适合临时测试手工操作易出错、效率低;镜像构建过程不透明,存在安全隐患(无法审计是否含恶意程序)快速生成临时镜像,不推荐生产环境
基于本地模板导入1. 下载操作系统模板(如 OpenVZ 模板,地址:http://openvz.org/Download/templates/precreated);2. 用docker import <模板文件> <镜像名:标签>导入直接复用现成模板,操作简单模板来源有限,定制化程度低快速获取特定版本操作系统镜像
Dockerfile 构建(推荐)1. 编写 Dockerfile(含基础镜像、操作指令等);2. 用docker build -t <镜像名:标签> [路径]执行构建构建过程透明(可通过docker history <镜像名>查看);可重复执行,支持版本控制;定制化灵活需学习 Dockerfile 语法生产环境、自定义应用镜像构建

四、Dockerfile 核心知识

1. 基本概念与文件结构

Dockerfile 是一个文本文件,包含一系列指令,每一条指令对应一层镜像,通过指令描述镜像的构建步骤。其文件结构分为四部分:

  1. 基础镜像信息:必须放在首行(非注释行),用FROM指定
  2. 维护者信息:用MAINTAINER(旧版)或LABEL(新版)指定
  3. 镜像操作指令:如安装软件(RUN)、复制文件(COPY/ADD)、暴露端口(EXPOSE)等
  4. 容器启动执行指令:如CMD(指定默认启动进程)、ENTRYPOINT(指定固定启动进程)

2. 常用指令及语法

Dockerfile 指令决定镜像的构建逻辑与容器启动行为,核心指令如下:

指令作用语法格式关键说明
FROM指定基础镜像FROM <仓库名>:<标签>FROM <仓库名>@<哈希值>哈希值(Digest)用于防止镜像被冒名顶替,确保安全性
MAINTAINER/LABEL声明镜像作者 / 元数据MAINTAINER <邮箱>LABEL <键>=<值> <键>=<值>MAINTAINER已被LABEL替代,LABEL支持多键值对元数据
COPY/ADD复制文件到镜像COPY <源路径> <目标路径>ADD <源路径> <目标路径>ADD支持自动解压本地 tar 文件、下载 URL 文件(URL tar 不自动解压),COPY仅复制本地文件,推荐优先用COPY
RUN构建镜像时执行命令RUN <shell命令>RUN ["可执行文件", "参数1", "参数2"]命令需在基础镜像中存在,运行于docker build阶段
CMD指定容器默认启动进程1. CMD ["可执行文件", "参数1", "参数2"];2. CMD <shell命令>;3. CMD ["参数1", "参数2"](配合ENTRYPOINT仅最后一个CMD生效;docker run命令行参数可覆盖CMD;进程结束后容器终止
ENTRYPOINT指定容器固定启动进程1. ENTRYPOINT ["可执行文件", "参数1", "参数2"];2. ENTRYPOINT <shell命令>docker run命令行参数会作为参数传递给ENTRYPOINT,仅--entrypoint选项可覆盖
EXPOSE声明容器待暴露端口EXPOSE <端口>/<协议>(如EXPOSE 80/tcp 443/udp仅为声明,需docker run -P(随机映射)或-p <主机端口>:<容器端口>实现真正端口映射
ENV定义环境变量ENV <键> <值>ENV <键>=<值> <键>=<值>变量可被后续指令调用($变量名${变量名}),docker run -e可覆盖变量值
WORKDIR指定工作目录WORKDIR <绝对/相对路径>影响后续指令的执行目录,可调用ENV定义的变量
VOLUME创建镜像挂载点VOLUME <挂载点>VOLUME ["<挂载点>"]仅支持 Docker 管理的卷(指定容器内路径),不支持宿主机路径,用于数据持久化
USER指定构建 / 运行用户USER <用户名>:<组名>USER <UID>:<GID>默认用户为 root,用于限制容器进程权限

3. 镜像缓存机制

  • 缓存原理docker build时,Docker 会缓存每一层镜像。若构建新镜像时,指令与之前一致(如基础镜像未变、RUN命令未改),则直接复用缓存层,加速构建
  • 禁用缓存:若需强制重新构建所有层,可在docker build后加--no-cache参数(如docker build --no-cache -t <镜像名> .

五、核心总结

  1. 镜像本质:静态文件系统集合,无内核,为容器提供运行基础;容器是动态进程,依赖镜像文件系统并占用系统资源
  2. 分层优势:Base 镜像为根基,镜像层只读可复用,容器层可写隔离修改,降低存储占用与构建时间。
  3. 构建首选:Dockerfile 构建是生产环境首选,因其透明、可重复、易维护,docker commit与模板导入仅适合临时场景
  4. 指令关键区别RUN(构建时执行)与CMD/ENTRYPOINT(容器启动时执行);CMD可被命令行覆盖,ENTRYPOINT仅能被--entrypoint覆盖

分层结构
Docker里的镜像绝大部分都是在别的镜像的基础上去进行创建的,也就是使用镜像的分层结
构。实际上,Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来
的。比如我们现在构建一个新的镜像,具体操作如下:

[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    07ccdb783875   14 hours ago   160MB
luoqi        v1        e80543456e0c   8 days ago     204MB
nginx        <none>    203ad09fc156   7 weeks ago    192MB
httpd        latest    2416cb32cb59   2 months ago   117MB
httpd        sysy      2416cb32cb59   2 months ago   117MB
centos       7         eeb6ee3f44bd   4 years ago    204MB
[root@docker ~]# vim Dockerfile
FROM centos:7
RUN mkdir /luoqi
RUN touch /luoqi/cy
CMD ["/bin/bash"]
~  
[root@docker ~]# docker build -t luoqi:v1 .
[+] Building 0.8s (7/7) FINISHED                                                  docker:default=> [internal] load build definition from Dockerfile                                        0.0s=> => transferring dockerfile: 106B                                                        0.0s=> [internal] load metadata for docker.io/library/centos:7                                 0.0s=> [internal] load .dockerignore                                                           0.0s=> => transferring context: 2B                                                             0.0s=> [1/3] FROM docker.io/library/centos:7                                                   0.0s=> [2/3] RUN mkdir /luoqi                                                                  0.4s=> [3/3] RUN touch /luoqi/cy                                                               0.3s=> exporting to image                                                                      0.0s=> => exporting layers                                                                     0.0s=> => writing image sha256:f72f60e820dc6bbeca2e398bb6342d8aa98c07289fcfcf2cc338b97305127e  0.0s=> => naming to docker.io/library/luoqi:v1      
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
luoqi        v1        f72f60e820dc   46 seconds ago   204MB
[root@docker ~]# docker history luoqi:v1 
IMAGE          CREATED              CREATED BY                                      SIZE      COMMENT
f72f60e820dc   About a minute ago   CMD ["/bin/bash"]                               0B        buildkit.dockerfile.v0
<missing>      About a minute ago   RUN /bin/sh -c touch /luoqi/cy # buildkit       0B        buildkit.dockerfile.v0
<missing>      About a minute ago   RUN /bin/sh -c mkdir /luoqi # buildkit          0B        buildkit.dockerfile.v0
<missing>      4 years ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      4 years ago          /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      4 years ago          /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB    

docker镜像构建三种方法
Docker提供了三种构建镜像的方法:
1、docker commit命令
2、基于本地模板导入
3、Dockerfile构建文件

docker commit
docker commit命令可以基于容器创建镜像,创建过程大致分为三步,先创建容器,在容器中安装我
们所需要的内容,再使用docker commit将容器打包为镜像即可
下面展示一个示例:在centos的base镜像中安装vim-common并保存为新镜像
1、先基于centos7运行容器,容器名为cy,并使用-it生成终端进入容器

[root@docker ~]# docker run --name sy -it centos:7 /bin/bash

2、在容器中安装vim-common

[root@306bed18de27 /]# yum -y install vim-common
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=container error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error"One of the configured repositories failed (Unknown),and yum doesn't have enough cached data to continue. At this point the onlysafe thing yum can do is fail. There are a few ways to work "fix" this:1. Contact the upstream for the repository and get them to fix the problem.2. Reconfigure the baseurl/etc. for the repository, to point to a workingupstream. This is most often useful if you are using a newerdistribution release than is supported by the repository (and thepackages for the previous distribution release still work).3. Run the command with the repository temporarily disabledyum --disablerepo=<repoid> ...4. Disable the repository permanently, so yum won't use it by default. Yumwill then just ignore the repository until you permanently enable itagain or use --enablerepo for temporary usage:yum-config-manager --disable <repoid>orsubscription-manager repos --disable=<repoid>5. Configure the failing repository to be skipped, if it is unavailable.Note that yum will try to contact the repo. when it runs most commands,so will have to try and fail each time (and thus. yum will be be muchslower). If it is a very temporary problem though, this is often a nicecompromise:yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=trueCannot find a valid baseurl for repo: base/7/x86_64

3、退出容器后,使用docker commit将v1容器打包为镜像,新镜像名为centos:v1

[root@docker ~]# docker commit sy centossy:7
sha256:4d740ad40a41bccac21a453d819248a1c2c11811acf4c1fb0f2624912f6c0aba
[root@docker ~]# docker images | grep centos
centossy     7         4d740ad40a41   13 seconds ago   228MB
centos       7         eeb6ee3f44bd   4 years ago      204MB
[root@docker ~]# docker run --name sy2 -it centossy:7
[root@f43620dfbe58 /]# [root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
centossy     7         4d740ad40a41   About a minute ago   228MB

docker commit
这样一个新的镜像就构建完成了,centoscy:7镜像是在centos:7镜像基础之上创建的,通过查看镜像
属性,发现centoscy:7要比centos:7镜像大一些
然而,Docker并不建议用户通过这种方式构建镜像。这是一种手工创建镜像的方式,容易出错,效
率低且可重复性弱。更重要的,使用者并不知道镜像是如何创建出来的,里面是否有恶意程序。也就是说无法对镜像进行审计,存在安全隐患

基于本地模板导入
用户可以直接从一个操作系统模板文件导入一个镜像,主要使用 docker [container] import 命令
命令 格式为 docker [image] import [OPTIONS] file|URL|-[REPOSITORY[:TAG]] ,要直接导入一个镜
像,可以使用 OpenVZ 提供的模板来创建,或者用其他已导入的镜像模板来创建。OpenVZ 模板的下载
地址为 http://openvz.org/Download/templates/precreated
如:下载了 ubuntu:12.04 的模板压缩包,之后使用以下命令导入即可:

[root@docker ~]# rz -E
rz waiting to receive.
[root@docker ~]# ls
anaconda-ks.cfg  Desktop     Downloads             nginx     Templates
centos.tar.gz    Dockerfile  initial-setup-ks.cfg  Pictures  ubuntu-12.04-x86-minimal.tar.gz
data             Documents   Music                 Public    Videos
[root@docker ~]# docker import ubuntu-12.04-x86-minimal.tar.gz syubuntu:v1
sha256:c24052f699a9d66f3875765db4a0960a17d8c3b185140083a5d6c12ae5a63fdf
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
syubuntu     v1        c24052f699a9   5 seconds ago    146MB

dockerfile的基本概念
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件
外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构
建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问
题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是Dockerfile
Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因
此每一条指令的内容,就是描述该层应当如何构建。有了Dockerfile,当我们需要定制自己额外的
需求时,只需在 Dockerfile上添加或者修改指令,重新生成镜像即可,省去了敲命令的麻烦

dockerfile文件格式
Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动执行指令。一开始必须要指明所基于的镜像名称,接下来一般会说明维护者信息;后面则是镜像操作指令,例如ADD指令。每执行一条ADD指令,镜像添加新的一层,并提交;最后是CMD指令,来指明运行容器时的操作命令。
示例如下,我们构建一个httpd镜像

[root@docker ~]# ls
Dockerfile 
[root@docker ~]# vim Dockerfile 
FROM centos:7         # 1、第一行必须指定,基础镜像信息
MAINTAINER shenyi@example.com        # 2、维护者信息
RUN yum install -y httpd     3、镜像操作指令 
EXPOSE 80
CMD ["/bin/bash"]       # 4、容器启动执行指令
~  

把构建容器所需要的指令都存放在Dockerfile文件中,这个文件的名字是固定的,不能够更改,再使用docker build命令构建容器,使用-t定义新的镜像名,如果构建镜像的Dockerfile文件不在当前目录下可以使用-f指定
Dockerfile文件路径,示例如下:

[root@docker ~]# docker build -t httpd:sysy /root/
[+] Building 1.3s (5/5) FINISHED                                                  docker:default=> [internal] load build definition from Dockerfile                                        0.0s=> => transferring dockerfile: 134B                                                        0.0s=> [internal] load metadata for docker.io/library/centos:7                                 0.0s=> [internal] load .dockerignore                                                           0.0s=> => transferring context: 2B                                                             0.0s=> CACHED [1/2] FROM docker.io/library/centos:7                                            0.0s=> ERROR [2/2] RUN yum install -y httpd                                                    1.3s
------                                                                                           > [2/2] RUN yum install -y httpd:                                                               
0.506 Loaded plugins: fastestmirror, ovl                                                         
0.704 Determining fastest mirrors                                                                
1.216 Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=container error was
1.216 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error"
1.221 
1.221 
1.221  One of the configured repositories failed (Unknown),
1.221  and yum doesn't have enough cached data to continue. At this point the only
1.221  safe thing yum can do is fail. There are a few ways to work "fix" this:
1.221 
1.221      1. Contact the upstream for the repository and get them to fix the problem.
1.221 
1.221      2. Reconfigure the baseurl/etc. for the repository, to point to a working
1.221         upstream. This is most often useful if you are using a newer
1.221         distribution release than is supported by the repository (and the
1.221         packages for the previous distribution release still work).
1.221 
1.221      3. Run the command with the repository temporarily disabled
1.221             yum --disablerepo=<repoid> ...
1.221 
1.221      4. Disable the repository permanently, so yum won't use it by default. Yum
1.221         will then just ignore the repository until you permanently enable it
1.221         again or use --enablerepo for temporary usage:
1.221 
1.221             yum-config-manager --disable <repoid>
1.221         or
1.221             subscription-manager repos --disable=<repoid>
1.221 
1.221      5. Configure the failing repository to be skipped, if it is unavailable.
1.221         Note that yum will try to contact the repo. when it runs most commands,
1.221         so will have to try and fail each time (and thus. yum will be be much
1.221         slower). If it is a very temporary problem though, this is often a nice
1.221         compromise:
1.221 
1.221             yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true
1.221 
1.221 Cannot find a valid baseurl for repo: base/7/x86_64
------
Dockerfile:3
--------------------1 |     FROM centos:72 |     MAINTAINER shenyi@example.com3 | >>> RUN yum install -y httpd4 |     EXPOSE 805 |     CMD ["/bin/bash"]
--------------------
ERROR: failed to solve: process "/bin/sh -c yum install -y httpd" did not complete successfully: exit code: 1

通过以上镜像的构建过程可以看出,Dockerfile文件内的指令会逐一运行,构建过程如下:
1、下载centos7镜像
2、添加镜像构建者信息

dockerfile文件格式
3、基于centos7镜像启动容器,安装httpd软件,安装完毕后将容器打包为镜像
4、基于上一步生成的镜像启动容器,将80端口打开,打开后将容器打包为镜像
5、基于上一步生成的镜像启动容器,添加容器启动后需要执行的指令,再打包为镜像
也就说一条指令就是一层镜像,还可以通过docker history查看镜像的构建过程,这样我们构建的镜像就呈现出透明化,整个构建的过程都可以看到

[root@docker ~]# docker history httpd:sysy
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
2416cb32cb59   2 months ago   CMD ["httpd-foreground"]                        0B        buildkit.dockerfile.v0
<missing>      2 months ago   EXPOSE map[80/tcp:{}]                           0B        buildkit.dockerfile.v0
<missing>      2 months ago   COPY httpd-foreground /usr/local/bin/ # buil…   138B      buildkit.dockerfile.v0
<missing>      2 months ago   STOPSIGNAL SIGWINCH                             0B        buildkit.dockerfile.v0
<missing>      2 months ago   RUN /bin/sh -c set -eux;   savedAptMark="$(a…   32.5MB    buildkit.dockerfile.v0
<missing>      2 months ago   ENV HTTPD_PATCHES=                              0B        buildkit.dockerfile.v0
<missing>      2 months ago   ENV HTTPD_SHA256=58b8be97d9940ec17f7656c0c6b…   0B        buildkit.dockerfile.v0
<missing>      2 months ago   ENV HTTPD_VERSION=2.4.65                        0B        buildkit.dockerfile.v0
<missing>      2 months ago   RUN /bin/sh -c set -eux;  apt-get install --…   5.65MB    buildkit.dockerfile.v0
<missing>      2 months ago   WORKDIR /usr/local/apache2                      0B        buildkit.dockerfile.v0
<missing>      2 months ago   RUN /bin/sh -c mkdir -p "$HTTPD_PREFIX"  && …   0B        buildkit.dockerfile.v0
<missing>      2 months ago   ENV PATH=/usr/local/apache2/bin:/usr/local/s…   0B        buildkit.dockerfile.v0
<missing>      2 months ago   ENV HTTPD_PREFIX=/usr/local/apache2             0B        buildkit.dockerfile.v0
<missing>      2 months ago   # debian.sh --arch 'amd64' out/ 'trixie' '@1…   78.6MB    debuerreotype 0.16

镜像缓存
使用DockerFile文件构建完镜像以后,Docker会把构建过程中的每一层临时镜像进行缓存。在构建新镜像时,可以直接使用之前缓存的镜像层,这样能加速镜像的构建。镜像缓存示例如下:

[root@docker ~]# vim Dockerfile 
FROM centos:7       # 1、第一行必须指定,基础镜像信息
MAINTAINER shenyi@example.com     # 2、维护者信息 
RUN mkdir /galaxy     # 3、镜像操作指令
~ 

修改之前的Dockerfile文件,然后我们再构建新的镜像,构建过程如下,通过构建过程可以得知,DockerFile文件里面共三条指令,前两条指令都是用之前构建镜像的缓存,只有第三个指令才重新构建了缓存层。如果希望在构建镜像时不使用缓存,可以在docker build命令中加上–no-cache参数

[root@docker ~]# docker build -t sycentos:7 .
[+] Building 0.4s (6/6) FINISHED                                                  docker:default=> [internal] load build definition from Dockerfile                                        0.0s=> => transferring dockerfile: 99B                                                         0.0s=> [internal] load metadata for docker.io/library/centos:7                                 0.0s=> [internal] load .dockerignore                                                           0.0s=> => transferring context: 2B                                                             0.0s=> CACHED [1/2] FROM docker.io/library/centos:7                                            0.0s=> [2/2] RUN mkdir /galaxy                                                                 0.3s=> exporting to image                                                                      0.0s=> => exporting layers                                                                     0.0s=> => writing image sha256:74d5027f7c62dee6b2e318a3169c1bedd596e2a1ad2cdad3facfa36ccfbf2f  0.0s=> => naming to docker.io/library/sycentos:7      

总结
1、镜像的来源多种多样,可以通过Docker Hub社区获取,或者通过国内的公有镜像仓库中获取
2、Docker镜像是Docker容器运行的基础,没有Docker镜像,就不可能有Docker容器,这也是Docker的设计原则之一
3、Docker可以同时支持多种Linux镜像,模拟出多种操作系统环境。容器只能使用Docker host的kernel,并且不能修改
4、base镜像有两层含义:不依赖其他镜像,从scratch构建;以此为基础镜像,进行扩展
5、构建镜像的方式有三种:使用docker commit构建、基于本地模板导入和使用Dockerfile构建构建
6、docker commit命令可以基于容器创建镜像,创建过程大致分为三步,先创建容器,在容器中安装我们所需要的内容,再使用docker commit将容器打包为镜像即可
7、用户可以使用docker import命令直接从一个操作系统模板文件导入一个镜像

  1. 构建镜像的方式有三种:使用docker commit构建、基于本地模板导入和使用Dockerfile构建构建
    9、Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建
    10、在Dockerfile语法中,RUN、CMD都是运行命令的指令,RUN是在构建镜像时运行的命令,CMD是容器启动时运行的命令
http://www.dtcms.com/a/457280.html

相关文章:

  • 容器技术与 Docker 入门部署
  • linux学习笔记(20)线程
  • Vue3后台表单快速开发
  • 前端技术栈 —— 创建React项目
  • 推荐一个 GitHub 开源项目信息卡片生成工具,支持Docker快速部署和API调用
  • 元宇宙的工业制造应用:重构生产、研发与供应链
  • 做美足网站违法吗北京网站建设哪家比较好
  • 2025版本的idea解决Git冲突
  • 深入浅出 HarmonyOS ArkTS:现代跨平台应用开发的语法基石
  • Spring boot 3.0整合RocketMQ不兼容的问题
  • 淮安制作企业网站莱芜金点子最新招聘
  • AI+机器人浪潮已至:是方舟还是巨浪?
  • Linux:虚拟世界的大门
  • 市桥网站建设培训数据库与网站建设
  • LangGraph学习笔记 (二)-10分钟搭建自己第一个Agent
  • Sutton:LLM 通往 AGI 的隐秘瓶颈
  • 吴恩达机器学习课程(PyTorch 适配)学习笔记大纲
  • 聊透自动驾驶系统:从“怎么跑”到“怎么聪明跑”
  • 网站建设属于什么职能wordpress建站教程
  • LeetCode 刷题【107. 二叉树的层序遍历 II、108. 将有序数组转换为二叉搜索树】
  • 宝塔服务器面板部署安装git通过第三方应用安装收费怎么办—bash: git: command not found解决方案-优雅草卓伊凡
  • 9. linux shell命令(6)Linux网络配置管理
  • 专做品质游的网站河东苏州网站建设
  • Spring的三级缓存原理 笔记251008
  • Coze源码分析-资源库-编辑数据库-后端源码-应用/领域/数据访问/基础设施层
  • 北京建设网站的公司兴田德润简介济南网站建设平台官网
  • 力扣 —— 动态规划(背包问题)
  • 基础微网站开发代理商wordpress图文模板
  • bind,apply,call
  • 最新ECCV最新大感受野的小波卷积