05. Docker容器:镜像的创建和实践

目录

一、Docker镜像的创建

1、基于现有容器创建

1.1 启动新的容器

1.2 提交为新镜像

1.3 启动新的容器

2、基于本地模板创建

2.1 下载地址

2.2 下载文件

2.3 导入镜像

2.4 运行容器

3、基于Dockerfile创建

3.1 联合文件系统(UnionFS)

3.2 docker镜像的分层(基于AUFS构建)

3.2.1 镜像的分层

3.2.2 涉及技术

3.3 镜像加载原理

3.4 为什么Docker里的centos的大小才200M

3.5 认识Dockerfile

3.6 Dockerfile结构

3.7 Docker镜像结构的分层

3.8 Dockerfile操作常用的指令

二、Dockerfile 镜像实战

1、构建 ssh 镜像

2、构建 systemctl 镜像

3、构建 apache 镜像

4、构建 nginx 镜像

5、构建 tomcat 镜像

6、构建 mysql 镜像

三、总结

1、创建镜像

1.1 基于现有镜像创建

1.2 基于本地模版创建

1.3 基于 Dockerfile 创建镜像


一、Docker镜像的创建

情况说明:创建镜像有三种方法,分别为基于已有的容器创建、基于本地模板创建以及基于Dockerfile创建

1、基于现有容器创建

1.1 启动新的容器

命令示例:首先创建并启动一个容器,在容器里新增数据

docker run -it --name test centos:7 /bin/bash
echo "hello world" |tee 1.txt
exit
docker ps -a

输出结果:

[root@MineGi ~]# docker run -it --name test centos:7 /bin/bash
[root@372617ed7dd0 /]# echo "hello world" |tee 1.txt
hello world
[root@372617ed7dd0 /]# exit
exit
[root@MineGi ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED          STATUS                     PORTS     NAMES
372617ed7dd0   centos:7   "/bin/bash"   30 seconds ago   Exited (0) 6 seconds ago             test
[root@MineGi ~]# 

1.2 提交为新镜像

docker commit -m "new-1.txt" -a "centos" test centos:new-1.txt  #创建新镜像
#常用选项:
-m:说明信息
-a:作者信息
-p:生成过程中停止容器的运行
docker images |grep new-1.txt 

命令示例:然后将新增数据后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像

docker ps -a
docker images |grep new-1.txt 
docker commit -m "new-1.txt" -a "centos" test centos:new-1.txt
docker images |grep new-1.txt 

输出结果:

[root@MineGi ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED              STATUS                      PORTS     NAMES
372617ed7dd0   centos:7   "/bin/bash"   About a minute ago   Exited (0) 51 seconds ago             test
[root@MineGi ~]# docker images |grep new-1.txt 
[root@MineGi ~]# docker commit -m "new-1.txt" -a "centos" test centos:new-1.txt
sha256:7e23e7ad18dd92566340c51588d58bab2a681f466a07b7b4eafdc6c98931aba7
[root@MineGi ~]# docker images |grep new-1.txt 
centos       new-1.txt   7e23e7ad18dd   3 seconds ago   204MB
[root@MineGi ~]# 

1.3 启动新的容器

命令示例:创建新容器并使用该镜像

docker run -it centos:new-1.txt /bin/bash
ls
cat 1.txt
exit
docker rm -f $(docker ps -aq)
docker ps -a

输出结果:

[root@MineGi ~]# docker run -it centos:new-1.txt /bin/bash
[root@5993132ccb28 /]# ls
1.txt              bin  etc   lib    media  opt   root  sbin  sys  usr
anaconda-post.log  dev  home  lib64  mnt    proc  run   srv   tmp  var
[root@5993132ccb28 /]# cat 1.txt 
hello world
[root@5993132ccb28 /]# exit
exit
[root@MineGi ~]# docker rm -f $(docker ps -aq)
5993132ccb28
372617ed7dd0
[root@MineGi ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@MineGi ~]# 

2、基于本地模板创建

情况说明:通过导入操作系统模板文件可以生成镜像,模板可以从 OPENVZ 开源项目下载

2.1 下载地址

下载地址为:http://openvz.org/Download/template/precreated

2.2 下载文件

【docker-images:百度网盘

方法一:浏览器下载包并上传至Linux机器
cd /opt      #上传centos-7-x86_64-minimal.tar.gz
 
方法二:直接在Linux机器下载包
wget http://download.openvz.org/template/precreated/centos-7-x86_64-minimal.tar.gz

命令示例:

wget http://download.openvz.org/template/precreated/centos-7-x86_64-minimal.tar.gz
ll centos-7-x86_64-minimal.tar.gz
ls -lh centos-7-x86_64-minimal.tar.gz

输出结果:

[root@MineGi ~]# wget http://download.openvz.org/template/precreated/centos-7-x86_64-minimal.tar.gz
--2024-12-18 10:43:30--  http://download.openvz.org/template/precreated/centos-7-x86_64-minimal.tar.gz
正在解析主机 download.openvz.org (download.openvz.org)... 130.117.225.97
正在连接 download.openvz.org (download.openvz.org)|130.117.225.97|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:145639219 (139M) [application/x-gzip]
正在保存至: “centos-7-x86_64-minimal.tar.gz”

100%[================================================================>] 145,639,219 1.49MB/s 用时 2m 4s  

2024-12-18 10:45:35 (1.12 MB/s) - 已保存 “centos-7-x86_64-minimal.tar.gz” [145639219/145639219])

[root@MineGi ~]# ll centos-7-x86_64-minimal.tar.gz
-rw-r--r-- 1 root root 145639219 11月 27 2016 centos-7-x86_64-minimal.tar.gz
[root@MineGi ~]# ls -lh centos-7-x86_64-minimal.tar.gz
-rw-r--r-- 1 root root 139M 11月 27 2016 centos-7-x86_64-minimal.tar.gz
[root@MineGi ~]#

2.3 导入镜像

#导入为镜像
cat centos-7-x86_64-minimal.tar.gz | docker import - centos:minimal
#查看当前所有镜像
docker images

命令示例:

docker images |grep minimal
cat centos-7-x86_64-minimal.tar.gz | docker import - centos:minimal
docker images |grep minimal

输出结果:

[root@MineGi ~]# docker images |grep minimal
[root@MineGi ~]# cat centos-7-x86_64-minimal.tar.gz | docker import - centos:minimal
sha256:58b814914e6ead5f301d0347105ed0653106a28e6b046578e82100d8e3442ed3
[root@MineGi ~]# docker images |grep minimal
centos       minimal     58b814914e6e   5 seconds ago   435MB
[root@MineGi ~]# 

2.4 运行容器

#创建新容器并运行,可使用刚导入的centos镜像
docker run -itd --name centos centos:minimal /bin/bash
#也可进入并使用该容器
docker exec -it centos1 /bin/bash

命令示例:

docker run -it centos:minimal /bin/bash
ls
cat /etc/redhat-release
uname -r
exit 
docker rm -f $(docker ps -aq) &>/dev/null
docker ps -a

输出结果:

[root@MineGi ~]# docker run -it centos:minimal /bin/bash
[root@e145e427967a /]# ls
bin   dev  fastboot  lib    lost+found  mnt  proc  run   srv  tmp  var
boot  etc  home      lib64  media       opt  root  sbin  sys  usr
[root@e145e427967a /]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core) 
[root@e145e427967a /]# uname -r
3.10.0-1127.el7.x86_64
[root@e145e427967a /]# exit
[root@MineGi ~]# docker rm -f $(docker ps -aq) &>/dev/null
[root@MineGi ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@MineGi ~]# 

3、基于Dockerfile创建

3.1 联合文件系统(UnionFS)

  • UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下
  • Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
  • 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
  • 下载镜像的时候看到的一层层的就是联合文件系统

联合文件系统的主要优点包括:

  1. 节省空间:由于联合文件系统的特性,相同的文件只需在底层文件系统存储一次,因此可以节省存储空间
  2. 快速构建和部署:通过将不同层的文件系统组合在一起,可以快速构建和部署容器镜像
  3. 轻量级:联合文件系统允许容器共享相同的基础镜像层,从而减少了资源消耗

        常见的联合文件系统实现包括 OverlayFS、AUFS、btrfs、Devicemapper等。这些技术在不同的操作系统和容器平台中有不同的支持程度,但它们都提供了类似的功能,使得容器技术能够更高效地利用文件系统资源

3.2 docker镜像的分层(基于AUFS构建)

3.2.1 镜像的分层

        镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker 使用存储驱动管理镜像每层内容及可读写层的容器层

  • Dockerfile 中的每个指令都会创建一个新的镜像层
  • 镜像层将被缓存和复用
  • 当Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应镜像层缓存就会失效
  • 某一层的镜像缓存失效,它之后的镜像层缓存都会失效
  • 镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在 Docker 容器中不可见了

Kernel(内核层)

  • 是操作系统的核心组件,负责管理硬件资源、提供系统服务,并为应用程序提供运行环境。在Docker场景下,提及 Kernel 通常是指 Docker 宿主机的 Kernel,而不是镜像内部的 Kernel

Base Image(基础镜像层)

  • 是构建其他 Docker 镜像的基础。它通常是最底层的镜像,包含一个精简的操作系统环境(如Alpine Linux、Ubuntu、CentOS等)以及必要的系统工具

Image(只读镜像层)

  • 是 Docker 中用于创建容器的模板,它是由一系列分层组成的。每个镜像层代表了对前一层的增量更改,如安装一个软件包、添加文件或修改配置。镜像层是只读的,且每一层都有一个唯一的标识符

Container(容器层)

  • 是基于镜像实例化的、轻量级的、可执行的软件单元。容器包含了运行特定应用所需的所有依赖(代码、运行时、库、环境变量等),并利用Linux内核的隔离机制与其他容器及宿主机隔离。每个容器都从其对应的镜像顶部的读写层(也称为“容器层”或“Overlay层”)开始,在此之上进行运行时的写入操作

Worke(工作节点)

  • 在需要修改文件时创建文件的副本,而不是直接修改原始文件。在容器中,这意味着当容器试图修改镜像中的文件时,文件系统并不直接修改原始文件,而是在需要时将原始文件复制到新的位置,然后对副本进行修改。确保原始镜像层的完整性,同时允许容器在自己的文件系统视图中进行修改,而不会影响其他容器或原始镜像

Merge(合并视图层)

  • 对 Docker 镜像信息进行抽象、组织并展示给用户的逻辑层面;实际上是软件为用户提供的一种逻辑抽象和交互界面,用于展示和操作 Docker 镜像的相关信息。由于它是一个逻辑概念,且通过用户接口隐藏了底层细节,所以被称为“看不见的”
3.2.2 涉及技术

(1)bootfs (boot file system) 内核空间

  • 主要包含bootloader和kernel,bootloader主要是引导加载kernel, Linux刚启 动时会加载bootfs文件系统
  • 在Docker 镜像的最底层是bootfs,这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会把临时创建的bootfs这个文件系统删掉
  • 在linux操作系统中(不同版本的linux发行版本),linux加载bootfs时会将rootfs设置为read-only,系统自检后会将只读改为读写,让我们可以在操作系统中进行操作

(2)rootfs (root file system) 内核空间

  • 在bootfs之上(base images, 例如centos、ubuntu)
  • 包含的就是典型Linux 系统中的/dev, /proc, /bin, /etc 等标准目录和文件
  • rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等

3.3 镜像加载原理

        其实就是当容器启动时,镜像的各个层通过联合文件系统技术被叠加到一起,形成一个单独的文件系统视图

  1. 分层结构:Docker镜像采用分层结构,每一层包含了文件系统的一部分和相关设置。这些层相互叠加,形成完整的镜像
  2. 联合文件系统:Docker使用联合文件系统(UnionFS)技术将这些分层的只读文件系统叠加在一起,形成一个虚拟的文件系统视图
  3. 镜像加载:当容器被创建时,Docker会根据镜像的定义,将这些层加载到内存中,并创建一个可写的容器层,以便容器内的应用程序可以对其进行修改而不影响原始镜像
  4. 写时复制:对于容器内的文件修改,Docker使用写时复制(Copy-on-Write)技术,即只有在需要修改文件时才会复制底层数据,确保原始镜像层的完整性
  5. 一旦镜像的各个层被加载并合并到一起,容器运行时负责启动容器进程,并提供隔离的运行环境,使得应用程序能够在其中独立运行
  • 我们可以理解成一开始内核里什么都没有,操作一个命令下载debian,这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image
  • 接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs
  • 在Docker的体系里把这些rootfs叫做Docker的镜像
  • 但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作
  • 当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs

3.4 为什么Docker里的centos的大小才200M

  • 因为对于精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用宿主机的kernel,自己只需要提供rootfs就可以了
  • 由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs

3.5 认识Dockerfile

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

3.6 Dockerfile结构

  • Dockerfile结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令
  • Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#“号开头的注释

3.7 Docker镜像结构的分层

        镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层

  1. Dockerfile 中的每个指令都会创建一个新的镜像层;
  2. 镜像层将被缓存和复用;
  3. 当Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效;
  4. 某一层的镜像缓存失效,它之后的镜像层缓存都会失效;
  5. 镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在 Docker 容器中不可见了

3.8 Dockerfile操作常用的指令

(1)指定基础镜像
格式:FROM 镜像:标签
#指定新镜像所基于的基础镜像,第一条指令必须为 FROM 指令,每创建一个镜像就需要一条 FROM 指令
 
(2)设置镜像的作者信息
格式:MAINTAINER 名字
#说明新镜像的维护人信息
 
(3)运行命令,类似于在容器中执行命令
格式:RUN 命令
#在所基于的镜像上执行命令,并提交到新的镜像中
 
(4)定义容器启动时执行的默认命令,并且可以被覆盖
格式:ENTRYPOINT ["要运行的程序", "参数 1", "参数 2"]
#设定容器启动时第一个运行的命令及其参数,可以通过使用命令docker run --entrypoint 来覆盖镜像中的ENTRYPOINT指令的内容
 
(5)定义容器启动时执行的默认命令
格式:CMD ["要运行的程序", "参数1", "参数2"] 
#上面的是exec形式,shell格式:CMD  命令 参数1 参数2
#启动容器时默认执行的命令或者脚本,Dockerfile只能有一条CMD命令。如果指定多条命令,只执行最后一条命令
 
注:如果在docker run时指定了命令或者镜像中有ENTRYPOINT,那么CMD就会被覆盖,CMD 可以为 ENTRYPOINT 指令提供默认参数
如:先执行 ENTRYPOINT ["rm"]
    后执行 CMD ["cp" ,"-rf",“*”]
此时,CMD执行的cp命令无效,有效的是ENTRYPOINT执行的rm命令,且CMD为ENTRYPOINT命令提供参数
-rf 和 *,所有最终执行的命令是rm -rf *
 
java -jar xxxxxxx.jar  8090
 
执行命令的优先级:RUN > ENTRYPOINT > CMD,先执行run命令后执行ENTRYPOINT命令最后执行CMD命令
 
(6)暴露容器的端口
格式: EXPOSE 8090
#指定新镜像加载到 Docker 时要开启的端口
 
(7)在镜像中设置环境变量
格式:ENV 环境变量 变量值
#设置一个环境变量的值,会被后面的 RUN 使用
linxu PATH=$PATH:/opt
  ENV PATH=$PATH:/opt
 
(8)将源文件复制到镜像中,源文件要与 Dockerfile 位于相同目录中,或者是一个 URL  
格式:ADD 源文件/目录 目标文件/目录
 
有如下注意事项:
如果源路径是个文件,且目标路径是以 / 结尾, 则docker会把目标路径当作一个目录,会把源文件拷贝到该目录下
如果目标路径不存在,则会自动创建目标路径
/home/data/:此路径表示目录
 
如果源路径是个文件,且目标路径是不以 / 结尾,则docker会把目标路径当作一个文件
如果目标路径不存在,会以目标路径为名创建一个文件,内容同源文件;
如果目标文件是个存在的文件,会用源文件覆盖它,当然只是内容覆盖,文件名还是目标文件名。
如果目标文件实际是个存在的目录,则会源文件拷贝到该目录下。 注意,这种情况下,最好显示的以 / 结尾,以避免混淆。
/home/data/1.txt:此路径表示文件
 
如果源路径是个目录,且目标路径不存在,则docker会自动以目标路径创建一个目录,把源路径目录下的文件拷贝进来。
如果目标路径是个已经存在的目录,则docker会把源路径目录下的文件拷贝到该目录下。
 
如果源文件是个归档文件(压缩文件),则docker会自动帮解压。    
URL下载和解压特性不能一起使用。任何压缩文件通过URL拷贝,都不会自动解压。
 
(9)将文件从主机复制到镜像内部
格式:COPY 源文件/目录 目标文件/目录
#只复制本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile 在相同的目录中
 
(10)在容器中创建一个挂载点
格式:VOLUME [“目录”]   
 
(11)指定运行容器时的用户
格式:USER 用户名/UID
 
(12)设置工作目录,后续命令将在此目录下执行
格式:WORKDIR 路径 /home
#为后续的 RUN、CMD、ENTRYPOINT 指定工作目录
 
(13)指定所生成的镜像作为一个基础镜像时所要运行的命令
ONBUILD <instruction> 
#当在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A镜像)不会产生实质性影响
#但是当编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令
 
ONBUILD rm - rf /*
注:请各位自己在生产中如果用的是别的dockerfile 请自习阅读,否则后果自付
 
(14)健康检查
HEALTHCHECK [options] CMD command_to_run
#使用给定的命令进行健康检查,如果返回状态码为0,则表示容器健康;否则为不健康
HEALTHCHECK none 
#禁用健康检查
 
HEALTHCHECK可以包含以下选项:
--interval=duration:设置间隔多久运行一次健康检查命令,默认为30秒
--timeout=duration:设置健康检查命令运行超时时间,默认为30秒
--retries=n:设置在健康检查失败后重试的次数,默认为3次

在编写 Dockerfile 时,有严格的格式需要遵循:

  • 第一行必须使用 FROM 指令指明所基于的镜像名称
  • 之后使用 MAINTAINER 指令说明维护该镜像的用户信息
  • 然后是镜像操作相关指令,如 RUN 指令。每运行一条指令,都会给基础镜像添加新的一层
  • 最后使用 CMD 指令指定启动容器时要运行的命令操作

二、Dockerfile 镜像实战

1、构建 ssh 镜像

  • 构建SSH镜像的作用在于为用户提供一个具备SSH(Secure Shell)功能的容器环境
  • SSH是一种加密的网络协议,常用于安全地远程登录到计算机系统,并在远程系统上执行命令
# 以CentOS 7为基础镜像(你也可以根据需求选择其他CentOS版本,比如CentOS 8等)
FROM centos:7

#维护镜像的用户信息
MAINTAINER sshd image <mg>  

#安装OpenSSH服务器和客户端工具、net-tools(用于网络配置和诊断)lsof(用于列出打开文件的工具)、telnet(用于远程登录测试)   
RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum install -y openssh* net-tools lsof telnet && \
    sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config && \
    ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key && \
    ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

#复制本地当前目录的公钥到容器中  
ADD id_rsa.pub /root/.ssh/authorized_keys

#Docker容器监听SSH服务的22端口 
EXPOSE 22   

#对于OpenSSH服务器,由于其默认行为已经是前台模式,因此不需要额外指定参数FOREGROUND
#为了确保将输出发送到控制台并以调试模式持续运行,仍需要在启动命令中添加-D参数
CMD ["/usr/sbin/sshd" , "-D"]

#生成镜像名称为sshd-centos,标签为v1
docker build -t sshd-centos:v1 .   
# -t 参数用于指定构建镜像的名称及标签
# . 就是指示Docker在当前目录中查找名为Dockerfile的文件,并以此文件作为构建镜像的基础

命令示例:

mkdir -p /data/dockerfiles/ssh-centos
cd !$
ssh-keygen -t rsa -f /root/.ssh/id_rsa  -P "" -q
cp /root/.ssh/id_rsa.pub ./

cat >Dockerfile <<'eof'
FROM centos:7
MAINTAINER sshd image <mg>  
RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum install -y openssh* net-tools lsof telnet && \
    sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config && \
    ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key && \
    ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ADD id_rsa.pub /root/.ssh/authorized_keys
EXPOSE 22   
CMD ["/usr/sbin/sshd" , "-D"]
eof

ls
docker build -t sshd-centos:v1 .
docker images |grep sshd
docker run -d -p 33:22 sshd-centos:v1
docker ps -a
ssh localhost -p 33
hostname -i
logout
docker rm -f $(docker ps -aq) &>/dev/null

输出结果:

[root@MineGi ~]# mkdir -p /data/dockerfiles/ssh-centos
[root@MineGi ~]# cd !$
cd /data/dockerfiles/ssh-centos
[root@MineGi ssh-centos]# ssh-keygen -t rsa -f /root/.ssh/id_rsa  -P "" -q
[root@MineGi ssh-centos]# cp /root/.ssh/id_rsa.pub ./
[root@MineGi ssh-centos]# cat >Dockerfile <<'eof'
> FROM centos:7
> MAINTAINER sshd image <mg>  
> RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
>     yum install -y openssh* net-tools lsof telnet && \
>     sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config && \
>     ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key && \
>     ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && \
>     ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
> ADD id_rsa.pub /root/.ssh/authorized_keys
> EXPOSE 22   
> CMD ["/usr/sbin/sshd" , "-D"]
> eof
[root@MineGi ssh-centos]# ls
Dockerfile  id_rsa.pub
[root@MineGi ssh-centos]# docker build -t sshd-centos:v1 .
[+] Building 0.1s (8/8) FINISHED                                                           docker:default
 => [internal] load build definition from Dockerfile                                                 0.0s
 => => transferring dockerfile: 557B                                                                 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
 => [internal] load build context                                                                    0.0s
 => => transferring context: 432B                                                                    0.0s
 => CACHED [2/3] RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Ce  0.0s
 => [3/3] ADD id_rsa.pub /root/.ssh/authorized_keys                                                  0.0s
 => exporting to image                                                                               0.0s
 => => exporting layers                                                                              0.0s
 => => writing image sha256:ec605109a541802171d6b4949ac7134f5aa9ce3e1aba1bf542364c6b1fc2e220         0.0s
 => => naming to docker.io/library/sshd-centos:v1                                                    0.0s
[root@MineGi ssh-centos]# docker images |grep sshd
sshd-centos   v1          ec605109a541   11 seconds ago   556MB
[root@MineGi ssh-centos]# docker run -d -p 33:22 sshd-centos:v1
c03843b2b94133e247b2b90af3af7c544220569b460b780bdc70d1fea41b2bd6
[root@MineGi ssh-centos]# docker ps -a
CONTAINER ID   IMAGE            COMMAND               CREATED         STATUS         PORTS                               NAMES
c03843b2b941   sshd-centos:v1   "/usr/sbin/sshd -D"   5 seconds ago   Up 4 seconds   0.0.0.0:33->22/tcp, :::33->22/tcp   goofy_chatelet
[root@MineGi ssh-centos]# ssh localhost -p 33
The authenticity of host '[localhost]:33 ([::1]:33)' can't be established.
RSA key fingerprint is SHA256:+L5+An3amtj2fysb3gtdVxIFzXVbmbHY8jI9vhJrv7w.
RSA key fingerprint is MD5:bc:50:74:62:14:bf:f5:17:02:0b:87:d6:40:90:9d:b3.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:33' (RSA) to the list of known hosts.
[root@c03843b2b941 ~]# hostname -i
172.17.0.2
[root@c03843b2b941 ~]# logout
Connection to localhost closed.
[root@MineGi ssh-centos]# docker rm -f $(docker ps -aq) &>/dev/null
[root@MineGi ssh-centos]#

2、构建 systemctl 镜像

FROM sshd-centos:v1
MAINTAINER systemctl image <mg>
ENV container docker          
#设置一个环境变量container,其值为docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ 
#删除除了systemd-tmpfiles-setup.service的其它所有文件       
rm -f /lib/systemd/system/multi-user.target.wants/*; \
rm -f /etc/systemd/system/*.wants/*; \
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
#CMD ["/usr/sbin/init"]
#基础镜像中的CMD指令会被继承到新镜像中,除非在新的Dockerfile中显式地覆盖它
#基础镜像(sshd:centos)已经定义了CMD指令(CMD ["/usr/sbin/sshd", "-D"])

命令示例:

mkdir -p /data/dockerfiles/systemctl
cd !$

cat >Dockerfile <<'eof'
FROM sshd-centos:v1
MAINTAINER systemctl image <mg>
ENV container docker          
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ 
rm -f /etc/systemd/system/*.wants/*; \
rm -f /lib/systemd/system/multi-user.target.wants/*; \
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
eof

docker build -t systemd:v1 .
docker images |grep systemd

输出结果:

[root@MineGi ssh-centos]# mkdir -p /data/dockerfiles/systemctl
[root@MineGi ssh-centos]# cd !$
cd /data/dockerfiles/systemctl
[root@MineGi systemctl]# cat >Dockerfile <<'eof'
> FROM sshd-centos:v1
> MAINTAINER systemctl image <mg>
> ENV container docker          
> RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ 
> rm -f /etc/systemd/system/*.wants/*; \
> rm -f /lib/systemd/system/multi-user.target.wants/*; \
> rm -f /lib/systemd/system/local-fs.target.wants/*; \
> rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
> rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
> rm -f /lib/systemd/system/basic.target.wants/*;\
> rm -f /lib/systemd/system/anaconda.target.wants/*;
> VOLUME [ "/sys/fs/cgroup" ]
> eof
[root@MineGi systemctl]# docker build -t systemd:v1 .
[+] Building 0.6s (6/6) FINISHED                                                                                         docker:default
 => [internal] load build definition from Dockerfile                                                                               0.0s
 => => transferring dockerfile: 644B                                                                                               0.0s
 => [internal] load metadata for docker.io/library/sshd-centos:v1                                                                  0.0s
 => [internal] load .dockerignore                                                                                                  0.0s
 => => transferring context: 2B                                                                                                    0.0s
 => [1/2] FROM docker.io/library/sshd-centos:v1                                                                                    0.0s
 => [2/2] RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i;  0.4s
 => exporting to image                                                                                                             0.0s
 => => exporting layers                                                                                                            0.0s
 => => writing image sha256:4bd6499116312c00676050f80092f856e4bfd11afe0955b9fd20a8b96310ec56                                       0.0s
 => => naming to docker.io/library/systemd:v1                                                                                      0.0s
[root@MineGi systemctl]# docker images |grep systemd
systemd       v1          4bd649911631   19 seconds ago   556MB
[root@MineGi systemctl]#

#启动容器,并挂载宿主机目录挂载到容器中,和进行初始化
docker run --privileged -d -P -v /sys/fs/cgroup:/sys/fs/cgroup:ro systemd:centos /sbin/init
# --privileged: 使用特权模式,这会赋予容器访问主机上所有设备的权限
# 使container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限
# -P: 将容器内部使用的网络端口映射到主机上的随机端口
# -v /sys/fs/cgroup:/sys/fs/cgroup:ro: 将主机的/sys/fs/cgroup目录挂载到容器的相同路径,并设置为只读(ro表示read-only)
# 这是为了让容器能够访问主机的 cgroup 文件系统,通常用于容器内运行systemd
# /sbin/init: 指定容器启动时要运行的命令,这里是启动systemd的初始化进程
或者:
docker run --privileged -it -P -v /sys/fs/cgroup:/sys/fs/cgroup:ro systemd:centos /sbin/init &

命令示例:

docker run --name test --privileged -d -P -v /sys/fs/cgroup:/sys/fs/cgroup:ro systemd:v1 /sbin/init
docker ps -a
docker exec -it test bash
systemctl status sshd
systemctl start sshd
systemctl is-active sshd
exit
docker rm -f $(docker ps -aq) &>/dev/null
docker ps -a

输出结果:

[root@MineGi systemctl]# docker run --name test --privileged -d -P -v /sys/fs/cgroup:/sys/fs/cgroup:ro systemd:v1 /sbin/init
055f672dc41d3fe1c2f709c040cce0b105fb2fadbb952d0c417ec382317e1979
[root@MineGi systemctl]# docker ps -a
CONTAINER ID   IMAGE        COMMAND        CREATED         STATUS         PORTS                                   NAMES
055f672dc41d   systemd:v1   "/sbin/init"   5 seconds ago   Up 4 seconds   0.0.0.0:1024->22/tcp, :::1024->22/tcp   test
[root@MineGi systemctl]# docker exec -it test bash
[root@055f672dc41d /]# systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:sshd(8)
           man:sshd_config(5)
[root@055f672dc41d /]# systemctl start sshd
[root@055f672dc41d /]# systemctl is-active sshd
active
[root@055f672dc41d /]# exit
exit
[root@MineGi systemctl]# docker rm -f $(docker ps -aq) &>/dev/null
[root@MineGi systemctl]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@MineGi systemctl]# 

3、构建 apache 镜像

vim Dockerfile
 
FROM centos:7                           # 基于的基础镜像centos:7
MAINTAINER apache image <mg>            # 维护镜像的用户信息
RUN yum -y update
RUN yum install -y httpd                # 基于基础镜像安装apache
EXPOSE 80                               # Docker服务器开启80端口
ADD index.html /var/www/html/index.html # 复制本地源文件至正在构建的镜像内部
#方法一:将启动容器时运行apache服务的执行脚本复制到镜像中
ADD run.sh /run.sh               
RUN chmod 755 /run.sh                    # 给镜像中的apache.sh脚本添加权限
CMD ["/run.sh"]                          # 启动容器时执行脚本
 
#方法二:使用ENTRYPOINT和CMD命令来设置启动容器时运行apache服务
ENTRYPOINT ["/usr/sbin/apachect1"]      # 启动容器时运行apache服务
CMD ["-D","FOREGROUND"]                
# "-D" 参数用于指定一个调试标志或定义服务器的特定行为,FOREGROUND以前台模式运行,进程结束时终止
# CMD优先级低于ENTRYPOINT,为ENTRYPOINT提供命令参数,且
 
#方法三:使用CMD命令来设置启动容器时运行apache服务
CMD [ "/usr/sbin/apachectl","-D", "FOREGROUND"]
或者运行容器时覆盖默认参数:
docker run my_apache_container -k start

#使用方法一时必须得创建,使用其他方法可不创建
vim run.sh
#!/bin/bash
rm -rf /run/httpd/*                # 清理httpd的缓存
/usr/sbin/apachectl -D FOREGROUND  # 指定为前台运行

命令示例:

mkdir -p /data/dockerfiles/apache-centos
cd !$

cat >Dockerfile <<'eof'
FROM centos:7
MAINTAINER apache image <mg>
RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum install -y httpd &&\
    yum clean all
EXPOSE 80
ADD index.html /var/www/html
ADD run.sh /run.sh               
RUN chmod 755 /run.sh               
CMD ["/run.sh"]
eof

cat >run.sh <<'eof'
#!/bin/bash
rm -rf /run/httpd/*  
/usr/sbin/apachectl -D FOREGROUND
eof

echo "this is apache web" >index.html
docker build -t httpd-centos:v1 .
docker images |grep httpd-centos
docker run -d -p 999:80 httpd-centos:v1
docker ps -a 
hostname -I
curl 10.4.7.11:999
docker rm -f $(docker ps -aq) &>/dev/null
docker ps -a

输出结果:

[root@MineGi systemctl]# mkdir -p /data/dockerfiles/apache-centos
[root@MineGi systemctl]# cd !$
cd /data/dockerfiles/apache-centos
[root@MineGi apache-centos]# cat >Dockerfile <<'eof'
> FROM centos:7
> MAINTAINER apache image <mg>
> RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
>     yum install -y httpd &&\
>     yum clean all
> EXPOSE 80
> ADD index.html /var/www/html
> ADD run.sh /run.sh               
> RUN chmod 755 /run.sh               
> CMD ["/run.sh"]
> eof
[root@MineGi apache-centos]# cat >run.sh <<'eof'
> #!/bin/bash
> rm -rf /run/httpd/*  
> /usr/sbin/apachectl -D FOREGROUND
> eof
[root@MineGi apache-centos]# echo "this is apache web" >index.html
[root@MineGi apache-centos]# docker build -t httpd-centos:v1 .
[+] Building 0.9s (10/10) FINISHED                                                                                       docker:default
 => [internal] load build definition from Dockerfile                                                                               0.0s
 => => transferring dockerfile: 354B                                                                                               0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                        0.0s
 => [internal] load .dockerignore                                                                                                  0.0s
 => => transferring context: 2B                                                                                                    0.0s
 => [1/5] FROM docker.io/library/centos:7                                                                                          0.0s
 => [internal] load build context                                                                                                  0.0s
 => => transferring context: 159B                                                                                                  0.0s
 => CACHED [2/5] RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo &&     yum install  0.0s
 => [3/5] ADD index.html /var/www/html                                                                                             0.0s
 => [4/5] ADD run.sh /run.sh                                                                                                       0.0s
 => [5/5] RUN chmod 755 /run.sh                                                                                                    0.3s
 => exporting to image                                                                                                             0.4s
 => => exporting layers                                                                                                            0.4s
 => => writing image sha256:66dce47c4bebffa62fc7e1f991a6d6a231059686a6fa4ba3f5b900807a6b9c64                                       0.0s
 => => naming to docker.io/library/httpd-centos:v1                                                                                 0.0s
[root@MineGi apache-centos]# docker images |grep httpd-centos
httpd-centos   v1          66dce47c4beb   13 seconds ago   261MB
[root@MineGi apache-centos]# docker run -d -p 999:80 httpd-centos:v1
3b1721f89c4d70d16d86fbdadd035527a657f8453ea5aa5b7153af1c8f1e7246
[root@MineGi apache-centos]# docker ps -a
CONTAINER ID   IMAGE             COMMAND     CREATED         STATUS         PORTS                                 NAMES
3b1721f89c4d   httpd-centos:v1   "/run.sh"   5 seconds ago   Up 4 seconds   0.0.0.0:999->80/tcp, :::999->80/tcp   optimistic_nobel
[root@MineGi apache-centos]# hostname -I
10.4.7.11 172.17.0.1 
[root@MineGi apache-centos]# curl 10.4.7.11:999
this is apache web
[root@MineGi apache-centos]# docker rm -f $(docker ps -aq) &>/dev/null
[root@MineGi apache-centos]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@MineGi apache-centos]# 

4、构建 nginx 镜像

下载地址:Index of /download/

【Nginx:百度网盘

vim Dockerfile
 
FROM centos:7
MAINTAINER nginx image <mg>
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
ADD nginx-1.22.0.tar.gz /opt/
WORKDIR /opt/nginx-1.22.0
RUN ./configure \
--prefix=/usr/local/nginx \     # 指定了NGINX安装目录
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make -j 2 && make install # 启用了NGINX的stub status模块
ENV PATH /usr/local/nginx/sbin:$PATH
EXPOSE 80                       # 指定了NGINX监听的HTTP和HTTPS端口
EXPOSE 443
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
# daemon off;指示NGINX在前台运行,而不是作为守护进程
ADD run.sh /run.sh         
RUN chmod 755 /run.sh   
CMD ["/run.sh"]               # 容器启动时要执行的脚本
#CMD ["/usr/local/sbin/nginx", "-g", "daemon off;"]
# -g 参数是用来设置NGINX的全局配置项的

命令示例:

mkdir -p /data/dockerfiles/nginx-centos
cd !$
wget https://nginx.org/download/nginx-1.22.0.tar.gz

cat >Dockerfile <<'eof'
FROM centos:7
MAINTAINER nginx image <mg>
ADD nginx-1.22.0.tar.gz /opt/
ADD run.sh /run.sh 
RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum -y install pcre-devel zlib-devel gcc gcc-c++ make && \
    useradd -M -s /sbin/nologin nginx && \
    yum clean all && \
    chmod 755 /run.sh   
WORKDIR /opt/nginx-1.22.0
RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \
    --with-http_stub_status_module && make -j 2 && make install
ENV PATH /usr/local/nginx/sbin:$PATH
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
CMD ["/run.sh"]
eof

cat >run.sh <<'eof'
#!/bin/bash
/usr/local/nginx/sbin/nginx
eof#!/bin/bash

ll
docker build -t nginx-centos:v1 .
docker images |grep nginx-centos
docker run -d -p 80:80 nginx-centos:v1
docker ps -a 
curl -I 10.4.7.11
docker rm -f $(docker ps -aq) &>/dev/null
docker ps -a

输出结果:

[root@MineGi apache-centos]# mkdir -p /data/dockerfiles/nginx-centos
[root@MineGi apache-centos]# cd !$
cd /data/dockerfiles/nginx-centos
[root@MineGi nginx-centos]# wget -q https://nginx.org/download/nginx-1.22.0.tar.gz
[root@MineGi nginx-centos]# cat >Dockerfile <<'eof'
> FROM centos:7
> MAINTAINER nginx image <mg>
> ADD nginx-1.22.0.tar.gz /opt/
> ADD run.sh /run.sh 
> RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
>     yum -y install pcre-devel zlib-devel gcc gcc-c++ make && \
>     useradd -M -s /sbin/nologin nginx && \
>     yum clean all && \
>     chmod 755 /run.sh   
> WORKDIR /opt/nginx-1.22.0
> RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \
>     --with-http_stub_status_module && make -j 2 && make install
> ENV PATH /usr/local/nginx/sbin:$PATH
> EXPOSE 80
> EXPOSE 443
> RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
> CMD ["/run.sh"]
> eof
[root@MineGi nginx-centos]# cat >run.sh <<'eof'
> #!/bin/bash
> /usr/local/nginx/sbin/nginx
> eof
[root@MineGi nginx-centos]# ll
总用量 1060
-rw-r--r-- 1 root root     639 12月 19 13:53 Dockerfile
-rw-r--r-- 1 root root 1073322 5月  24 2022 nginx-1.22.0.tar.gz
-rw-r--r-- 1 root root      40 12月 19 13:53 run.sh
[root@MineGi nginx-centos]# docker build -t nginx-centos:v1 .
[+] Building 90.6s (12/12) FINISHED                                                                                      docker:default
 => [internal] load build definition from Dockerfile                                                                               0.0s
 => => transferring dockerfile: 678B                                                                                               0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                        0.0s
 => [internal] load .dockerignore                                                                                                  0.0s
 => => transferring context: 2B                                                                                                    0.0s
 => [1/7] FROM docker.io/library/centos:7                                                                                          0.0s
 => [internal] load build context                                                                                                  0.0s
 => => transferring context: 117B                                                                                                  0.0s
 => CACHED [2/7] ADD nginx-1.22.0.tar.gz /opt/                                                                                     0.0s
 => [3/7] ADD run.sh /run.sh                                                                                                       0.0s
 => [4/7] RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo &&     yum -y install pc  60.7s
 => [5/7] WORKDIR /opt/nginx-1.22.0                                                                                                0.0s 
 => [6/7] RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx     --with-http_stub_status_module && make -j 2 &  28.5s 
 => [7/7] RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf                                                               0.3s 
 => exporting to image                                                                                                             0.9s 
 => => exporting layers                                                                                                            0.9s 
 => => writing image sha256:e568fd65475f9354be78bf8b27a5c24c5f8d830475bf9957f6c8b6efad019cc5                                       0.0s 
 => => naming to docker.io/library/nginx-centos:v1                                                                                 0.0s 
[root@MineGi nginx-centos]# docker images |grep nginx-centos                                                                            
nginx-centos   v1          e568fd65475f   3 minutes ago       349MB
[root@MineGi nginx-centos]# docker run -d -p 80:80 nginx-centos:v1
5e0d65d6f4ef0036ff39ee4eaccd6126606879595ba9a2da3834ef181746b385
[root@MineGi nginx-centos]# docker ps -a 
CONTAINER ID   IMAGE             COMMAND     CREATED         STATUS         PORTS                                        NAMES
5e0d65d6f4ef   nginx-centos:v1   "/run.sh"   6 seconds ago   Up 5 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp   optimistic_herschel
[root@MineGi nginx-centos]# curl -I 10.4.7.11
HTTP/1.1 200 OK
Server: nginx/1.22.0
Date: Thu, 19 Dec 2024 06:00:36 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 19 Dec 2024 05:55:34 GMT
Connection: keep-alive
ETag: "6763b556-267"
Accept-Ranges: bytes

[root@MineGi nginx-centos]# docker rm -f $(docker ps -aq) &>/dev/null
[root@MineGi nginx-centos]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@MineGi nginx-centos]# 

5、构建 tomcat 镜像

【JDK:百度网盘

【Tomcat:百度网盘

jdk6:https://www.oracle.com/cn/java/technologies/javase-java-archive-javase6-downloads.html
jdk8:https://www.oracle.com/cn/java/technologies/javase/javase8u211-later-archive-downloads.html
Tomcat:https://archive.apache.org/dist/tomcat/

vim Dockerfile
 
FROM centos:7
MAINTAINER tomcat image <dh>
ADD jdk-8u291-linux-x64.tar.gz /usr/local/  
# 将jdk……tar.gz文件解压到/usr/local/目录下
WORKDIR /usr/local/                         
# 为后续命令指定工作目录/usr/local/
RUN mv jdk1.8.0_291 /usr/local/java         
# 解压后的JDK目录重命名为java并移动到/usr/local/目录下
ENV JAVA_HOME /usr/local/java               
# 设置环境变量JAVA_HOME为/usr/local/java
ENV JRE_HOME ${JAVA_HOME}/jre               
# 设置环境变量JRE_HOME为${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib 
# 置环境变量CLASSPATH,包含当前目录、Java库和JRE库 
ENV PATH $JAVA_HOME/bin:$PATH               
# 将JAVA_HOME/bin加入到PATH环境变量中
ADD apache-tomcat-8.5.16.tar.gz /usr/local/
WORKDIR /usr/local/                         
# 设置工作目录为/usr/local/
RUN mv apache-tomcat-8.5.16 /usr/local/tomcat 
# 将解压后的Tomcat目录重命名为tomcat并移动到/usr/local/目录下
EXPOSE 8080                                 # 暴露容器的 8080 端口
#CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
# 设置容器启动时执行的命令为 /usr/local/tomcat/bin/catalina.sh run,以启动 Tomcat 服务
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]
CMD ["/usr/local/tomcat/bin/startup.sh","start"]
# 设置容器启动时默认执行的命令为 /usr/local/tomcat/bin/startup.sh start,以启动Tomcat服务
# 使用更推荐的 LABEL 指令设置维护者信息
LABEL maintainer="tomcat image <mg>"

# 先设置工作目录为 /usr/local,后续操作都在此目录下进行相关解压和移动操作,减少 WORKDIR 指令切换次数
WORKDIR /usr/local

# 考虑先将 JDK 压缩包下载到宿主机,再使用 COPY 指令复制进容器,提高稳定性和可控性
# 这里假设宿主机当前目录下有 jdk-8u291-linux-x64.tar.gz 文件
COPY jdk-8u291-linux-x64.tar.gz.
RUN tar -zxvf jdk-8u291-linux-x64.tar.gz && \
    mv jdk1.8.0_291 java && \
    # 设置 Java 环境变量
    export JAVA_HOME=/usr/local/java && \
    export JRE_HOME=${JAVA_HOME}/jre && \
    export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib && \
    export PATH=$JAVA_HOME/bin:$PATH

# 同样先将 Tomcat 压缩包复制进容器,再解压和移动
COPY apache-tomcat-8.5.16.tar.gz.
RUN tar -zxvf apache-tomcat-8.5.16.tar.gz && \
    mv apache-tomcat-8.5.16 tomcat

# 暴露 8080 端口
EXPOSE 8080

# 只保留 ENTRYPOINT,因为它定义了容器启动时执行的命令,CMD 在此处冗余且可能导致一些启动行为的混淆
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh", "run"]

命令示例:

mkdir -p /data/dockerfiles/tomcat-centos
cd !$
#wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.16/bin/apache-tomcat-8.5.16.tar.gz
cat >Dockerfile <<'eof'
FROM centos:7
LABEL maintainer="tomcat image <mg>"
WORKDIR /usr/local
ADD jdk-8u291-linux-x64.tar.gz ./ 
ADD apache-tomcat-8.5.16.tar.gz ./
RUN mv jdk1.8.0_291 java && \
    mv apache-tomcat-8.5.16 tomcat
ENV JAVA_HOME=/usr/local/java
ENV JRE_HOME=${JAVA_HOME}/jre
ENV CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH=$JAVA_HOME/bin:$PATH
EXPOSE 8080
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]
eof

ll
docker build -t tomcat-centos:v1 .
docker images |grep tomcat-centos
docker run -d --name tomcat1 -p 888:8080 tomcat-centos:v1 
docker ps -a
curl -I 10.4.7.11:888
docker rm -f $(docker ps -aq) &>/dev/null
docker ps -a

输出结果:

[root@MineGi nginx-centos]# mkdir -p /data/dockerfiles/tomcat-centos
[root@MineGi nginx-centos]# cd !$
cd /data/dockerfiles/tomcat-centos
[root@MineGi tomcat-centos]# rz -E
rz waiting to receive.
[root@MineGi tomcat-centos]# rz -E
rz waiting to receive.
[root@MineGi tomcat-centos]# cat >Dockerfile <<'eof'
> FROM centos:7
> LABEL maintainer="tomcat image <mg>"
> WORKDIR /usr/local
> ADD jdk-8u291-linux-x64.tar.gz ./ 
> ADD apache-tomcat-8.5.16.tar.gz ./
> RUN mv jdk1.8.0_291 java && \
>     mv apache-tomcat-8.5.16 tomcat
> ENV JAVA_HOME=/usr/local/java
> ENV JRE_HOME=${JAVA_HOME}/jre
> ENV CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
> ENV PATH=$JAVA_HOME/bin:$PATH
> EXPOSE 8080
> ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]
> eof
[root@MineGi tomcat-centos]# ll
总用量 150744
-rw-r--r-- 1 root root   9417469 10月 14 18:45 apache-tomcat-8.5.16.tar.gz
-rw-r--r-- 1 root root       411 12月 19 14:36 Dockerfile
-rw-r--r-- 1 root root 144935989 10月 30 11:01 jdk-8u291-linux-x64.tar.gz
[root@MineGi tomcat-centos]# docker build -t tomcat-centos:v1 .
[+] Building 0.1s (10/10) FINISHED                                                                                       docker:default
 => [internal] load build definition from Dockerfile                                                                               0.0s
 => => transferring dockerfile: 450B                                                                                               0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                        0.0s
 => [internal] load .dockerignore                                                                                                  0.0s
 => => transferring context: 2B                                                                                                    0.0s
 => [1/5] FROM docker.io/library/centos:7                                                                                          0.0s
 => [internal] load build context                                                                                                  0.0s
 => => transferring context: 99B                                                                                                   0.0s
 => CACHED [2/5] WORKDIR /usr/local                                                                                                0.0s
 => CACHED [3/5] ADD jdk-8u291-linux-x64.tar.gz ./                                                                                 0.0s
 => CACHED [4/5] ADD apache-tomcat-8.5.16.tar.gz ./                                                                                0.0s
 => CACHED [5/5] RUN mv jdk1.8.0_291 java &&     mv apache-tomcat-8.5.16 tomcat                                                    0.0s
 => exporting to image                                                                                                             0.0s
 => => exporting layers                                                                                                            0.0s
 => => writing image sha256:dba02f27d5cf29eda07cff8e1257117f94c927103e9f7f0a84ca8b991c04f8ff                                       0.0s
 => => naming to docker.io/library/tomcat-centos:v1                                                                                0.0s
[root@MineGi tomcat-centos]# docker images |grep tomcat-centos
tomcat-centos   v1          dba02f27d5cf   10 minutes ago      950MB
[root@MineGi tomcat-centos]# docker run -d --name tomcat1 -p 888:8080 tomcat-centos:v1 
b7a5543ca1b9e42b5cc41d576623e738a5cf83e6b2658babcfe19c9a9254c8ad
[root@MineGi tomcat-centos]# docker ps -a
CONTAINER ID   IMAGE              COMMAND                   CREATED         STATUS         PORTS                                     NAMES
b7a5543ca1b9   tomcat-centos:v1   "/usr/local/tomcat/b…"   6 seconds ago   Up 4 seconds   0.0.0.0:888->8080/tcp, :::888->8080/tcp   tomcat1
[root@MineGi tomcat-centos]# curl -I 10.4.7.11:888
HTTP/1.1 200 
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 19 Dec 2024 06:37:32 GMT

[root@MineGi tomcat-centos]# docker rm -f $(docker ps -aq) &>/dev/null
[root@MineGi tomcat-centos]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@MineGi tomcat-centos]#

6、构建 mysql 镜像

注意事项:构建MySQL镜像,将虚拟机的内存临时调到大些,防止报错或卡顿

https://mirrors.aliyun.com/mysql/

【MySQL:百度网盘

命令示例:

mkdir -p /data/dockerfiles/mysql-centos
cd !$
wget /data/tpges https://mirrors.aliyun.com/mysql/MySQL-5.7/mysql-boost-5.7.36.tar.gz
ll

输出结果:

[root@MineGi tomcat-centos]# mkdir -p /data/dockerfiles/mysql-centos
[root@MineGi tomcat-centos]# cd !$
cd /data/dockerfiles/mysql-centos
[root@MineGi mysql-centos]# wget -q /data/tpges https://mirrors.aliyun.com/mysql/MySQL-5.7/mysql-boost-5.7.36.tar.gz
[root@MineGi mysql-centos]# ll
总用量 51728
-rw-r--r-- 1 root root 52968383 9月   7 2021 mysql-boost-5.7.36.tar.gz
[root@MineGi mysql-centos]#

命令示例:

cat >Dockerfile <<'eof'
FROM centos:7
MAINTAINER mysql image <mg>
RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum -y install gcc gcc-c++ cmake make bison bison-devel ncurses ncurses-devel libtirpc \
    libtirpc-devel libxml2-devel openssl-devel libevent-devel libaio-devel libcurl-devel libarchive-devel \
    boost-devel zlib-devel gnutls-develncurses && useradd -M -s /sbin/nologin mysql && yum clean all
ADD mysql-boost-5.7.36.tar.gz /usr/local/src/ 
ADD my.cnf /etc/my.cnf   
WORKDIR /usr/local/src/mysql-5.7.36/
RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
    -DSYSCONFDIR=/etc -DSYSTEMD_PID_DIR=/usr/local/mysql -DDEFAULT_CHARSET=utf8  \
    -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DWITH_INNOBASE_STORAGE_ENGINE=1 \
    -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
    -DMYSQL_DATADIR=/usr/local/mysql/data -DWITH_BOOST=boost \
    -DWITH_SYSTEMD=1 && make -j 2 && make install  && \      
    chown -R mysql:mysql /usr/local/mysql/ && \
    chown mysql:mysql /etc/my.cnf
EXPOSE 3306                      
WORKDIR /usr/local/mysql/bin/    
RUN ./mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data && \
    cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/  && \
    systemctl enable mysqld
ENV PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH 
VOLUME [ "/usr/local/mysql" ]    
CMD ["/usr/sbin/init"]
eof

输出结果:

[root@MineGi mysql-centos]# cat >Dockerfile <<'eof'
> FROM centos:7
> MAINTAINER mysql image <mg>
> RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
>     yum -y install gcc gcc-c++ cmake make bison bison-devel ncurses ncurses-devel libtirpc \
>     libtirpc-devel libxml2-devel openssl-devel libevent-devel libaio-devel libcurl-devel libarchive-devel \
>     boost-devel zlib-devel gnutls-develncurses && useradd -M -s /sbin/nologin mysql && yum clean all
> ADD mysql-boost-5.7.36.tar.gz /usr/local/src/ 
> ADD my.cnf /etc/my.cnf   
> WORKDIR /usr/local/src/mysql-5.7.36/
> RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
>     -DSYSCONFDIR=/etc -DSYSTEMD_PID_DIR=/usr/local/mysql -DDEFAULT_CHARSET=utf8  \
>     -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DWITH_INNOBASE_STORAGE_ENGINE=1 \
>     -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
>     -DMYSQL_DATADIR=/usr/local/mysql/data -DWITH_BOOST=boost \
>     -DWITH_SYSTEMD=1 && make -j 2 && make install  && \      
>     chown -R mysql:mysql /usr/local/mysql/ && \
>     chown mysql:mysql /etc/my.cnf
> EXPOSE 3306                      
> WORKDIR /usr/local/mysql/bin/    
> RUN ./mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data && \
>     cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/  && \
>     systemctl enable mysqld
> ENV PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH 
> VOLUME [ "/usr/local/mysql" ]    
> CMD ["/usr/sbin/init"]
> eof
[root@MineGi mysql-centos]#

如果使用脚本来设置启动容器时运行mysqld服务,就需要创建run.sh脚本
vim run.sh
 
#!/bin/bash
/usr/local/mysql/bin/mysqld    
systemctl enable mysqld

命令示例:

cat >my.cnf <<'eof'
[client]
port = 3306
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock
[mysql]
port = 3306
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock
[mysqld]
user = mysql
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port = 3306
character_set_server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket = /usr/local/mysql/mysql.sock
server-id = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
eof

输出结果:

[root@MineGi mysql-centos]# cat >my.cnf <<'eof'
> [client]
> port = 3306
> default-character-set=utf8
> socket = /usr/local/mysql/mysql.sock
> [mysql]
> port = 3306
> default-character-set=utf8
> socket = /usr/local/mysql/mysql.sock
> [mysqld]
> user = mysql
> basedir = /usr/local/mysql
> datadir = /usr/local/mysql/data
> port = 3306
> character_set_server=utf8
> pid-file = /usr/local/mysql/mysqld.pid
> socket = /usr/local/mysql/mysql.sock
> server-id = 1
> sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
> eof
[root@MineGi mysql-centos]# 

命令示例:

docker build -t mysql-centos:v1 .
docker images |grep mysql-centos
docker run --name mysql_server -d -P --privileged mysql-centos:v1 /usr/sbin/init
docker ps -a

输出结果:

[root@MineGi mysql-centos]# docker build -t mysql-centos:v1 .
[+] Building 2470.2s (13/13) FINISHED                                                                                    docker:default
 => [internal] load build definition from Dockerfile                                                                               0.0s
 => => transferring dockerfile: 1.60kB                                                                                             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/8] FROM docker.io/library/centos:7                                                                                   0.0s
 => [internal] load build context                                                                                                  0.0s
 => => transferring context: 75B                                                                                                   0.0s
 => [2/8] RUN curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo &&     yum -y install g  131.0s
 => [3/8] ADD mysql-boost-5.7.36.tar.gz /usr/local/src/                                                                            8.9s 
 => [4/8] ADD my.cnf /etc/my.cnf                                                                                                   0.0s 
 => [5/8] WORKDIR /usr/local/src/mysql-5.7.36/                                                                                     0.0s 
 => [6/8] RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock     -DSYSCONFDIR=/et  2277.4s 
 => [7/8] WORKDIR /usr/local/mysql/bin/                                                                                            0.3s 
 => [8/8] RUN ./mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data &&     cp /u  7.3s 
 => exporting to image                                                                                                            45.1s 
 => => exporting layers                                                                                                           45.1s 
 => => writing image sha256:1f91ce33f68eaade1f2a7283420f189838e69bd8233ce23e617e425935fa131a                                       0.0s 
 => => naming to docker.io/library/mysql-centos:v1                                                                                 0.0s 
[root@MineGi mysql-centos]# docker images |grep mysql-centos                                                                            
mysql-centos         v1          1f91ce33f68e   11 minutes ago      8.07GB
[root@MineGi mysql-centos]# docker run --name mysql_server -d -P --privileged mysql-centos:v1 /usr/sbin/init
700dad29b95d803e5ccf0836b5a996306605094dd2481d7121f28acb9331d049
[root@MineGi mysql-centos]# docker ps -a
CONTAINER ID   IMAGE             COMMAND            CREATED          STATUS         PORTS                                       NAMES
700dad29b95d   mysql-centos:v1   "/usr/sbin/init"   24 seconds ago   Up 8 seconds   0.0.0.0:1024->3306/tcp, :::1024->3306/tcp   mysql_server
[root@MineGi mysql-centos]# 

docker exec -it mysql_server /bin/bash
# 可以选择修改密码:
# 给root账号设置密码
# mysqladmin -u root -p password "123456"  直接回车
# 登录 mysql -u root -p123456

mysql> mysql -u root -p  # 无初始密码直接回车
mysql> grant all privileges on *.* to 'root'@'%' identified by 'abc123';
# 授予了一个名为'root'的用户在任何主机上('%'表示所有主机)对所有数据库的所有表拥有全部权限,并设置了密码为'abc123'
mysql> grant all privileges on *.* to 'root'@'localhost' identified by 'abc123';
# 仅授权了在本地主机(即指定为 'localhost')上的'root'用户
mysql> flush privileges;
# 刷新MySQL的权限,使新授权的权限立即生效

命令示例:

docker exec -it mysql_server /bin/bash
mysql -u root -p
grant all privileges on *.* to 'root'@'%' identified by 'abc123';
grant all privileges on *.* to 'root'@'localhost' identified by 'abc123';
flush privileges;
exit
exit
docker rm -f $(docker ps -aq) &>/dev/null
docker ps -a 

输出结果:

[root@MineGi mysql-centos]# docker exec -it mysql_server /bin/bash
[root@700dad29b95d bin]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 Source distribution

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> grant all privileges on *.* to 'root'@'%' identified by 'abc123';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> grant all privileges on *.* to 'root'@'localhost' identified by 'abc123';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> exit
Bye
[root@700dad29b95d bin]# exit
exit
[root@MineGi mysql-centos]# docker rm -f $(docker ps -aq) &>/dev/null
[root@MineGi mysql-centos]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@MineGi mysql-centos]# 

三、总结

1、创建镜像

1.1 基于现有镜像创建

docker run 创建并启动容器;再通过 docker exec/cp 等容器操作指令修改容器内容;然后 docker commit 提交成新的镜像

1.2 基于本地模版创建

从网上下载现有的镜像模版 ,或使用 docker export 导出本地容器的快照模版,然后 docker import - 将快照模版导入本地镜像。

1.3 基于 Dockerfile 创建镜像

Dockerfile 构建镜像的步骤:

  • 先用 FROM 指令指定基础镜像
  • 再用 MAINTAINER 指定维护人信息
  • 然后再用 RUN、EXPOSE、ADD、ENV、USER、WORKDIR 等指令编写镜像的过程
  • 最后使用 CMD 或 ENTPYONT 指令指定启动容器时执行的命令

ENTPYONT与CMD 区别:

  • 容器启动时执行命令的优先级
  • docker run --entypont=命令 镜像 选项 参数 ---> ENTPYONT ["命令","选顶","参数”] ---> docker run 镜像 命令 选项 参数 ---> CMD ["命令","选项","参数"]
  • 如果在同一个 dockerfile 文件中同时存在 ENTPYONT 和 CMD 时,ENTPYONT 会覆盖 CMD 运行命令,CMD 为提供选项和参数

ADD 和 COPY 区别:

  • 都可以复制本地文件/目录到镜像中
  • ADD 可以通过 URL 路径下的文件并复制到镜像,还可以把本地的 tar 压缩包进行解压后复制到镜像
  • COPY 支持配合 --from 选项实现多个阶段构建

如何缩小 Dockerfile 构建的镜像体积大小?

  • 尽可能减少指令的数量,比如把RUN的linux命令进行合并
  • 尽可能得使用最简洁的基础镜像
  • 使用多阶段(多级)构建
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MineGi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值