Docker配置ngnix,实现同服务器ip,多域名映射多站点

1.说明

一般情况下,我们的域名映射到ip后,默认访问的是80端口。如果你的服务器只部署了一个服务,这样也是够用的。

但是很多项目对性能的占用并没有那么夸张,一个服务器一个站点未免有些浪费了。虽然我们可以用域名:端口来访问,但是这样对于用户来说并不友好,对于强迫症来说看着很不舒服🤣

这时候,就需要配置反向代理来实现不同域名到服务器不同端口的映射。

1.1 反向代理

你可以理解为,反向代理是服务器的一个中间商,其能将80端口的,不同域名来源的请求,导向到服务器上的不同端口

1
2
3
www.example.com 指向 8080端口
aaa.example.com 指向 3000端口
这两个域名都映射到服务器公网ip 114.514.8.8

当你访问www.example.com时,请求的是114.514.8.8:80端口,也就是反向代理的服务。此时反向代理能知道你的来源是www.example.com,于是就把你带到了8080端口的服务上;

同理,访问aaa.example.com时,就会被带到3000端口。


这里用nginx作演示,nginx是最常用的反向代理服务

2.docker安装nginx

本文参考:https://www.jianshu.com/p/6b317192480c

用其他方式还得整一大堆依赖项,这里直接用docker,方便又快捷;

服务器安装docker的方式,根据你的系统,自行百度

1
docker pull nginx

2.1 配置

启动之前,先在你的当前路径下创建一个文件夹(我这里是root用户)

1
mkdir /root/docker/ngnix

随后用下面的命令启动nginx容器

1
2
3
4
5
6
docker run \
--name=ngx \
-p 80:80 -p 443:443 \
-v /root/docker/nginx/conf.d:/etc/nginx/conf.d \
-v /root/docker/nginx/cert:/etc/nginx/cert \
-d nginx

对一些参数进行说明

  • -p命令映射端口,将80端口映射给服务器的80端口(右侧容器端口,左侧本地端口
  • -v命名映射目录,将本地的/root/nginx/conf.d映射到docker里面的/etc/nginx/conf.d 这是nginx的配置文件路径
  • --name设置容器的名字,和镜像名字无关

安装完成后,打开云服务器的ip,就能看到nginx的初始页面

image-20230125144452198

3.编辑配置文件

nginx.conf 配置文件我们直接用官方默认的就行,这里主要对站点的配置文件做说明;

3.1 https

如果不需要https加密,可以用下面的配置文件来操作,当使用test.com访问你的云服务器ip时,会被转到4000端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
listen 80; # 监听80端口
server_name test.com; # 自己的域名

location / {
# 设置缓冲区大小
proxy_buffer_size 64k;
proxy_buffers 32 32k;
proxy_busy_buffers_size 128k;

proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 需要代理的地址:端口(因为是docker部署的,需要填公网ip)
proxy_pass http://IP:4000;
}
}

3.1.1 关于proxy_pass

这里必须要注意一下proxy_pass

因为我们的nginx是用docker部署的,此时你填 127.0.0.1或localhost,实际上访问的都是nginx这个docker内部的端口,是没有用的,会弹出502 gateway报错!

正确的办法就是填云服务器的公网ip+端口

3.2 https

配置https如下,这样配置会将80端口的http访问强制转成https

域名的证书可以在域名提供商里面申请,腾讯云支持申请单域名1年的免费证书。还可以去joyssl,申请90天的域名通配符证书

因为在启动docker容器的时候,我配置了路径映射,证书配置的cert/对应的其实是 /root/docker/nginx/cert/目录,将证书文件放到该目录下即可

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
server {
listen 443 ssl;
server_name img.text.top; # 域名
# 注意文件位置,是从/etc/nginx/下开始算起的
ssl_certificate cert/img.text.top.crt; # 域名证书文件crt
ssl_certificate_key cert/img.text.top.key; # 域名证书key
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;

client_max_body_size 1024m;

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header Upgrade-Insecure-Requests 1;
proxy_set_header X-Forwarded-Proto https;

# 因为是docker部署的nginx,所以要填云服务器公网ip
proxy_pass http://云服务器公网IP:端口;
}
}
## 强制重定向
server {
listen 80; # 监听80端口
server_name img.text.top; # 域名
#把http的域名请求转成https
return 301 https://$host$request_uri;
}

修改配置文件后重启nginx的容器,即可正常访问


更多:用portainer管理docker

portainer是一个图形化管理docker镜像和容器的项目,还是很不错的;缺点就是只有英文,想要中文可以配置中文包,但是中文包已经非常非常久没有更新了,索性直接用英文版

1
2
3
4
5
6
7
8
docker run -d \
-p 14730:9000 \
-p 14729:8000 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /root/docker/portainer/data:/data \
portainer/portainer