Docker配置ngnix,实现同服务器ip,多域名映射多站点
本文首发于 慕雪的寒舍
1.说明
一般情况下,我们的域名映射到ip后,默认访问的是80端口。如果你的服务器只部署了一个服务,这样也是够用的。
但是很多项目对性能的占用并没有那么夸张,一个服务器一个站点未免有些浪费了。虽然我们可以用域名:端口
来访问,但是这样对于用户来说并不友好,对于强迫症来说看着很不舒服🤣
这时候,就需要配置反向代理来实现不同域名到服务器不同端口的映射。
1.1 反向代理
你可以理解为,反向代理是服务器的一个中间商,其能将80端口的,不同域名来源的请求,导向到服务器上的不同端口
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的方式,根据你的系统,自行百度
docker pull nginx
2.1 配置
启动之前,先在你的当前路径下创建一个文件夹(我这里是root用户)
mkdir /root/docker/ngnix
随后用下面的命令启动nginx容器
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的初始页面
3.编辑配置文件
nginx.conf
配置文件我们直接用官方默认的就行,这里主要对站点的配置文件做说明;
3.1 https
如果不需要https加密,可以用下面的配置文件来操作,当使用test.com
访问你的云服务器ip时,会被转到4000
端口
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/
目录,将证书文件放到该目录下即可
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镜像和容器的项目,还是很不错的;缺点就是只有英文,想要中文可以配置中文包,但是中文包已经非常非常久没有更新了,索性直接用英文版
docker run -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 \
-d portainer/portainer