轻松学习Docker容器的基础知识
目录

docker学习网站
Docker 文档
https://docs.docker.top/index.htm说明:这里我找到一个可以直接访问的docker学习网站,可以提供给大家学习

一.容器介绍
1.1基本概念
沙箱:一种使软件运行在受限制的系统环境中的技术,能够有效预防外来黑客通过该软件,对我们系统的破环。
容器简介:容器可以说是一种沙箱技术,就是将你的应用封装到一个集装箱的技术。它的核心功能就是两个:隔离和搬用。容器与容器之间的相互隔离,就是应用与应用之间的相互隔离,互不干扰。同时,容器也可以被轻松的搬用到其他虚拟机上使用。容器的核心技术:共享操作系统的内核。
Linux容器:Linux容器本质上就是一个系统上运行的进程,只不过有意思的点在于:它会与系统中的其他服务进程隔离起来。它运行时所需的镜像文件(除了系统内核),也由自己内容的镜像文件支持,与系统的镜像文件无关。因此它很方便被移植到其他系统上使用,具备可移植性和一致性。
软件容器:容器本身是一种虚拟化的技术,用于封装应用服务的软件包及其它的所有依赖和配置,以便它能够在其他系统上能够正常工作。而软件容器,会提供一种轻量级、一致性的运行环境,确保在开发、测试和部署时有很好的可移植性
1.2容器的特点
跨平台性:容器可以在不同的操作系统和云平台上使用,同时确保应用环境的一致性。
一致性和可重复性:容器封装了应用服务及其所有依赖和配置文件,确保了开发和测试时一致的运行环境。同时,容器封装的应用服务支持多次重复部署,避免不同环境导致的问题。
资源隔离: 容器提供了一定程度的隔离性,使得多个容器可以在同一主机上并行运行而互不干扰。这种隔离性能够确保应用程序的稳定性和安全性。
快速部署和启动: 容器可以在几秒钟内启动,启动时间更短。
高可伸缩性:容器架构支持自动化的横向扩展,可以根据需求动态地增加或减少容器实例。这种高可伸缩性使得应用程序能够更好地应对流量和负载的变化。
环境隔离: 容器提供了独立的运行环境,每个容器都有自己的文件系统、网络和进程空间。这种环境隔离有助于防止应用程序之间的相互影响,提高了系统的稳定性和安全性。
资源效率: 容器共享主机操作系统的内核,相比虚拟机,容器更加轻量级,更加节省系统资源。
持续集成和持续部署(CI/CD): 容器与持续集成和持续部署工具集成紧密,使得开发团队能够更容易地实现自动化构建、测试和部署流程
1.3容器的核心技术
说明:Namespaces的作用是隔离,它让容器只能看见自己内部的资源,而不干扰外部系统和其他容器的使用。Cgroups的作用是限制,它让容器只能使用已经分配好的资源,没办法无限制的使用系统资源。
1.3.1Namespaces命名空间
说明:
命名空间:Linux 内核提供的一种“资源隔离”功能。它的作用是:为进程打造一个独立的“虚拟小世界”。
当有多个不同类型的命名空间被部署在同一个虚拟机时,各个docker容器之间独立运行,却共用同一个宿主机的内核。他们受docker主进程管理,但进程树上属于独立的进程。
每个容器都类似虚拟机一样,拥有相互隔离的运行空间,不同的是,容器是在一个进程内,搭建指定服务的运行环境,同时不干扰主机的其他进程运行。
1.基本概念
基本概念:只提供进程、文件系统和网络等资源的隔离,确保容器运行时只会操作自己的服务进 程,而不干扰容器外的进程运行。
例如:命名空间可以提供一个进程相互隔离的独立网络空间,不同的容器间进程`PID`可以相同,进程并不冲突影响,但可以共享底层的计算和存储资源
2. MNT Namespace——文件系统隔离
基本概念:每个容器都必须拥有一个根文件系统,同时拥有一个用户空间,应用服务在容器内部的用户空间中启动并在容器内部的环境中运行。

例如:一个ubuntu环境下,部署了一个基于centos环境的nginx服务。在nginx服务启动时,是运行在centos的环境下,与ubuntu环境无关。它只是会调用ubuntu的系统内核,而ubuntu和centos的内核都是Linux,所以不会影响服务的正常运行。
3. UTS Namespaces——主机名标识隔离
基本概念:包含操作系统内核的基本信息,用于系统标识。如:主机名,内核名称等。它能够使每个容器拥有一个自己的主机名标识,这个主机名标识独立于宿主机系统和其他容器。
4. NET Namespaces——网络和端口隔离
基本概念:每个容器都有一个Vthex接口,通过这个接口,拥有自己的网络IP和端口,容器内的端口和IP占用并不影响宿主机和其他容器的端口和IP的使用。

5. PID Namespaces——进程隔离
基本概念:每个容器中都有一个独立的父进程PID1,负责用来收养孤儿进程和僵尸进程,同时,容器内的进程只能看到该 Namespace 内的 PID 列表,看不到宿主机或其他容器的 PID,实现进程隔离。因此,每个容器中都可以有相同的PID号

6. User Namespaces——用户隔离
基本概念:每个容器内都可以拥有相同的用户(uid)和用户组(gid),他们之间互不冲突。只是用户仅会在当前的容器内存在和使用。

1.3.2Cgroups
说明:
Cgorups是Linux内核中的一个功能,它的核心作用是完成限制、用户和管理进程组。Cgroups实现了对系统资源(如:CPU、I/O、内存、磁盘等)的精细控制,它允许系统管理员对一个进程的资源分配和限制,该进程无法无限制地使用系统资源。容器本质上就是一个进程,因此Cgroups也能够实现对容器的资源分配和限制。
总的来说,Cgroups能够限制一个进程使用资源的最大上限,还能完成进程的优先级设置,数量统计和资源控制等等。

1.4容器与虚拟化
1.传统虚拟化:
虚拟化其实就是在一个操作系统上运行另一个操作系统。通过软件模拟一个虚拟的电脑,创造一个与主机完全隔离的环境,将操作系统本身所需要的硬件全都虚拟出来的。例如:我们在windows上使用VM软件运行Linux操作系统。虚拟化本身不会对主机的操作系统有任何影响,因为它实质上就是一堆文件,如果不需要,删除即可。这套虚拟技术能够很好的让虚拟的操作系统运行应用服务,而不会影响主机 操作系统的正常运行。
缺点:占用主机的资源较多,启动时间长,冗余步骤多
2.容器:
容器的最大特征就是:它并不是做到与主机的完全隔离,而是一个进程的隔离。事实上,它在运行时,还是会依赖主机的内核资源。在容器中,它会将软件运行所需的所有资源(镜像文件、软件依赖包等)全部打包在一个隔离的容器中。运行容器时,只需要软件资源库和相关设置。因此部署变得高效且稳定。
3.虚拟化与容器的不同之处:
虚拟化其实就是虚拟出一个完整的操作系统,拥有自己的内核和硬件资源,其中包含内存、CPU、硬盘等等。在这个操作系统上,运行自己的服务进程。而容器并没有自己独立的内核和硬件资源,它的内部只有一些文件,运行服务时,在容器内部运行进程。因此效率更高,启动更快。对于系统来说,容器只是系统中的一个进程。
二.部署Docker
2.1简单介绍
2.1.1基本概念
说明:Docker是一款平台即服务的产品。它基于操作系统层的虚拟化技术,将软件及其依赖项打包成容器的镜像文件。托管容器的产品名称:Docker引擎。Docker能够帮助开发者在轻量级的容器中自动部署应用服务,并使得不同容器之间的产品服务相互隔离,从而高效工作。同时,开发人员也可以将自己的软件打包成标准单元,上传到Docker仓库中,用于开发,搬运和测试等工作。Docker将软件应用及其依赖文件全部打包到一个容器内,以便一个应用程序能够从一个计算机资源快速在另外一个计算资源中运行。
总的来说:Docker容器镜像是一个轻量级的、独立的可执行软件包,里面包含了运行程序所需的所有东西:代码、运行环境、系统工具等等。容器镜像在运行时会变成容器服务。
2.1.2Docker的三大目标
Docker的三大目标:build(构建)、ship(传输)、run (运行)。
1.build(构建):docker build,做一个完整的镜像文件,方式:手动构建和文件构建。
2.ship(传输):docker pull或docker push,即将构建的镜像文件上传到docker仓库中,或者从docker仓库中下载容器镜像
3.run(运行):docker run,运行容器镜像文件,从镜像文件变成容器进程。


2.1.3Docker架构

1.Docker Client(客户端):用户与Docker系统进行交互的接口,用户通过CLI命令(如docker run,docker build,docker pull等)与 Docker守护进程通信,发出管理容器的各种指令。
2.Dockerd (Docker 守护进程):也称docker Engine,他是docker 的核心部分,负责处理docker client的请求,管理 docker 的容器镜像、运行、网络和数据卷等等,并将请求传递给下一级组件(如Containerd)。
3.Containerd:容器运行时,负责管理容器的整个生理周期。包括:容器的创建、执行、挂载等等。通过 gRPC 接收 Docker 的指令,并进一步传递给 Runc 和 Shim。
- 生命周期:启动、停止和删除容器
- 镜像管理:构建、拉取和上传容器镜像
- 资源管理:容器运行的资源限制
- 日志管理:处理容器的日志输出
4.Runc:Runc是一个CLI工具,负责容器的底层启动操作。通过fork进程创建容器,containerd调用runc,并确保Docker镜像以OCI标准的格式交给runc。
5.Shim: Shim是一个中介程序,在容器与Containerd之间进行隔离。当Runc启动完程序后,shim会将Runc从系统中分离出来,接管服务,保持服务运行。
如果Containerd重启或者崩溃掉,容器仍然可以继续运行,充当服务的父进程。作为父进程的shim,负责管理容器与容器之间的通信。
当应用服务结束后,Shim负责接收容器的退出状态,并清理资源。
在Docker中,shim的作用是让容器独立于Dockerd,使得容器的运行更加稳定。
2.1.4工作机制
正常的docker服务运行流程如下:

说明:由于Docker官方不允许我们直接访问docker官网,因此我们需要借助代理去访问它。docker的工作流程就繁琐了,需要我们借助代理在官网上下载它的镜像文件。之后,再去运行它。

2.2安装Docker
1.前往阿里云官方镜像网站,下载docker-ce软件源仓库
说明:由于dokcer官方不允许我们直接访问它,因此我们需要配置阿里云源去安装docker
官方镜像网站:阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区
https://developer.aliyun.com/mirror/1.1在搜索栏搜索docker,进入docker-ce

1.2找到软件源仓库地址,复制它

1.3使用wget命令下载软件仓库,并指定安装位置(/etc/yum.repos.d)
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -P /etc/yum.repos.d/
yum update #刷新yum软件仓库,观察是否成功加入

2.安装docker软件包
说明:docker中含有两个版本 社区版(ce) 和 企业版(ee),其中社区版是免费的,有开源代码和强大的社区;企业版提供额外的安全性,同时具备更多功能,但需要付费使用
yum install -y docker-ce

3.添加docker.conf配置文件(可选)
说明:如果不做该操作,在docker初始化时,会出现以下警报:

3.1查看并列出所有与IP转发有关的内核配置
说明:默认情况下,IP转发的所有功能都是关闭的,需要我们手动去设置它
sysctl -a | grep ip_forward #查看IP转发功能状态
sysctl -a | grep iptables #查看ipv4的iptables防火墙状态
sysctl -a | grep ip6tables ##查看ipv6的流量转发iptables防火墙状态

3.3开启IP转发功能
echo "net.ipv4.ip_forward= 1 " >> /etc/sysctl.d/docker.conf ##启用 Linux 内核的 IP 数据包转发功能
说明:容器默认使用的是bridge模式,有着自己的网段。如果不启用转发功能,数据包就无法传递到外网上。
3.4设置Linux流量转发时经过 iptables
echo "net.bridge-nf-call-iptables= 1 " >> /etc/sysctl.d/docker.conf # 让经过 Linux 网桥(Bridge)的流量,也经过 iptables 的 FORWARD 链
echo "net.bridge-nf-call-ip6tables= 1 " >> /etc/sysctl.d/docker.conf #针对ipv6,让经过 Linux 网桥(Bridge)的流量,也经过 iptables 的 FORWARD 链
说明:设置这个功能,能够确保流量经过虚拟网桥时,也能经过iptables的forward链。Docker 利用 iptables 来实现端口映射(
-p)、网络隔离和 NAT 地址转换

3.5刷新内核参数
sysctl --system
![]()

4. 启动docker服务并设置开机自启
systemctl enable --now docker

5.完成docker初始化
docker info
![]()

说明:不存在 docker.sock文件,一般是在初始化前没有启动docker服务产生的问题
解决方法:
systemctl restart docker #重新启动docker
三.docker的基本操作
说明:官方的docker平台,我们无法直接流畅地访问,因此我们需要借助代理来访问。这里我推荐一个1ms(1毫秒),有免费和付费两种。免费能够访问,但速度较慢;付费版每月有定额高速访问流量。
直接访问Docker平台:
yum search 镜像文件 #搜索镜像文件

说明:直接搜索Docker平台上的镜像文件,连接会被拒绝
借助代理访问Docker平台:
yum search docker.1ms.run/镜像文件 #借助docker.1ms.run代理访问Docker平台

3.1镜像操作
3.1.1搜索镜像
yum search docker.1ms.run/镜像文件 #借助docker.1ms.run代理访问Docker平台

说明:搜索时,除了官方镜像,也会搜索到其他人自己的镜像,需要做些区分
3.1.2下载镜像
yum pull docker.1ms.run/镜像文件:tag #借助docker.1ms.run代理访问Docker平台

说明:tag是指镜像文件的标签,如果在下载时不加标签默认直接下载标签为:lagest的镜像文件。此外,使用代理下载的镜像文件,文件前面一般会多出代理的名称
3.1.3查看本地镜像仓库
docker images

说明:查看本地镜像仓库里的所有镜像文件时本地操作,所以不需要借助代理。
参数说明:
REPOSITORY:镜像文件名称
TAG:标签
IMAGE_ID:镜像文件ID
CREATED:创建时间
SIZE:文件大小
3.1.4复制镜像文件
docker tag 源镜像文件名称:tag 新镜像文件名称:tag

说明:该方式复制了一份新的镜像文件,之后,我们可以删除源镜像文件,从而实现镜像文件的重命名
3.1.5删除镜像文件
docker rmi 镜像文件名称

3.1.6打包镜像文件(tar包)
docker save -o 打包名称 镜像文件

3.1.7加载镜像文件(tar包)
docker load -i 镜像文件的tar包

3.1.8查看镜像文件的信息
1.查看镜像文件的构造历史和分层:
docker history 镜像文件

2.查看镜像的详细信息:
docker image inspect 镜像文件
参数:
--format:筛选信息

3.2容器操作
3.2.1查看容器列表
docker ps [参数]
参数:
-a:展示所有容器列表,包括正在运行和已经停止的容器,不加-a,无法查看已经停止的容器。

3.2.2运行容器
docker run [参数] 镜像文件:tag #不写tag,默认为latest
参数:
--name:为这个容器命名,每一个容器的名称都是唯一的,无法共享,如果不加这个参数,系统为自动为这个容器命名
-p:端口映射,将本机上的端口,映射成容器中的服务端口
-d:后台运行容器,防止占用当前端口

不加-d:它会持续占用桌面

使用 ctrl + c,退出它:

测试:
直接访问本机的80端口,无法直接访问到容器中的服务:

访问本机的8080端口,容器中,docker会将端口映射成80端口访问:

3.2.3创建容器
说明:仅创建一个容器,但不运行它,需要我们手动启动它
docker create 镜像文件


3.2.4开启容器
说明:开启容器与启动容器不同。开启容器,是将已经停止了的容器启动起来;运行容器,是将原先没有的容器启动起来。容器ID,可以通过docker ps 查看
docker start 容器ID/容器名称

3.2.5停止容器
说明:容器停止,并不代表已经被删除。在容器未被删除前,无法创建与它同名的容器。同时,已经停止的容器也可以通过start命令重新启动它。容器ID,可以通过docker ps 查看
1.温柔的停止容器:终止信号。礼貌地告诉进程“请终止”,进程可以捕获此信号并执行清理逻辑
docker stop 容器ID/容器名称


一次性停止所有容器:
docker stop $(docker ps -aq)

测试:在停止该容器的情况下,创建一个新的同名容器,有如下报错:

2.强制停止容器:强制杀死信号。进程无法捕获或忽略此信号,操作系统会直接回收该进程的资源。
docker kill 容器ID/容器名称
3.2.6删除容器
说明:之前说过,停止容器不表示删除容器。在停止容器之后,我们需要使用删除指令彻底删除该容器。
docker rm 容器ID/容器名称

一次性删除全部容器:
说明:筛选出所有容器的ID,一次性全部删除
docker rm $(docker ps -aq)

测试:已经运行的容器,无法直接删除,需要加-f参数,强制删除
不加-f:
![]()
加-f:

3.2.7暂停容器
docker pause 容器ID/容器名称

3.2.8恢复容器
docker unpause 容器ID/容器名称

3.2.9查看容器的详细信息
docker inspect 容器名称/容器ID
参数:
--format:筛选信息

3.2.10查看容器日志
说明:容器日志,能够在容器未正常启动时查看它的历史日志信息。日志需要在shell上输出出来,才能够被docker api捕捉到,并在命令窗口显示出来。
存储位置:/var/lib/docker/containers/容器ID
docker logs 容器ID/容器名称

3.2.11以交互方式进入容器
docker exec -it 容器名称/容器ID /bin/bash 或者 /sh

退出操作:
ctrl + d:直接退出容器和停止容器服务
ctrl + p + q:仅退出容器内部,容器服务依旧运行
3.3示例
3.3.1.成功运行一个小游戏容器
1.搜索镜像
docker search docker.1ms.run/yakexi007

2.下载镜像
docker pull docker.1ms.run/yakexi007/game2048
docker images #查看镜像仓库

3.运行容器
docker run -d --name game -p 80:80 docker.1ms.run/yakexi007/game2048

4.在浏览器上搜索本机IP

3.3.2运行mysql服务
1.加载mysql.tar包
docker load -i mysql.tar

2.运行容器
说明:这里只是启动mysql 服务,后面我们还需要一个mysql客户端去访问它
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=redat --name dbserver mysql

3.安装mariadb
yum install -y mariadb
![]()
4.访问数据库
mysql -h 127.0.0.1 -predat

说明:如果不指定主机,mysql会找不到指定的socket文件:

四.构建镜像文件
4.1简单介绍
说明:构建镜像文件,主要分为两种方式,一种是手动方式,一种是文件方式。
4.2手动构建镜像文件
说明:通过运行一个基础容器,在里面手动执行命令(安装软件、修改配置),最后将修改后的容器“保存”为一个新镜像
操作步骤:
1.启动一个基础容器,并进入交互终端
2.在容器终端内,进行各种手动操作
3.退出容器后,执行 docker commit 将容器的当前状态保存为新镜像。
核心操作命令:
docker commit 容器名称/ID 镜像文件(自命名)
示例:创建三个普通文件,复制本机文件到容器中,打包成一个镜像文件
1.下载busybox镜像
说明:BusyBox 是一个“超级压缩的百宝箱”,把一个完整 Linux 系统最常用的 300 多个命令,全部塞进了一个仅有 1~2 MB 大小的单一文件中。方便我们用来测试。
docker pull docker.1ms.run/busybox

2.运行并进入busybox内部
说明:在容器内部创建三个文件,并保持服务状态运行的情况下,退出容器内部
docker run --name demo -it docker.1ms.run/busybox
touch file1 file2 file3

3.将本机的文件复制到容器内部
docker cp os.sql demo:/

4.封装成镜像文件
docker commit -m 'add os.sql' demo demo:v1
参数:
-m:备注镜像文件信息

5.运行容器,查看容器内部的文件情况
docker run -it --name test demo:v1

4.3通过文件构建镜像文件
说明:编写一个名为 Dockerfile 的文本文件,在里面逐条写明构建镜像所需的每一条指令(基础镜像、依赖安装、文件复制、启动命令等),然后通过 docker build 命令自动构建。
操作步骤:
1.创建一个 Dockerfile 文件。
2.按格式编写构建指令。
3.在 Dockerfile 所在目录执行 docker build 命令。
核心操作命令:
docker build -t 镜像文件(自命名) .(Dockfile文件所在目录)
参数:
-t:为这个新的镜像文件起一个名字
示例:创建三个普通文件,复制本机文件到容器中,打包成一个镜像文件
1.创建一个目录,进入后,创建一个Dockerfile文件
mkdir Docker
cd Docker
touch Dockerfile
touch os.sql #充当复制的源文件

![]()
2.编写Dockfile文件
vim Dockerfile
内容如下:
FROM docker.1ms.run/busybox #引入busybox镜像
RUN touch file1 file2 file3 #创建三个普通文件
COPY os.sql / #把当前目录下的os.sql文件,复制到镜像文件的根目录/下

3.构成镜像文件
docker build -t demo:v2 .
docker images


4.测试:运行镜像文件,查看容器内部是否含有文件

4.4比较两种方式的不同点
1.手动方式操作较为繁琐,建议直接通过Dockfile文件一步生成镜像文件
2.两种方式的信息不同,在使用docker history中,手动方式看不到具体的实现过程,文件可以看到,更加安全可靠
手动创建镜像:
docker history demo:v1

文件创建镜像:
docker history demo:v2

4.6镜像文件优化
常见方法如下:
1.选择最精简的基础镜像
2.减少镜像的层数,(压缩步骤)
3.清理镜像构建的中间产物(例如压缩包)
4.注意优化网络请求
5.多用构建缓存
6.使用多阶段构建镜像
下面我会从零使用源码编译nginx:提前将nginx源包放到目录下
4.6.1准备工作
1.创建工作目录
mkdir nginx
cd nginx
2.上传centos 7的镜像压缩包和nginx的源码包到当前目录下

3.将本机的软件源仓库复制到这里,用来充当容器的软件源仓库
cp /etc/yum.repos.d/CentOS-Base.repo .
![]()
4.加载centos7镜像文件到本地镜像文件仓库
docker load -i centos7.tar


4.6.2第一版
1.编写Dockerfile
vim Dockerfile
![]()
内容如下:
FROM centos:7 #引入centos 7镜像
RUN rm -f /etc/yum.repos.d/*.repo #删除原有源
COPY CentOS-Base.repo /etc/yum.repos.d/ #添加新源
RUN yum install -y gcc make pcre-devel openssl-devel #安装依赖
ADD nginx-1.30.4.tar.gz /mnt/ #添加nginx的源码包,并解压到/mnt目录下
WORKDIR /mnt/nginx-1.30.4 #cd /mnt/nginx-1.30.4
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc #注释掉 gcc 编译器的调试选项 -g,减小编译出的二进制文件体积
RUN ./configure --with-http_ssl_module --with-http_stub_status_module #添加功能模块,检查配置文件
RUN make #生成makefile文件
RUN make install #完成编译
EXPOSE 80 #暴露80端口
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"] #前台运行nginx

2.构建镜像文件
docker build -t nginx:v1 .


3.运行容器,观察服务是否启动
docker run -d --name web1 -p 80:80 nginx:v1
curl localhost

注意:由于我们没有更改日志的输出位置,所以使用docker logs 无法直接捕捉到日志,如以下情况:
![]()
解决办法:
修改nginx.conf文件,更改输出位置,将日志输出到终端上
1.复制nginx.conf文件
docker cp web1:/usr/local/nginx/conf/nginx.conf .

2.修改文件内容
vim nginx.conf
内容如下:
error_log /dev/stderr notice; #将错误日志输出到终端
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout main; #将访问日志输出到终端

3.在Dockerfile中,修改容器中的nginx.conf文件
COPY nginx.conf /usr/local/nginx/conf

4.测试
docker logs web1

4.6.2第二版
优化方式:减少镜像层数,清理镜像中的产物
1.修改Dockerfile文件内容
说明:将多个RUN合并在一起,同时清理掉与源码目录
FROM centos:7
RUN rm -f /etc/yum.repos.d/*.repo
COPY CentOS-Base.repo /etc/yum.repos.d/
ADD nginx-1.30.4.tar.gz /mnt/
WORKDIR /mnt/nginx-1.30.4
RUN yum install -y gcc make prce-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.30.4 && yum clean all #将多个RUN合并在一起,同时清理掉与源码目录
RUN yum remove -y gcc make pcre-devel openssl-devel
COPY nginx.conf /usr/local/nginx/conf/
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

2.生成镜像文件
docker build -t nginx:v2 .

3.运行容器,测试效果并查看镜像大小
docker run --name web1 -d -p 80:80 nginx:v2
curl localhost #能看到页面,说明功能正常
docker logs web1
docker images



4.6.3第三版
说明:引入两个CentOS 7镜像文件,一个镜像专门用来构建环境,另一个作为实际的镜像文件,将上一个镜像文件生成的 nginx服务和它的依赖文件全部拷到这个新的镜像文件上,能够大幅减少空间大小。
1.修改Dockerfile文件
内容如下:
FROM centos:7 as build #搭建镜像文件环境,用来生成nginx服务和它的依赖文件
RUN rm -f /etc/yum.repos.d/*.repo
COPY CentOS-Base.repo /etc/yum.repos.d/
ADD nginx-1.30.4.tar.gz /mnt/
WORKDIR /mnt/nginx-1.30.4
RUN yum install -y gcc make prce-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.30.4 && yum clean all
RUN yum remove -y gcc make pcre-devel openssl-devel
COPY nginx.conf /usr/local/nginx/conf/
FROM centos:7 #实际的镜像文件
COPY --from=build /usr/local/nginx /usr/local/nginx #将最后的结果(nginx的服务程序和依赖文件)转移到这个文件中
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

2.生成镜像文件
docker build -t nginx:v3 .

3.运行容器,测试效果并查看镜像大小
docker run --name web1 -d -p 80:80 nginx:v3
curl localhost #能看到页面,说明功能正常
docker logs web1
docker images



4.6.4第四版
说明:这里直接调用官方的nginx镜像文件作为地基,同时引入一个最精简的基础环境镜像文件构建一个新的镜像文件。简单理解,就是把别人搭建好的nginx程序服务复制到一个最精简的系统环境上去运行。
1.引入debain镜像文件
docker load -i base-debian12.tar

2.修改镜像文件
内容如下:
FROM nginx:latest as base
RUN mkdir -p /opt/var/cache/nginx &&\
cp -a --parents /usr/lib/nginx /opt &&\
cp -a --parents /usr/share/nginx /opt &&\
cp -a --parents /var/log/nginx /opt &&\
cp -aL --parents /var/run /opt &&\
cp -a --parents /etc/nginx /opt &&\
cp -a --parents /etc/passwd /opt &&\
cp -a --parents /etc/group /opt &&\
cp -a --parents /usr/sbin/nginx /opt &&\
cp -a --parents /usr/sbin/nginx-debug /opt &&\
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt &&\
cp -a --parents /usr/lib/x86_64-linux-gnu/libpcre* /opt &&\
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt &&\
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt &&\
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt &&\
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt &&\
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt &&\
cp -a --parents /lib/x86_64-linux-gnu/libzstd* /opt &&\
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt &&\
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt
FROM gcr.io/distroless/base-debian12:latest
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]

3.构建镜像文件
docker build -t nginx:v4 .

4.运行容器,测试效果并查看镜像大小
docker run --name web1 -d -p 80:80 nginx:v4
curl localhost #能看到页面,说明功能正常
docker logs web1
docker images



openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)