尝试一个脚本自动化部署和配置个人服务器的过程

Mussy Hu

需求

配置需求

  • 建立专门的配置文件夹,基于 Docker 部署不同的应用程序,将配置文件夹内针对不同应用的配置挂载到对应的容器内
  • 全过程仅需执行一个脚本

服务需求

  • nginx 提供基于不同域名的内网服访问
  • nps 内网穿透服务
  • 个人博客

实现

思路

一开始想到的实现思路是:

  1. 先使用 git 拉取配置仓库
  2. 调用 docker 启动容器,同时分别挂载配置文件夹

配置可以自己定制化后上传到 github,而自己需要的各种服务可以制作相应的 Docker 镜像,即可实现一个脚本部署并配置自己的个人服务器,关键点在于与此同时我想要使用 nginx 进行反向代理,使用域名区分服务。

脚本的一个简单使用过程如下:

通过网络或其它渠道获取脚本(. sh 文件),并开始执行脚本
执行后脚本拉取配置仓库到本地文件夹,使用 docker 拉取服务器镜像,如博客和内网穿透服务端
启动各镜像并将对应的配置挂载到各容器内,即可开始对外提供服务
访问不同域名即可访问到不同服务

行动

开始实现这个思路:

一,

我先在自己的服务器上验证直接用 docker 部署 nps 服务端,部署完成后发现访问不了 web 管理页面,经过检查发现没有端口映射。

在更改启动指令后,使用 docker ps 查看运行的容器状态,发现仍然没有端口映射信息。

经过检查发现是由于我的镜像是直接在云端仓库里随便找的别人的,该镜像并没有配置暴露对应端口,因此我基于该镜像自制了一个暴露 8080,80,443,8024 这四个端口的版本的镜像,运行并将容器内的 8080 端口映射到主机上的 8080 端口后

8080 端口为 nps 服务端的 web 管理页面

访问主机 ip 加该端口仍然访问不到网页,再一番测试后发现将容器内 8080 映射到 80 端口则可以成功访问,因此猜测是因为服务器防火墙是没有放行 8080 等其它端口

后续简单测试了一下按网上找的方法放行 8080 端口,仍然无效,不知道是不是方法有问题

二,

后面想到反正最后都要用 nginx 做反向代理,那只要 80 端口对外有效即可,只要 nginx 能访问到内网端口就行,因此接下来开始配置 nginx:
对 nginx 的部署我仍然采用了 docker 的方式(此处有大坑),在部署完成并映射好 80 端口后,发现能够访问到 nginx 页面,但在按教程配置好代理本地的 nps 的 web 管理服务器后,期待的效果是在浏览器输入域名能够访问到被代理的 nps 管理页面,但是一直没有效果,经过反复搜索,最终发现问题在于我的 nginx 也是容器化部署,因此 nginx 代理配置的本地端口,是容器内部的端口,而我需要被代理的 nps 服务端位于另一个容器内,因此二者完全不相及,自然没有效果。

接下来面对我的是两个解决方法,一是将 nginx 直接挪到主机上,不使用容器部署,另一个方法是寻找方法实现容器间的端口映射

第一种方法很直接,nginx 在主机上就没有什么其它问题了,只要简单的将不同容器内的端口映射到主机上就可以被 nginx 代理了.

再说第二种方法,在网络上简单查询后发现这种方法比较简单的一种实现是用 docker 建立一个网络,然后在启动容器时将其加入这个网络, 这样加入到这个网络的不同容器之间就共用同一个本地网络,就能够进行网络通信了。但这种方法的问题在于如果各个服务都位于同一个网络环境,那它们之间端口冲突的可能性就比较高,需要在部署每个应用时考虑其专门的端口配置,以防止冲突,这里的详细内容见 Docker容器网络模式

出于配置简单的考虑,我最终选择第一种方法,我感觉统一在容器的端口映射这个层面考虑端口问题比较轻松一点,第一种的缺点可能是这样就要在主机上安装 nginx,不清楚会不会影响脚本的灵活性。

三,

我先直接在服务器上测试了 nginx 通过域名反向代理 nps 的可行性,测试后发现能够访问 web 管理页面,说明反向代理这一步目前来说是可行的,我还用 nginx 代理了主机上的 8024 端口,将访问 nps.我的域名 的请求转发到本机的 8004 端口,8004 端口映射到 nps 服务端容器内的 8024 端口,这样就实现了域名代理了 nps 的 tcp 客户端连接端口。

目前来看以上实现有诸多弊端,nginx 置于宿主机上,其监听外界对不同端口的请求再转发自本机的其它端口,我的出发点是这样可以给其它容器内的服务(通常监听常用端口)映射到主机上的不常用端口,然后 nginx 再代理常用端口,通过域名区分将请求分发到不同的不常用端口,这样可以解决不同容器对主机端口的占用问题,毕竟一个端口最多只能一个服务使用。我用 nginx 代理只能解决外部访问同一个端口获得不同的服务,但不能解决内部服务的端口相同,实际上内部不同的服务必然监听不同的端口。
带来的问题很明显,映射关系较为复杂,每个容器都必须暴露自身的所有提供服务的端口,并映射到不常用端口上,然后再被 nginx 代理接受来自常用端口的访问。

先忽略各种问题,在初步尝试编写一个我理想中的脚本后,得到的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 拉取配置仓库

git clone github.com/musdrop/musdrop_conf ~/musdrop_conf

# 进入仓库目录

cd ~/musdrop_conf

# 运行 nps

docker run -d --name=nps --restart=always -p 8001:8080 -p 8002:80 -p 8003:443 -p 8004:8024 -v ./nps:/conf musdrop/nps:v2

# 安装 nginx

apt install nginx

# 建立符号链接

rm -rf /etc/nginx/conf.d

ln -s ./nginx /etc/nginx/conf.d

# 启动 nginx

service nginx start

步骤基本上就是照着思路来的,从 github 拉取自己的配置仓库,然后安装各服务,然后将目录下的配置载入各服务的配置文件夹,然后启动服务

在尝试在一台全新的服务器上运行上述脚本,就面临严重的问题,缺少 git,docker 等依赖,于是我加上了 apt-get updata, apt install git, apt install docker 等指令,运行后结果安装 git 的时候报错了,让我加上–fix-missing,而且我还发现安装过程中会要求输入 y,不过后来发现安装指令里加上-y 就可以自动输入 y,但加上以上内容后,同时我还让 ChatGPT 润色了一下,最后得到的脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/bin/bash

# 更新软件包列表

apt-get update || { echo "更新软件包列表失败"; }

# 安装必要的软件包

apt install -y git --fix-missing || { echo "安装git失败"; exit 1; }

apt install -y docker.io --fix-missing || { echo "安装docker失败"; exit 1; }



# 拉取配置仓库

git clone https://github.com/musdrop/musdrop_confs.git ~/musdrop_confs || { echo "拉取配置仓库失败"; exit 1; }



# 进入仓库目录

cd ~/musdrop_confs || { echo "进入仓库目录失败"; exit 1; }



# 运行 nps

docker run -d --name=nps --restart=always \

  -p 8001:8080 -p 8002:80 -p 8003:443 -p 8004:8024 \

  -v $(pwd)/nps:/conf musdrop/nps:v2 || { echo "运行nps失败"; exit 1; }



# 安装nginx

apt install -y nginx --fix-missing || { echo "安装nginx失败"; exit 1; }



# 建立符号链接

rm -rf /etc/nginx/conf.d || { echo "删除默认配置失败"; exit 1; }

ln -s $(pwd)/nginx /etc/nginx/conf.d || { echo "创建符号链接失败"; exit 1; }



# 启动nginx

service nginx start || { echo "启动nginx失败"; exit 1; }



echo "服务器初始化完成!"

然后我不幸的发现安装的时候又爆了其它错误,明明之前安装 git 的时候报错让我尝试加上–fix-missing,但是这次又让我尝试加上别的,更奇怪的是我发现明明 git 已经被安装了(能用指令查到版本),却仍然报错退出了脚本执行。
考虑到指令执行过程中的报错过于常见(由于各种问题),而且我无法进行出错处理,导致这个脚本的运行成功率较低,因此暂时先不考虑这个自动化部署的脚本了。

四,

我开始测试 nps 的可用性,最终发现自己没有放开服务器的 8024 端口导致白忙活半天

除了服务器的防火墙以外,还要在云服务控制台页面放开相应端口

放开端口也连不上,捣鼓半天是版本问题,客户端与服务端版本对不上,对的上的似乎又版本太老还是咋地启动不了,遂放弃。

经过沉淀决定将任务重心转换到以下几点来

  1. 通过对 docker 网络模式的学习,好奇能否通过将 nginx 容器设为 host 模式,同时将其与其它服务器加入同一个自定义 bridge 网络实现 doker 对各服务的访问,这样就不用给容器配置繁琐的端口映射了
  2. 如果上诉可行便可将 nginx 也使用 docker 部署而不用置于宿主机之上
  3. 由于目前使用的 nps 镜像内的 nps 服务端版本过老,因此准备自己动手制作一个新版本的 nps 服务镜像

五,

对于第三点,直接在 docker 官方又找了几个镜像发现有最新版的 nps,不过还发现了一个 2.6.20 的版本的 nps 服务端,但我在 github 上明明看到最新版是 2.6.10,不知道这个 2.6.20 是 2.6.2 多写了一个 0 还是是其它人维护的新版本,为了稳妥起见我选择了 2.6.10 版本并制作了暴露相应端口的镜像。

对于一二两点,再尝试后发现 nginx 用 docker 部署并启用 host 模式确实是可行的方案,最起码能代替直接在宿主机上安装 nginx,但是缺点是 host 模式的容器无法再加入自定义的 bridge 网络,也就是说我的第一点的思路没办法实现。

一开始测试时我在自己电脑上想先验证一下第一点,结果设为 host 模式的容器压根访问不了,网上查了后才知道 host 模式只在 linux 上有效,在 Docker Desktop 上是不支持的。

所以目前为止实现效果是:
使用 docker 部署 nginx 和 nps,nginx 设为 host 模式,监听主机所有对外提供服务的端口,代理到其它不常用端口,而其它服务的容器则需将自己内部提供服务的端口映射到主机不常用端口,nginx 对同一个常用端口使用域名区分服务转发到不同的不常用端口。
在这些变动之后我更新了自己的脚本和配置文件夹
目前的脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash

# 更新软件包列表
apt-get update || { echo "更新软件包列表失败"; }

# 安装必要的软件包
apt install -y git --fix-missing || { echo "安装git失败"; exit 1; }
apt install -y docker.io --fix-missing || { echo "安装docker失败"; exit 1; }

# 拉取配置仓库
git clone https://github.com/musdrop/musdrop_confs.git ~/musdrop_confs || { echo "拉取配置仓库失败"; exit 1; }

# 进入仓库目录
cd ~/musdrop_confs || { echo "进入仓库目录失败"; exit 1; }

# 运行nginx
docker run -d --name=nginx --restart=always -v $(pwd)/nginx:/etc/nginx/conf.d nginx:stable-perl || { echo "运行nps失败"; exit 1; }

# 运行 nps
docker run -d --name=nps --restart=always \
-p 8001:8080 -p 8002:80 -p 8003:443 -p 8004:8024 \
-v $(pwd)/nps:/conf musdrop/nps:v2 || { echo "运行nps失败"; exit 1; }

# 启动nginx
service nginx start || { echo "启动nginx失败"; exit 1; }

echo "服务器初始化完成!"

后续内容主要集中在对内网穿透的服务器的搭建,详见搭建nps服务器和frp服务器的尝试过程

  • 标题: 尝试一个脚本自动化部署和配置个人服务器的过程
  • 作者: Mussy Hu
  • 创建于 : 2024-12-18 00:00:00
  • 更新于 : 2024-12-19 20:47:20
  • 链接: https://blog.musdrop.com/2024/12/18/尝试一个脚本自动化部署和配置个人服务器的过程/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
目录
尝试一个脚本自动化部署和配置个人服务器的过程