一.docker run语法介绍
你可以把 docker run 理解为一台虚拟机的"一键开机"按钮。它的核心作用是:根据你提供的"蓝图"(镜像),制造并启动一个独立的、隔离的"房间"(容器),然后在这个房间里执行你指定的任务。
命令的核心逻辑
docker run 命令的执行流程可以简化为以下几步:
- 检查本地:Docker 客户端会先检查你的本地机器上是否存在命令中指定的 IMAGE(镜像)。
- 拉取镜像(如果必要):如果本地没有这个镜像,它会自动去 Docker Hub(默认仓库)或你配置的其他仓库下载它。
- 创建容器:根据镜像的层次结构,创建一个可写的容器层。这个容器层就像是放在只读镜像之上的一个写字板,所有修改都会发生在这里。
- 分配资源:根据你提供的 [OPTIONS](参数),为容器分配一个文件系统、网络、一个(或一组)独立的进程空间等资源。
- 运行命令:在容器内部执行 [COMMAND]。如果你没指定,则会运行镜像中定义的默认命令(例如,nginx 镜像的默认命令是启动 Nginx 服务)。
- 连接终端:如果配置了交互模式(-i、-t),则会为你分配一个伪终端,让你可以和容器内部的 shell 进行交互。
1.1.无参,-d
当你直接运行docker run IMAGE而不加任何参数时:
-
容器会在前台运行
-
你的当前终端会被绑定到容器的标准输入、输出和错误流
-
你会实时看到容器内进程的所有输出
-
如果容器内有交互式程序(如 shell),你可以直接与之交互
-d 是 --detach 的缩写,意思是"分离模式":
- 容器在后台运行
- 命令立即返回,并显示容器 ID
- 你的终端不被占用,可以继续执行其他命令
- 容器在后台持续运行,直到手动停止或进程结束
说白了,就是下面这两句
- 想看看容器在干什么 → 无参运行
- 想让容器在后台默默工作 → -d 运行
首先我们看看

我们运行一下
bash
docker run nginx:1.23.4-perl

我们换一个窗口看看

我们来看一下docker ps和docker ps -a。
- docker ps:默认显示当前正在运行的容器。
- docker ps -a:显示所有容器,包括正在运行的和已经停止的。
举例说明:
如果你运行了一个容器,然后它正常退出(例如执行完一个命令后退出),那么:
- docker ps 不会显示这个容器。
- docker ps -a 会显示这个容器,并且状态为Exited。
如果你有多个容器,有的在运行,有的已经停止,那么:
- docker ps 只显示正在运行的。
- docker ps -a 显示所有的。
所以,当你想要查看所有曾经创建过的容器(包括停止的)时,使用docker ps -a。而只想查看当前运行的容器时,使用docker ps。
另外,docker ps -a会显示容器的状态(Status),可以知道容器是正在运行还是已经退出,以及退出的时间等信息。
现在我们终止我们的前台进程

我们查看一下

注意,如果说你想要删除这个容器的话,其实是很简单的
bashdocker stop 容器名 docker rm 容器名这个容器名就是下面这一列的东西
我给大家举个例子,我们的镜像名是下面这个
现在就完美删除了
现在我们使用-d来启动一下这个
bash
docker run -d nginx:1.23.4-perl

这个时候容器已经运行起来了,我们也可以查一下

这就是后台运行的效果。
1.2.-it,-i,-t
在讲解参数之前,先理解一个核心概念:交互式容器就是可以让你"进入"容器内部,像操作普通 Linux 系统一样执行命令的容器。
-i 是 --interactive 的缩写,意思是保持标准输入流(STDIN)打开。
通俗理解
想象一下你在跟一个人对话:
- 有 -i:你说话他能听见(输入),他说话你能听见(输出)→ 双向对话
- 无 -i:他说话你能听见,但你说什么他都听不见 → 单向广播
技术原理
- -i 保证容器内的进程可以接收来自外部的输入
- 即使没有连接终端(TTY),也能保持输入通道畅通
- 允许你向容器发送命令、文本等输入
-t 是 --tty 的缩写,意思是分配一个伪终端(pseudo-TTY)。
通俗理解
TTY 就是让你感觉像是在操作一个真实的终端:
- 有 -t:就像坐在真实的电脑前操作,有命令提示符、支持命令行编辑、颜色显示等
- 无 -t:就像在看一个纯文本输出流,没有"终端体验"
技术原理
- 为容器分配一个虚拟的终端设备
- 启用终端功能:命令行编辑、历史记录、作业控制、信号处理等
- 提供正确的终端环境变量(如 TERM=xterm)
单独使用任何一个参数都不完美:
- 只有 -i:能输入,但没有良好的终端体验
- 只有 -t:有终端界面,但无法可靠地接收输入
-it 组合:完美的交互式体验
组合效果
-it = -i + -t = 可交互的完整终端
见一见-it的效果
我们现在就来做一下实验,首先我们的机器是ubuntu24.04LTS的

现在我们就来拉取Centos7的镜像
bash
docker pull centos:7

现在我们就来运行



我们发现一运行就退出了。我们仔细观察下面这个命令

我们运行一个容器,如果只是这样运行,它会立即退出,因为容器内没有前台进程在运行。
具体解释:
-
docker run centos:7 命令会从镜像仓库拉取centos:7镜像(如果本地没有的话),然后创建并启动一个容器。
-
但是,centos:7镜像默认的启动命令是/bin/bash,这意味着它启动了一个shell,但因为没有交互式终端(没有分配tty)并且没有命令让它保持运行,所以shell立即退出。

-
因为 CentOS 镜像默认没有前台进程 :它的Docker 容器需要至少一个前台进程 才能保持运行,CentOS 镜像启动后执行完
/bin/bash就退出了,没有服务在后台运行,所以容器立即退出。 -
当容器内的主进程(这里是/bin/bash)退出时,容器就会停止。
所以,这样运行后,使用docker ps看不到正在运行的容器,而使用docker ps -a可以看到一个已经退出的容器。
如何让容器保持运行?
常见的做法是在运行容器时进入交互模式,例如:
bash
docker run -it centos:7 /bin/bash
这样,我们就可以在容器内执行命令,并且只要我们不退出bash,容器就会一直运行。

运行起来第一件事就是使用docker ps看看有没有这个容器!!
我们打开另外一个终端看看

很好,运行成功了
我们可以查看一下版本

我们可以跟它正常交互

一点问题都没有啊!
当然啊,我们执行下面这个命令就能退出我们的镜像
bash
exit

-i的效果
bash
docker run -i centos:7 /bin/bash

运行起来第一件事就是使用docker ps看看有没有这个容器!!

很好,运行起来了。
在下面这个界面

现在我们输入一些命令来

嗯?居然能运行这些命令,我们发现可以交互啊!!

退出之后,我们可以去看看它的状态

他是也退出了!!
-t的效果
bash
docker run -t centos:7 /bin/bash

运行起来后第一件事就是去看看docker ps

确实是有,说明运行成功了
我们输入一个命令

居然没有任何响应

还是没有响应,
这就是-t的效果。
1.3.-P,-p
-p 是 --publish 的缩写,用于精确指定端口映射关系。
语法格式
-p 参数有几种不同的格式:
最常用格式:-p <宿主机端口>:<容器端口>
bash
# 将容器的 80 端口映射到宿主机的 8080 端口
docker run -p 8080:80 nginx
外部访问 http://localhost:8080 → 到达容器的 80 端口
接下来我们就进行测试一下
bash
docker run -d -p 8081:80 nginx:1.23.4-perl
这个是将宿主机的8081端口映射到容器的80端口

启动成功了,我们现在去访问这个nginx,我们去浏览器输入
bash
http://你的主机ip:8081/
注意云服务器要提前开放8081端口号

还是很不错的吧!!
如果我们不设置端口映射的话,我们外部网络是访问不了容器的服务的!!
-P 是 --publish-all 的缩写,意思是自动随机映射一个端口号。
工作机制
- Docker 会读取镜像中通过 EXPOSE 指令暴露的所有端口
- 自动为每个暴露的端口在宿主机上分配一个随机的高端口(通常从 32768 开始)
- 建立映射关系,但端口号是随机的
我们试试看
bash
docker run -d -P nginx:1.23.4-perl

这回我们看看它映射的端口号

是宿主机的32768。
我们现在去访问一下
bash
http://你的主机ip:32768/

没有任何问题
我们停止并重新运行一下
bash
docker run -d -P nginx:1.23.4-perl



我们发现这次映射的端口号又是32769了!!
1.4.--name,-h,-e
- --name 选项
作用
- --name 选项用于为容器指定一个自定义的名称。
- 这个名称在同一个 Docker 主机上必须是唯一的。
- 如果你不指定名称,Docker 会为容器自动生成一个随机的名称,例如 loving_wozniak 等。
我们可以通过docker ps的最后一列来获取到容器的名字


注意事项
- 容器名称必须是唯一的,如果试图创建两个同名的容器,Docker 会报错。
- 容器名称可以用来在 Docker 网络中进行容器间通信(通过容器名称解析到 IP)。
- 容器名称在管理容器时非常方便,比如启动、停止、删除等操作,使用有意义的名称比使用随机的容器 ID 或随机名称更容易记忆。
我们现在就来测试一下
bash
docker run -d --name mynginx1 nginx:1.23.4-perl
运行之后,我们通过docker ps看它的name就是mynginx1

通过这个名字,我们可以来对这个容器进行交互,比如下面这两句

- -h 选项
作用
-h 或 --hostname 用于设置容器内部的主机名。
默认情况下,容器的主机名是它的容器 ID(一个长字符串,如 a1b2c3d4e5f6)。
通过这个选项,你可以为容器设置一个易读的主机名。
我们直接看例子
bash
docker run -it centos:7 bash

我们发现我们运行的这个centos镜像的主机名其实是随机生成的。
我们可以通过-h来进行指定主机名
bash
docker run -it -h mycentos7 centos:7 bash

咋样?还行不?
- -e 选项
作用
-e 或 --env 用于设置容器内的环境变量。
环境变量是配置容器内应用程序的常用方式。你可以通过多个 -e 选项来设置多个环境变量。
bash
docker run -it -h mycentos7 -e myenv=test centos:7 bash


1.5.--cpuset-cpus,-m
- --cpuset-cpus 参数:CPU 绑定(或称 CPU 亲和性)
这个参数的名字可以拆开看:cpu-set-cpus,意思是"CPU 集合"。
它的核心作用是将一个容器"绑定"或"限制"在宿主机上指定的一个或多个 CPU 核心上运行。
你可以把它想象成:
你有一栋大房子(宿主机),里面有多个房间(CPU 核心)。默认情况下,你的客人(容器)可以在所有房间里随意走动、工作。但如果你使用 --cpuset-cpus,就相当于你告诉这位客人:"你只能去 1 号房间和 2 号房间,其他房间不准进。"
工作原理与细节:
-
作用目标 :它不限制容器使用 CPU 的比例 ,而是限制它能在哪些物理核心上运行。
-
核心编号 :CPU 核心的编号从 0 开始。例如,一个 4 核的 CPU,其核心编号就是
0,1,2,3。 -
指定方式:
-
单个核心:
--cpuset-cpus="0"(只使用第 0 号 CPU 核心) -
多个不连续核心:
--cpuset-cpus="0,3"(使用第 0 号和第 3 号 CPU 核心) -
连续范围:
--cpuset-cpus="1-3"(使用第 1, 2, 3 号 CPU 核心) -
混合指定:
--cpuset-cpus="0,2-3"(使用第 0, 2, 3 号 CPU 核心)
-
为什么要用它?(使用场景)
-
避免 CPU 资源竞争,提高性能 :
当多个繁忙的容器在同一台宿主机上运行时,它们可能会争抢同一个 CPU 核心的缓存和执行时间,导致频繁的上下文切换,降低效率。通过将容器绑定到不同的核心上,可以避免这种"争抢",让每个容器都能独享自己核心的缓存和算力,尤其对计算密集型应用(如科学计算、高频交易)性能提升显著。
-
满足特定应用需求 :
某些老旧或有特殊许可要求的软件可能被设计为只能识别特定数量的 CPU。通过 CPU 绑定可以满足这类要求。
-
精细化资源调度 :
在复杂的部署环境中,系统管理员可以精确地将重要的容器绑定到性能更好的核心上(例如,物理机上的高性能核心),而将次要的容器绑定到其他核心,实现精细化的资源调度。
话不多说,我们直接看例子,首先我们看看我们的机器有几个cpu
bash
cat /proc/cpuinfo

服务器有 2个CPU核心:
- CPU 0:processor : 0
- CPU 1:processor : 1
这两个数字 0 和 1 就是 --cpuset-cpus 参数使用的CPU编号。
接下来我们来运行一下
bash
docker run -d --name mynginx2 --cpuset-cpus="0" nginx:1.23.4-perl

其实也就是控制他只能在哪个cpu跑而已
- -m 或 --memory 参数:内存限制
这个参数非常直观,它就是用来限制容器能够使用的最大内存量 。
你可以把它想象成:
同样是那栋大房子,内存就是房子的总储物空间。
默认情况下,一个贪婪的客人(容器)可能会试图把所有储物空间都占满,导致其他客人没地方放东西。
而 -m 参数就像是你给这个客人分配了一个固定大小的储物柜,告诉他:"你的东西只能放在这个柜子里,不能用别的地方。"
工作原理与细节:
-
硬限制:这是一个硬性上限。容器内的进程使用的内存(包括物理内存和交换分区,稍后解释)绝对不能超过这个值。
-
单位:可以使用 b (B), k (KB), m (MB), g (GB) 等单位。
例如:-m 512m (512 MB), -m 1g (1 GB), -m 2g (2 GB)。
为什么要用它?(使用场景)
-
防止单个容器耗尽主机内存 :
这是最核心的作用。如果没有内存限制,一个发生内存泄漏的容器可能会像黑洞一样吸干整个宿主机的内存,导致系统变慢、崩溃,甚至影响到宿主机上运行的其他所有容器和服务。
-m参数为这种故障设置了一个"安全围栏"。 -
保证多容器环境下的公平性 :
在有多个容器共享一台宿主机的环境下,为每个容器设置合理的内存上限,可以确保所有容器都能获得其应有的资源,不会因为某个"坏邻居"而饿死。
-
规划与成本控制 :
在云环境或资源受限的环境中,精确分配内存有助于进行资源规划和成本控制。你知道每个容器最多会消耗多少内存,从而可以更合理地规划宿主机的配置。
一个简单的例子:
bash
# 运行一个容器,并限制它最多只能使用 500MB 的内存(以及默认 100MB 的 swap)
docker run -d --name mynginx3 -m 500m nginx:1.23.4-perl
如果在这个容器内运行的进程试图分配超过 500MB 的内存,那么这些进程(通常是容器内的主进程)就会被操作系统强制终止(OOM Killed)。
我们现在就来看看,先看看不加控制的

接下来我们运行docker stats mynginx3来看看它的资源使用情况

可以看到它的内存上限是1.922GB啊~
现在我们再次运行一下下面这个命令
bash
# 运行一个容器,并限制它最多只能使用 500MB 的内存(以及默认 100MB 的 swap)
docker run -d --name mynginx4 -m 500m nginx:1.23.4-perl

我们再次运行docker stats mynginx4来看看它的资源使用情况

我们发现它的上限就是500MB.
1.6.--link
这是一个在早期 Docker 版本中非常重要的功能,虽然现在已经不推荐使用了,但理解它的工作原理对于学习 Docker 网络发展史和维护旧系统仍然很有价值。
什么是 --link?
--link参数是 Docker 早期用于实现容器间通信 和服务发现 的主要机制。它的核心功能是:让一个容器能够安全地连接到另一个容器,并获取对方的相关信息。
你可以把它想象成:
在同一个宿舍楼里,有两个室友(容器):
-
室友A:
database(数据库容器) -
室友B:
webapp(网页应用容器)
--link 就像是给室友B(webapp)一张纸条,上面写着:"室友A(database)住在305房间,他的内部电话分机号是3306"。这样室友B就知道该去哪里找室友A,并且能直接打电话给他。
--link 具体做了什么?
当你执行 docker run --link <目标容器名>:<别名> ... 时,Docker 会为新建的容器(源容器),其实它的核心功能就是下面这个
网络连接
-
在两个容器之间创建一个安全的网络通道。
-
默认情况下,容器是相互网络隔离的。
--link会打破这种隔离,允许源容器直接访问目标容器的所有暴露端口,而无需将这些端口映射到宿主机。
话不多说,我们直接看例子
bash
docker run -it --name mycentos1 centos:7 bash

我们检查一下

确实是运行起来了
我们打开另外一个终端
bash
docker run -it --name mycentos2 --link mycentos1:mywebsite1 centos:7 bash
重点讲解 --link mycentos1:mywebsite1
这个参数可以拆成两部分:--link <目标容器名>:<别名>
mycentos1:
- 这是一个已经存在并且正在运行的另一个容器的名字。
- 它是我们想要连接的那个容器,我们称它为"服务容器"。
mywebsite1:
- 这是你为 mycentos1 这个目标容器起的一个别名。
- 在 mycentos2 这个新容器内部,你将通过这个名字 mywebsite1 来访问 mycentos1 容器。
建立网络连接
默认情况下,容器之间是隔离的。--link 参数会在两个容器之间建立一个安全的网络通道,允许 mycentos2 访问 mycentos1 暴露的特定端口。
我们试试看
bash
ping mycentos1

bash
ping mywebsite1

为什么可以进行通信呢?
其实我们使用--link时,系统会自动完成下面这些事情
- 在 mycentos2 容器里,系统有一个 hosts 文件(就像电话本)。
- --link 会自动在这个电话本里添加一条记录:mycentos1 的IP地址。
- 所以,在 mycentos2 里,你不需要知道 mycentos1 的具体IP地址,直接 ping mycentos1 或者用 mycentos1 这个主机名去连接它(比如在代码里连接数据库),系统会自动找到正确的IP。

咋样?理解了没?
既然这个mycentos2可以访问到这个mycentos1,那么mycentos1可不可以访问到这个mycentos2呢?
现在我们回到这个mycentos1

可以看到这个host里面没有mycentos2的信息,所以是不行的。
1.7.--rm
什么是--rm参数?
--rm参数的作用是:让容器在退出时自动清理掉容器内部的文件系统,即自动删除容器 。
你可以把它想象成:
你租用了一个临时的工作间(容器),当你完成工作离开时,物业管理自动帮你把这个工作间里的所有东西清理干净,并将工作间退租,不留下任何痕迹。而不使用 --rm 的话,就好像你离开了但工作间还保留着你的东西,需要你手动去退租和清理。
为什么需要 --rm?
Docker 容器默认的设计是:当容器退出后,容器的文件系统(包括运行过程中产生的数据)仍然保留在磁盘上,除非你手动使用 docker rm 命令来删除容器。这样做的初衷是为了让你可以查看已经停止的容器的日志、文件系统变化,或者重新启动它。
但是,在大多数临时性、一次性的任务中(比如运行一个测试、一个临时工具),我们希望容器在运行完成后就彻底消失,不留任何痕迹。这就是 --rm 的用武之地。
使用 --rm 的好处:
-
自动清理:避免磁盘空间被大量已停止的容器占用。
-
避免混乱:不需要手动清理,减少管理负担,特别是对于短期测试任务。
-
保证状态新鲜:每次运行的都是一个全新的容器,不会受到之前容器遗留数据的影响。
如何使用?
在 docker run 命令中加上 --rm 即可:
bash
docker run --rm ubuntu echo "Hello, World!"
这个命令会:
-
从
ubuntu镜像创建一个新的容器。 -
在容器内执行
echo "Hello, World!"。 -
输出完成后,容器自动退出,并且 Docker 会自动删除这个容器。
注意事项:
-
与
-d(后台运行)同时使用 :如果你同时使用
--rm和-d(让容器在后台运行),那么容器会在停止后自动删除。但是,如果容器一直在后台运行,那么它不会自动删除,直到它停止运行。 -
不能与
--restart同时使用 :当使用
--restart策略(除非是--restart=on-failure)时,Docker 会在容器退出时重新启动它,这样容器就不会退出,因此--rm也就不会生效。实际上,Docker 不允许同时使用--rm和--restart(除了on-failure的情况),因为两者是冲突的:--restart旨在保持容器运行,而--rm旨在容器退出时删除它。 -
数据卷的清理 :
--rm会删除容器内部的文件系统,但是不会删除容器所挂载的数据卷(volumes) 。这是因为数据卷是被设计用来持久化数据的,独立于容器的生命周期。如果你希望同时删除数据卷,可以使用docker rm -v命令(但--rm不会自动做这个操作)。例如,如果你这样运行:
bashdocker run --rm -v /data ubuntu echo "Hello"容器退出后,容器本身被删除,但是一个匿名卷(在
/data挂载)仍然存在。如果你希望连卷也一起删除,需要在删除容器时使用-v选项,但是--rm不会自动做这件事。所以,如果你希望自动删除卷,可能需要使用其他方法(比如在 Docker Compose 中设置volumes的自动删除)。
与不带 --rm 的对比:
不使用 --rm:
bash
docker run ubuntu echo "Hello, World!"
运行后,容器退出,但容器仍然存在。你可以用 docker ps -a 看到它,并且需要手动 docker rm 来删除。
使用 --rm:
bash
docker run --rm ubuntu echo "Hello, World!"
运行后,容器退出,并且自动被删除,docker ps -a 也看不到它。
话不多说,我们直接进行实操
首先我们先运行一个不带--rm参数的
bash
docker run -it --name mycentos3 centos:7 bash

然后我们立刻退出

现在我们查看一下

这个东西还是存在。
每次我们都需要通过手动使用来清理这些停止的容器
bash
docker stop 容器名
docker rm 容器名

其实我们可以使用--rm参数来自动清理。
接下来我们运行--rm参数的
bash
docker run -it --name mycentos4 --rm centos:7 bash

我们一运行起来就退出
我们进行查看

怎么样?是不是自动被删掉了!!!
1.8.其他参数
其实docker run还有其他参数(--volume , -v,--network等),但是我不想在这里讲,也不适合在这里讲。我们现在知道上面这些参数即可。
二.实战------搭建一个nginx服务
2.1.nginx是干啥的
想象一下,你走进一家非常火爆的餐厅 。这家餐厅就是你要访问的网站。
餐厅里的三个关键角色:
-
你(顾客) = 网站的用户(用浏览器上网的人)
-
厨师(后厨) = 应用服务器(运行着网站核心逻辑的程序,比如 PHP, Java, Python。他们"做硬菜")
-
服务员(Nginx) = Nginx 服务器
Nginx(服务员)具体负责哪些工作?
- 静态内容服务(上小菜、递菜单)
-
场景: 你一坐下,服务员马上给你递上菜单 、倒上茶水。这些"小菜"和"茶水"都是现成的,不需要后厨现做。
-
在网站中: 菜单、茶水就像网站的 CSS文件、图片、JavaScript。这些东西都是固定不变的。Nginx 处理这些请求速度极快,因为它不需要麻烦后厨(应用服务器),自己直接从"备餐台"(硬盘)拿给你就行了。
- 反向代理(接单和传菜)
-
场景: 你看完菜单,告诉服务员:"我要一个宫保鸡丁"。服务员记下你的订单,然后走到后厨窗口,把你的单子交给里面忙活的厨师。
-
在网站中: "点宫保鸡丁"这个动作,就像你点击了网站的"登录"按钮。这是一个动态请求,需要后厨(应用服务器)真正动手"炒菜"(执行程序逻辑)。Nginx(服务员)在这里的作用就是接收你的请求,然后转发给后端真正的处理者。
- 负载均衡(聪明的订单分配)
-
场景: 这家餐厅后厨不止一个厨师,而是有三个厨师(三台应用服务器)。服务员(Nginx)非常聪明。
-
他不会把所有的订单都塞给第一个厨师,累死他。
-
他会轮流把新订单给三个厨师(轮询策略)。
-
或者他知道王师傅手艺好速度快,就多给他分几个单子(加权轮询)。
-
-
在网站中: 这就是负载均衡。当成千上万人同时访问网站时,Nginx 能把请求合理地分发给后端的多个服务器,防止任何一台服务器被压垮,保证了整个餐厅(网站)的运转顺畅。
为什么需要 Nginx(服务员)?不让顾客直接进后厨吗?
想象一下,如果没有服务员(Nginx)会怎样?
-
后厨忙疯了: 顾客直接冲进后厨点单。厨师一边要炒菜,一边还要应付顾客问"有什么招牌菜?"、"我的菜做好了吗?",效率极低。
-
秩序大乱: 所有顾客都挤在后厨门口,谁先谁后?谁来维持秩序?后厨门口会被堵死。
-
安全隐患: 顾客看到了后厨脏乱差的样子(知道了服务器的真实地址和端口),不安全。
而有了 Nginx(服务员)之后:
-
厨师(应用服务器)可以专注炒菜: 他们只负责从服务员那里接单、做菜,效率更高。
-
顾客(用户)体验好: 你只需要和一个友善的服务员打交道,流程清晰快捷。
-
餐厅(网站)容量大: 一个优秀的服务员可以同时照顾好多桌客人(高并发),并且能协调多个后厨工作。
总结一下
Nginx 就是这个位于用户和后端服务器之间的"超级服务员"。
-
对于简单请求(要菜单、加水),它自己瞬间搞定。
-
对于复杂请求(点硬菜),它负责接单并传递给后厨。
-
它还负责协调多个后厨的工作,让谁也别闲着,谁也别累着。
所以,现在几乎所有的大型网站都会在门口安排一个甚至多个 Nginx 这样的"金牌服务员",来应对全球亿万用户的访问。
2.2.ubuntu搭建nginx服务
首先我们先进行安装
bash
apt install nginx -y

我们看看它有没有在运行

查看一下版本

其实我们也可以通过下面这样子的的方式来进行启动,停止nginx,以及查看nginx的状态
bash
# 启动 Nginx 服务
systemctl start nginx
# 重启 Nginx 服务(先停止再启动,会中断当前连接)
systemctl restart nginx
# 停止 Nginx 服务
systemctl stop nginx
# 查看 Nginx 服务的运行状态和最近日志
systemctl status nginx

接下来我们就访问我们的nginx首页,我们打开浏览器,输入下面这些
bash
# 如果是在本地服务器上
http://localhost
http://127.0.0.1
http://你的服务器IP地址
# 如果是在远程服务器上
http://服务器公网IP地址
访问了就是下面这样子

我们可以看看nginx的配置文件

我们进去看看
bash
vim /etc/nginx/nginx.conf

......

由于我们nginx是通过http协议来运行的,所以我们只看http部分。
我们仔细看这两个目录
- /etc/nginx/conf.d/*.conf
- /etc/nginx/sites-enabled/*

我们发现
/etc/nginx/conf.d/*.conf没有任何东西
/etc/nginx/sites-enabled/*里面有一个软连接,连接着/etc/nginx/sites-available/default
我们现在就去看看/etc/nginx/sites-available/default
bash
vim /etc/nginx/sites-available/default

把这个换成下面这样

现在我们保存一下,然后重新加载一下配置
bash
nginx -s reload

这个时候我们回到浏览器,重新刷新一下

虽然内容没有变,但是我们去下面这个目录看看

看看里面的内容
bash
vim /usr/share/nginx/html/index.html

我们修改一下下面这一行

保存退出,我们刷新一下界面

怎么样?这个页面是不是变了!!!
2.3.docker搭建nginx服务
首先我们需要nginx的镜像源啊
一般来说,我们都是去docker hub官网上面寻找的:Docker Hub Container Image Library | App Containerization
进去官网之后,直接搜索nginx


在这里我们就能选择不同版本的

我们选择一个比较靠谱的,我们这里选择nginx:1.23.4-perl


现在我们就启动一下
bash
docker run -p 8090:80 --name myweb1 -h myweb1.com -e myenv=test nginx:1.23.4-perl

现在我们去浏览器访问一下
bash
# 如果是在远程服务器上
http://服务器公网IP地址:8090

同时,我们也看到前台进程打印了一些东西

这个时候我们ctrl+c

我们去浏览器刷新一下

这就是前台进程的缺陷,我们加上-d选项
bash
docker run -d -p 8091:80 --name myweb2 -h myweb2.com -e myenv=test nginx:1.23.4-perl

我们现在去浏览器访问一下

非常完美啊!!
可是我们还是修改不了我们的界面,我们可以通过-it参数,还有修改启动命令来进行设置
bash
docker run -p 8092:80 --name myweb3 -h myweb3.com -e myenv=test -it nginx:1.23.4-perl bash
- bash: 指定容器启动时运行的命令是bash。这会覆盖镜像默认的启动命令(默认是启动nginx)。
以nginx:1.23.4-perl镜像为基础,运行一个名为myweb3的容器,设置主机名为myweb3.com,设置环境变量myenv=test,并将宿主机的8092端口映射到容器的80端口。
同时,容器启动后不运行nginx,而是运行bash shell,并保持交互式终端。
正常情况下 nginx 镜像的行为:
默认情况下,当你运行:
bashdocker run nginx:1.23.4-perl容器会:
- 自动启动 nginx 服务器
- 在后台运行
- 你无法直接与容器交互
加了 bash 之后:
bashdocker run -it nginx:1.23.4-perl bash容器会:
- 不启动 nginx 服务器
- 直接进入 bash shell(命令行)
- 你可以像在普通Linux系统中一样操作。

我们可以在这个容器里面再进行启动nginx

现在我们去浏览器看看

现在我们想要修改它的主页,我们就去
bash
ls -l /usr/share/nginx/html/

这个index就是我们网页显示的内容,我们把它修改掉
bash
echo "Hello i am in docker my port is 8092" > /usr/share/nginx/html/index.html

我们回去浏览器看看

咋样??是不是跟着修改了!!


