1、什么是Docker
Docker 是一个开源的平台,旨在自动化应用程序的部署、扩展和管理。
它通过提供操作系统级别的虚拟化(也称为容器化)来实现这些目标。
容器是一种轻量级、独立、可移植的软件单元,它包含了应用程序及其所有的依赖项,从而确保应用程序在任何环境中都能一致地运行。
通过使用 Docker,开发者和运维人员可以更轻松地管理和部署应用程序,简化了开发流程,提高了软件交付的速度和可靠性。
2、Docker相关概念
2.1、 容器(Container)
- 容器是一个运行在操作系统级别的虚拟化环境。每个容器都是一个独立的运行实例,包含了应用程序和它所需要的所有依赖项。
- 容器之间相互隔离,但共享操作系统内核,这使得它们比虚拟机更轻量级。
2.2、 镜像(Image)
- 镜像是一个只读的模板,用于创建 Docker 容器。它包含了应用程序及其所有的依赖项。
- 镜像可以从公共或私有的 Docker 镜像仓库(例如 Docker Hub)中下载,也可以由用户自定义创建。
2.3、 Dockerfile
- Dockerfile 是一个文本文件,包含了一系列指令,用于定义如何构建一个 Docker 镜像。
- 用户可以通过编写 Dockerfile 来定制自己的应用程序镜像。
2.4、 Docker 引擎(Docker Engine)
- Docker 引擎是一个轻量级的容器化引擎,负责创建和管理 Docker 容器。
- 它包含了 Docker 守护进程(Daemon)、REST API 和命令行界面(CLI)。
2.5、 Docker Compose
- Docker Compose 是一个工具,用于定义和运行多容器的 Docker 应用程序。
- 用户可以通过一个 YAML 文件来配置应用程序的服务、网络和卷等资源。
3、Docker 的优势
- 可移植性:由于容器包含了应用程序运行所需的所有依赖项,Docker 容器可以在任何支持 Docker 的环境中一致地运行,无论是开发、测试还是生产环境。
- 轻量级:Docker 容器共享主机操作系统的内核,启动速度快,占用资源少,比传统的虚拟机更加高效。
- 版本控制和组件重用:Docker 镜像可以版本化,并且可以共享和重用已有的镜像层,提高了开发效率和一致性。
- 隔离性和安全性:每个容器都是独立的,彼此隔离,降低了应用程序之间的相互影响,增强了系统的安全性。
- 扩展和管理:Docker 提供了丰富的工具和平台支持(如 Kubernetes)来帮助用户扩展和管理容器化的应用程序。
4、Docker的架构
Docker由三部分组成:docker命令行、docker主机、docker仓库

docker命令行:用于操作docker对应的各种命令,通过不同的命令让docker主机去执行相关的操作
docker主机:其中运行着docker守护进程,通过docker命令行输入的所有命令最终都被守护进程所接受,然后再进行相关的仓库,比如:拉取镜像、运行镜像、构建镜像、推送镜像等等
docker仓库:存储着基于docker构建的各种镜像(类似于maven的中央仓库)
5、关于容器化介绍
容器是类似轻量级的虚拟机(VM),各个容器共享同意给操作系统内核,每个容器拥有自己独立的文件系统、CPU、内存、进程空间等,不同容器之间相互隔离,互不影响。即使某个容器中的项目发生崩溃也只是当前这个容器出问题,其它容器中的项目依然可以正常运行。

6、Docker的安装
docker官网:https://www.docker.com/
centos安装docker:https://docs.docker.com/engine/install/centos/
如果本地没有搭建Linux环境,可以去云平台购买一台服务器来完成实验。
华为云:https://www.huaweicloud.com/
腾讯云:https://cloud.tencent.com/
字节云:https://www.volcengine.com/
6.1、centos版本
CentOS 7 安装 Docker (推荐阿里云源 + 国内镜像加速)
CentOS 7(64位),采用 Docker 官方推荐方式,通过 阿里云的 Docker CE Yum 源 安装 稳定版 Docker(社区版,Docker CE),并配置 国内镜像加速器,解决拉取镜像慢、网络超时等问题
- 操作系统:CentOS 7(64 位)
- 内核版本:建议 3.10 或更高(CentOS 7 默认满足)
- 权限要求:具有 root 权限 或可使用
sudo - 网络:服务器能访问互联网,尤其是 HTTPS(443 端口)
# 检查内核版本
uname -r
# 3.10.0-957.el7.x86_64
6.2、更换 Yum 源为阿里云源(提升 yum 下载速度和稳定性)
确保后续 yum install(包括 Docker 及其依赖)更快、更稳定,建议先将 CentOS 默认的官方 yum 源替换为 阿里云的 CentOS 7 源。
备份原有 CentOS-Base.repo(可选但建议)
sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
下载阿里云的 CentOS 7 源配置文件
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
该源由阿里云官方提供,国内访问速度快、稳定可靠。
清理并重建 Yum 缓存
sudo yum clean all
sudo yum makecache
让 yum 使用新的阿里云源,后续安装软件会快很多。
6.3、卸载docker
如果之前安装过旧版 Docker(如 docker、docker-engine),建议先卸载,避免冲突。
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
6.4、安装 Docker CE(社区版)的依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
这些是 Docker 安装所需的依赖工具,用于管理 yum 源及存储驱动。
6.5、添加阿里云的 Docker CE Yum 源(推荐)
docker 官方为 CentOS 提供了 Docker CE 的 yum 源,阿里云提供了该源的国内镜像,更加稳定快速。
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
6.6、查看可安装的 Docker CE 版本(推荐操作)
Docker 官方可能推送较新但不兼容 CentOS 7 的版本(如 26.x),我们推荐安装 20.10.x 或 24.x 等稳定且兼容的版本。
# 运行以下命令,查看所有可用版本(按版本排序,最新的在上面)
yum list docker-ce --showduplicates | sort -r
6.7、安装指定版本的 Docker CE(推荐 20.10.9 或 24.0.7)
不要直接运行 yum install docker-ce,否则可能默认安装最新的 26.x,与 CentOS 7 不兼容,
明确指定版本号,推荐安装以下稳定版本之一:
选项 1:安装 Docker 24.0.7(推荐,较新且稳定)
sudo yum install -y docker-ce-24.0.7-1.el7 docker-ce-cli-24.0.7-1.el7 containerd.io
选项 2:安装 Docker 20.10.9(经典稳定版,兼容性好)
sudo yum install -y docker-ce-20.10.9-3.el7 docker-ce-cli-20.10.9-3.el7 containerd.io
以上命令中,同时安装了
docker-ce、docker-ce-cli和containerd.io,这是 Docker 正常运行所必需的组件。
6.8、启动 Docker 并设置开机自启
# 启动 Docker 服务 : 这个只是当前启动,若linux系统关闭了,还需要重
sudo systemctl start docker
# 设置开机自动启动
sudo systemctl enable docker
# 查看 Docker 运行状态
sudo systemctl status docker
如果显示 active (running),说明 Docker 已成功启动。
6.9、验证 Docker 是否安装成功
# 查看 Docker 版本
docker --version
# 运行一个测试容器
sudo docker run hello-world
如果看到如下输出,说明 Docker 安装成功:
Hello from Docker!
6.10、配置镜像加速地址
默认情况下,Docker 会从 Docker Hub(https://registry-1.docker.io) 拉取镜像,但国内访问速度慢,还容易超时。强烈建议配置国内镜像加速器!
什么是 Docker 镜像加速器?
Docker 镜像加速器是由 国内云服务商(如阿里云、网易、中科大等) 提供的 国内缓存服务,可以大幅提升 拉取 Docker Hub 镜像的速度与稳定性。
可以使用以下 公共镜像加速地址(免费,无需登录):
| 镜像源 | 加速地址 |
|---|---|
| 网易云 | https://hub-mirror.c.163.com |
| 中科大 | https://docker.mirrors.ustc.edu.cn |
| DaoCloud | https://f1361db2.m.daocloud.io |
| 腾讯云(需要登录) | https://mirror.ccs.tencentyun.com |
| 阿里云(需要登录获取个人地址) | https://<你的ID>.mirror.aliyuncs.com |
| 华为云(需要登录获取个人地址) | https:/ |
获取阿里云个人加速地址:
- 登录 阿里云容器镜像服务控制台
- 找到 “镜像加速器”
- 阿里云会提供类似如下的地址:
温馨提示:这里我用的是阿里云的镜像加速地址(根据自己使用的云平台去选择)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xkw8xit4.mirror.aliyuncs.com"]
}
EOF
# 重启 Docker 服务,使配置生效
sudo systemctl daemon-reload
sudo systemctl restart docker
如果你没有阿里云账号,推荐直接使用 网易云 或 中科大 的公共地址。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
7、镜像制作
需求:采用docker,启动一个nginx,并将它的首页改为自己的页面,发布出去,让所有人都能使用
实现步骤:

docker version: 查询docker客户端、服务端的版本等信息
docker info : 查询docker更加详细的信息
docker --help : 查询docker的命令的使用
7.1、下载镜像
镜像相关的命令:
- 搜索镜像:docker search 镜像名
- 下载对应版本的镜像:docker pull 镜像名:版本号
- 列出当前下载的所有镜像:docker images
- 删除某个镜像:docker rmi 镜像名:版本号 | 镜像唯一编号
docker的镜像仓库地址:https://hub.docker.com/ , 可以查阅对应的镜像,以及运行和操作相关配置等

docker search nginx
docker pull nginx
有时docker拉去镜像会发生下面的错误(即使配置国内镜像地址,依然不行,试试下面的镜像地址):
[root@localhost ~]# docker pull nginx
Using default tag: latest
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
这个问题通常是由于Docker与Docker Hub之间的连接超时导致的,可能是因为网络问题或者Docker Hub服务器响应缓慢。解决方法:
-
备份文件:/etc/docker/daemon.json
cp /etc/docker/daemon.json /etc/docker/daemon.json.bak -
修改文件:vim /etc/docker/daemon.json,内容如下:
{ "registry-mirrors":[ "https://docker.1ms.run", "https://docker.1panel.live/" ] } -
重新加载配置和重启docker
sudo systemctl daemon-reload sudo systemctl restart docker
7.2、镜像相关命令
7.2.1、docker images
docker images:列出所有镜像

repsositroy : 镜像源
tag:镜像的标签
image id :镜像的id(操作镜像的时候,可以根据镜像源名称操作,也可以通过image id 进行操作)
created:镜像创建的时间
size:镜像的大小
docker images [options]:
options : 操作镜像的时候,可以跟一些参数
-a : 查询当前镜像下的所有镜像(镜像通过会嵌套镜像)
-q: 只列出镜像的iamge id
–digests:列出镜像的摘要信息
–no-trunc:显示镜像的完整信息
7.2.2、docker search
docker search:从docker的仓库中搜索镜像。等价于通过浏览器访问:https://hub.docker.com

7.2.3、docker pull
docker pull:下载某个镜像
# 下载tomcat镜像
docker pull tomcat

docker pull 镜像名:版本号
7.2.4、docker rmi
docker rmi:删除镜像
# docker rmi 镜像名称或id
docker rmi tomcat
注意:删除的镜像不能是正在运行的镜像。
# 删除单个镜像 -f
docker rmi -f 镜像名或id
# 删除多个镜像 , 直接在后面书写多个镜像,使用空格隔开即可
docker rmi -f 镜像名或id 镜像名或id ……
# 删除全部镜像,这里需要使用组合命令
# docker rmi -f $(docker image -qa)
7.3、容器操作
重要的事情说三遍:有镜像,才能有容器,通过镜像创建容器
容器操作相关的命令:
- 运行:docker run(较复杂)
- 查询:docker ps
- 停止:docker stop
- 启动:docker start
- 重启:docker restart
- 状态:docker stats
- 日志:docker logs
- 进入:docker exec(较复杂)
- 删除:docker rm
其中的run和exec两个命令稍微复杂点,其它命令都是比较简单的
7.3.1、docker run
docker run 创建并启动容器。可以使用docker run --help,查询run的详细用法
docker run nginx

这时运行的nginx,属于前台运行,会占用当前命令行窗口,如果强制结束,那么nginx也会停止运行
docker run -d --name mynginx -p 80:80 nginx
操作符说明:
–name “容器新名称”:为启动的容器指定一个名称
-p 宿主机端口:容器端口 : 随机端口映射
-d : 后台运行容器,并返回容器的ID,即启动守护式容器
-i : 以交互模式运行容器,通常与-t同时使用
-t : 为容器重新分配一个伪输入终端,通常与-i同时使用
当使用上面的方式运行nginx之后,在与宿主机相同局域网的环境中就可以访问到nginx,docker所处的宿主机位于公网环境,那么在任何地方都可以访问nginx(前提:宿主机网络安全策略中必须开放80端口)
7.3.2、docker ps
docker ps 列出正在运行的容器
-a : 列出当前所有正在运行的容器和曾经运行过的容器
-q : 静默模式,只显示容器编号
docker ps # 列出正在运行的容器
docker ps -a # 列出运行和停止的容器

7.3.3、docker start
docker start : 当通过镜像已经创建出容器之后,如果容器停止了,可以再次去启动容器(注意不是创建容器哦)
命令 : docker start 容器id

7.3.4、docker restart
docker restart 不管这个容器是停止还是运行,都可以将这个容器运行起来

7.3.5、docker stop 停止和 docker kill 强制停止容器
停止命令: docker stop 容器ID或容器名称
强制停止:docker kill 容器ID或容器名称

7.3.6、docker rm 删除停止的容器
使用docker stop 或者 docker kill 可以停止容器,但是docker本身会记录已经创建的容器。容器本身还是存在的。

docker rm 容器名或容器id:删除停止运行的容器
docker rm -f 容器ID或容器名称:强制删除运行中的容器,也就是停止容器然后删除
删除多个容器命令:docker rm [-f] $( docker ps -a -q )
7.3.6、docker logs 日志
命令 : docker logs -f -t --tail 容器id

7.3.7、docker exec
docker exec : 进入到容器中,进行简单的命令操作
docker exec -it mynginx /bin/bash

从新刷新页面,可以看到内容已经变化(我这里采用的云服务器演示docker,忽略浏览器的IP地址)

8、保存镜像
8.1、docker commit 构建新镜像
可以使用docker commit --help,查阅命令的详细用法

docker commit 基于当前容器的改变情况,构建出一个新的镜像
docker commit -a "qubo" -m "change index.html" mynginx myapp:v1.0

8.2、docker save 保存新镜像
docker save : 将镜像保存成tar文件,就可以发送给别人,其它人就可以加载这个镜像去运行

8.3、docker load 加载镜像


9、分享镜像
将自己的镜像文件可以分享到社区(docker创库中),别人就可以直接拉取镜像去使用
分析镜像需要三部操作

9.1、docker login
分享镜像之前,需要登录自己的docker账号,若没有账号,需要先去docker官网注册账号,然后进行登录

9.2、docker tag
docker tag 原始镜像 新镜像(必须加上用户名)

9.3、docker push

有时会因为网络问题,导致推送失败,可以多尝试几次
10、数据存储
使用docker构建容器,当需要修改容器中的数据、配置文件等内容的时候。
如果每次都使用docker exec 进入容器进行操作,会非常麻烦,而且如果容器被删除,所有的数据和配置文件等全部都丢失。
docker提供两种方案来解决这个问题:挂载宿主机的某个目录或文件到容器中(类似于U盘的概念)、使用数据卷
10.1、目录挂载
使用 -v 宿主机目录:容器中的目录位置
docker run -d --name nginx01 -p 80:80 -v /app/html:/usr/share/nginx/html nginx
上面的指令相当于将宿主机的 /app/html目录挂载到nginx容器中/usr/share/nginx/html
这时修改宿主机的/app/html目录中的任何文件,都会同步到nginx容器中/usr/share/nginx/html目录中
若改宿主机的/app/html目录为空目录,那么nginx容器中/usr/share/nginx/html目录同样什么也没有(原来默认的首页等全部失效)

首次挂在完,访问会看到上述结果,就算因为宿主机的目录中没有任何文件(在挂载目录的时候,如果宿主机中目录不存在,会自动创建)

重新访问,可以正常看到页面

10.2、数据卷映射
10.2.1、数据卷介绍
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。
# 查询数据卷的所有命令
docker volume --help
# 创建数据卷
docker volume create
# 查询指定数据卷的详情
docker volume inspect 数据卷名
# 列出所有的数据卷
docker volume ls
10.2.2、数据卷演示
数据卷同样是使用-v命令进行操作,与目录挂载的区别在于不需要书写宿主机的目录名,而是书写数据卷名
docker run -d --name nginx02 -p 90:80 -v /app/html:/usr/share/nginx/html -v ngconfig:/etc/nginx/ nginx
这里书写的ngconfig它表示的数据卷的名称,如果不存在,也会自动创建数据卷。
上述数据卷对应容器中的nginx的核心配置文件所在的目录,修改数据卷中的内容,就相当于可以直接修改容器中nginx的配置文件

docker volume inspect ngconfig # 查询数据卷信息

查询数据卷信息,可以看到在数据卷在宿主机中的目录为:/var/lib/docker/volumes/ngconfig/_data 目录
/var/lib/docker/volumes/ 为所有数据卷所在的目录

进入到宿主机卷所在的目录中,可以看到已经将容器中对应的目录下的所有文件在宿主机卷目录复制一份
重要事情:若将容器删除,宿主机中挂载的目录或数据卷都不会被删除,下次创建运行容器依然可以使用
11、自定义网络
11.1、docker的默认网络
使用docker网络机制,可以构建集群等环境。
docker为每个容器分配唯一ip,使用 容器ip+容器端口 可以互相访问
# 使用docker inspect 容器名或容器ID,查询某个容器的详情
[root@hcss-ecs-3c1a _data]# docker inspect nginx01

看到每个容器自己的网络信息。可以使用docker exec -it 进入到某个容器中,使用IP地址去访问某个容器,但是这种操作容易出现问题,若容器的IP地址发生改变等,就会导致无法访问等现象出现。一般建议配置自定义网络。
11.2、自定义网络
使用docker network 创建自定义网络,可以先使用docker network --help 查询命令使用细节

[root@hcss-ecs-3c1a _data]# docker network create mynet

# 删除以前所有容器
[root@hcss-ecs-3c1a _data]# docker rm -f $(docker ps -aq)

# 在构建容器的时候,可以使用 --network 将容器加入到自定义网络中
[root@hcss-ecs-3c1a _data]# docker run -d --name nginx01 -p 80:80 --network mynet nginx
[root@hcss-ecs-3c1a _data]# docker run -d --name nginx02 -p 90:80 --network mynet nginx

查询网络容器的详情
[root@hcss-ecs-3c1a _data]# docker inspect nginx01

可以看到容器已经加入到自定义网络中,这样容器之间可以**直接通过****容器名称**访问,不需要关心容器对应的IP地址

12、docker安装mysql
在使用docker 构建容器的时候的时候需要注意内容:
- 容器要不要对外暴漏端口,若需要,必须使用-p 参数配置暴漏的端口
- 容器要不要配置网络,若需要,必须使用 --network 参数配置
- 容器要不要修改相关配置文件,若需要,可以使用-v 参数以目录或者数据卷方式完成
- 容器要不要挂载相关的数据,若需要,可以使用-v 参数以目录或者数据卷方式完成
- 容器要不要配置环境变量,若需要,可以使用-e 参数完成相关配置(不同镜像环境变量不同,需要查询文档)
docker run -d \
-p 3306:3306 \
--name mysql \
--network mynet \
-v /app/myconf:/etc/mysql/conf.d \
-v /app/mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql

进入到容器中操作mysql
[root@hcss-ecs-3c1a _data]# docker exec -it mysql bash

使用图形化工具链接测试


13、Docker Compose
13.1、docker compose介绍
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它通过一个简单的配置文件来描述应用程序的服务、网络和存储卷,使得管理和编排复杂的容器化应用变得更加容易。
13.2、compose语法介绍
compose语法:https://docs.docker.com/compose/compose-file/

在compose文件中,可以书写的顶级元素:
name:名称
services:服务
networks:网络
volumes:卷
configs:配置
secrets:密钥
主要使用前4个顶级元素,进行compose文件配置编写:
名称(name):顶级name属性由 Compose 规范定义为在您未明确设置项目名称时要使用的项目名称。
服务(Services):服务是一个独立的容器实例,通常对应一个微服务或应用程序的组成部分。例如,一个 Web 应用可能由多个服务组成,如数据库服务、后端 API 服务和前端服务。
网络(Networks):Docker Compose 允许定义多个网络,以便服务之间可以通过网络进行通信。默认情况下,所有服务都连接到同一个网络,但也可以配置自定义网络。
卷(Volumes):卷是持久化数据的机制。通过定义卷,可以确保容器重启或重建后数据依然存在。例如,可以将数据库的数据存储在卷中。
13.3、compose示例
编写一个compose文件,用于一键启动mysql和wordpress,文件名compose.yaml
name: mydemo
services:
mysql:
container_name: mysql
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /app/myconf:/etc/mysql/conf.d
restart: always
networks:
- blog
wordpress:
image: wordpress
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
restart: always
networks:
- blog
depends_on:
- mysql
volumes:
mysql-data:
wordpress:
networks:
blog:

13.4、 主要命令
- docker-compose up:启动并运行 docker-compose.yml 文件中定义的所有服务。如果镜像不存在,会先构建镜像。
- docker-compose down:停止并删除所有运行的容器、网络和卷,但不会删除镜像。
- docker-compose build:构建或重新构建服务的镜像。
- docker-compose pull:从镜像仓库中拉取服务所需的镜像。
- docker-compose ps:列出所有由 Docker Compose 管理的运行中服务的容器。
# 使用 docker compose 启动并运行 编写 compose.yaml文件
[root@hcss-ecs-3c1a app]# docker compose -f compose.yaml up -d
# 参数说明:
# -f 指定需要使用的compose文件
# -d 标签所有的容器,都以后台方式启动
如果compose.yml文件中使用到的镜像不存在,会开始下载,最终将对应的所有服务器全部运行起来。

打开网页访问搭建的wordpress博客系统,一切正常

14、DockerFile
14.1、DockerFile介绍
Dockerfile 是一个文本文件,包含了一系列指令,用于定义一个 Docker 镜像的构建过程。它是创建自定义 Docker 镜像的基础,通过描述应用程序及其依赖项的安装和配置步骤,确保生成的镜像可以在任何支持 Docker 的环境中一致地运行。
14.2、DockerFile语法
Dockerfile 的基本语法如下:https://docs.docker.com/reference/dockerfile/
- FROM - 指定基础镜像。每个 Dockerfile 必须以 FROM 指令开始。
- RUN - 执行命令来安装软件包或执行其他操作。每个 RUN 指令都会在基础镜像之上创建一个新层。
- COPY - 将文件或目录从宿主机复制到镜像中的指定位置。
- LABEL - 自定义标签
- ADD - 与COPY作用相同,ADD 比 COPY 多了几个功能,如解压 tar 文件和从 URL 下载文件。
- CMD - 指定容器启动时要执行的命令。CMD 可以有多次,但只有最后一个 CMD 会被执行。
- ENV - 设置环境变量。
- ARG - 构建参数
- EXPOSE - 声明容器运行时监听的端口。这只是一个文档化的声明,不会实际打开端口。
- VOLUME - 创建一个挂载点,使数据可以在容器之间共享或持久化。
- USER - 指定运行用户
- WORKDIR - 设置工作目录。后续的指令将会在这个目录下执行。
- ENTRYPOINT - 配置容器启动时运行的主命令,通常与 CMD 配合使用,以提供默认参数。
14.3、镜像分层介绍
Docker 镜像的分层(layering)是 Docker 镜像构建过程中的一个核心概念。它基于联合文件系统(Union File System),使得镜像可以由多个只读层(layers)叠加而成。每一层都是从前一层的修改结果,并且是只读的。

通过docker history 可以查询镜像分层信息
[root@hcss-ecs-3c1a ~]# docker history nginx:latest
IMAGE CREATED CREATED BY SIZE COMMENT
605c77e624dd 2 years ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 2 years ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
<missing> 2 years ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 2 years ago /bin/sh -c #(nop) ENTRYPOINT ["/docker-entr… 0B
<missing> 2 years ago /bin/sh -c #(nop) COPY file:09a214a3e07c919a… 4.61kB
<missing> 2 years ago /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7… 1.04kB
<missing> 2 years ago /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0… 1.96kB
<missing> 2 years ago /bin/sh -c #(nop) COPY file:65504f71f5855ca0… 1.2kB
<missing> 2 years ago /bin/sh -c set -x && addgroup --system -… 61.1MB
<missing> 2 years ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~bullseye 0B
<missing> 2 years ago /bin/sh -c #(nop) ENV NJS_VERSION=0.7.1 0B
<missing> 2 years ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.21.5 0B
<missing> 2 years ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
<missing> 2 years ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 2 years ago /bin/sh -c #(nop) ADD file:09675d11695f65c55… 80.4MB
通过查询自己构建的镜像与从官网下载的镜像进行对比,会发现基础部分完全一样

Docker 镜像层都是只读的,容器层是可写的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”
所有对容器的改动(无论添加、删除、还是修改文件)都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。
容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。
14.4、Dockerfile 示例
FROM openjdk:17
LABEL author=qubo
COPY *.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
需要将准备好的jar上传到宿主机中,然后编辑上面的Dockerfile文件内容

# 构建自定义的镜像
[root@hcss-ecs-3c1a app]# docker build -f Dockerfile -t javaapp:v1.0 .
# 注意:最后的(.) 表示从在当前目录执行构建自定义镜像操作
开始构建镜像
# 构建并运行容器
[root@hcss-ecs-3c1a app]# docker run -d -p 8080:8080 javaapp:v1.0
