测试-nginx挂载两个域名

    目标:一台云服务器,两个域名,通过nginx,分别指向同服务器上的两个Django网站,并分别配置ssl证书。

    先下载nginx:

yum -y install openssl openssl-develyum -y install gcc pcre-devel zlib zlib-develwget-P /usr/src./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_modulemake && make install

熟悉的欢迎界面

    配置nginx服务脚本,方便控制nginx

vim /usr/lib/systemd/system/nginx.service[Unit]#zhangxiaofeiDescription=The nginx HTTP and reverse proxy serverAfter=network.target remote-fs.target nss-lookup.target[Service]Type=forkingPIDFile=/usr/local/nginx/logs/nginx.pid# Nginx will fail to start if nginx.pid already exists but has the wrong# SELinux context. This might happen when running `nginx -t` from the cmdline.# ?id=ExecStartPre=/usr/bin/rm -f /usr/local/nginx/logs/nginx.pidExecStartPre=/usr/local/nginx/sbin/nginx -tExecStart=/usr/local/nginx/sbin/nginxExecReload=/bin/kill -s HUP $MAINPIDKillSignal=SIGQUITTimeoutStopSec=5KillMode=mixedPrivateTmp=true[Install]WantedBy=multi-user.targetsystemctl daemon-reload # 重启以生效

配置elinks,无缓存测试

yum install elinks lynxelinks ip -source

重温nginx系列学习文章

Nginx源码编译安装及配置文件初步学习

Nginx作为web服务器的功能以及虚拟主机的作用

Nginx反向代理、限速、url重写

Nginx优化

Nginx如何制作缓存\镜像服务器?

Nginx构建高可用集群,实现负载均衡应对高并发

    两个域名均以A记录类型指向测试服务器IP 111.22.44.121(下称X)。将TTL设置为最短600,方便快速生效。

    分别测试两个域名,可以看到已经生效

elinks *****b.com -sourceelinks *****3.com -source

    

    开始制作两个测试html文件,分别命名为WEB1,WEB2

cd /usr/local/nginx/htmlmkdir web1 web2echo "web1" > web1/index.html; echo "web2" >web2/index.html

    配置nginx文件server段,为了测试方便,我是直接在nginx.conf文件上进行修改,大概在34行左右,我将原有server段修改如下,并增加了一个server段

server{listen 80;    server_name domain1.com;location /{root html/web1;index index.html;    }}server {listen 80;    server_name  domain2.com;location /{root html/web2;indexindex.html index.htm;}}

/usr/local/nginx/sbin/nginx -t

显示syntax is ok,那么可以重启nginx服务了。

systemctl restart nginx.service

    此时在服务器上,测试如下

elinks host1.com -sourceelinks host2.com -source

    到这里,基本就可以确定,不同的域名可以解析到同一台云服务器上(单一公网IP),利用nginx对80端口的监听,分配到不同的网页内容,这也是预料之中的,不然nginx如何与如日中天的Apache抗衡呢。

通过uwsgi挂载不同项目

首先,需要制作一个测试的django项目。为了仿制正式环境,还是配置了一个python的虚拟环境,因为我的服务器版本比较高,centos8.2,所以如下命令安装比较顺畅,如果出现一些问题,可以参考一下Django框架搭建的网站上线小测试中虚拟环境配置问题

pip3 install virtualenvwrappervim /etc/profile# 在末尾加入以下内容VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3export WORKON_HOME=$HOME/.virtualenvssource /usr/local/bin/virtualenvwrapper.sh# 保存后让其生效source /etc/profile

    创建虚拟环境

mkvirtualenv web-3; mkvirtualenv web-b;lsvirtualenv

    分别在两个虚拟环境中配置Django

pip install django==3.1.7

    在本地创建一个django项目,待会第二个项目类似,这里主要是测试nginx与uwsgi的对接

django-admin startproject domainB

打开url配置文件,将其完全改写如下

cd domainB/domainBvim urls.pyfrom django.urls import pathfrom django.http import HttpResponsedef index(request):return HttpResponse("domain ****B")urlpatterns = [path(, index),]

    第二个项目

django-admin startproject domain3

    只需要修改上方的HttpResponse内容,方便待会测试区分

def index(request):    return HttpResponse("33333  domain")

    这样我就得到了两个可以用于测试的django项目,将其传到云服务上的srv目录下,方便待会指定路径

ls /srv/>> domain3domainB

    安装、配置uwsgi(uwsgi必须安装在系统级别的Python环境中)

pip install uwsgi

报错如下:

我的python版本

Python 3.6.8 (default, Mar 19 2021, 05:13:41)

安装相关依赖如下:

yum install gcc python36-devel

再次安装uwsgi即可。

    测试uwsgi是否正常工作,我当前所在路径

/srv/domain3uwsgi --http :8000 --module domain3.wsgi --venv=/root/.virtualenvs/web-3

‍‍    几个注意事项,http和:8000之间有空格,domain3.wsgi的是wsgi.py文件所在的文件夹名(别瞎改名),而--venv指向的是虚拟环境所在路径。

    这个时候访问服务器公网IP的8000端口,应该可以看到网页内容

elinks :8000 -source33333domain

    如果你想在公网进行访问,记得修改django项目配置文件的ALLOWED_HOSTS

ALLOWED_HOSTS = ["*"]

    可以看到uwsgi正常工作,由于这一长串的参数启动比较麻烦,所以,写一个ini配置文件来启动,当前目录/srv/domain3

touch demo1.inivim demo1.ini[uwsgi]chdir = /srv/domain3module = domain3.wsgihttp = :8000home = /root/.virtualenvs/web-3

接下来启动配置文件,网站可以正常访问

uwsgi demo1.ini

那么配置文件已经配置成功,修改配置文件,将内部通讯换成更为高效的sock文件:

[uwsgi]chdir = /srv/domain3module = domain3.wsgi#http = :8000home = /root/.virtualenvs/web-3master= true# 最大数量的工作进程processes = 4# socket文件路径,绝对路径,会自动创建socket= /srv/domain3/domain3.sock# 设置socket的权限chmod-socket= 666# 退出的时候是否清理环境vacuum= true

    依葫芦画瓢,制作第二个项目的ini配置文件

cp /srv/domain3/demo1.ini /srv/domainB/demo2.ini[uwsgi]chdir = /srv/domainBmodule = domainB.wsgihome = /root/.virtualenvs/web-bmaster= trueprocesses = 4socket= /srv/domainB/domainB.sockchmod-socket= 666vacuum= true

    开始配置nginx配置文件,将之前配置的两个测试server删除掉

html{upstream demo1site {# 设定目录自动创建,即ngnix和uwsgi通讯的sock位置# 一定要和demo1.ini中定义的socket一致server unix:///srv/domain3/domain3.sock;}upstream demo2site {server unix:///srv/domainB/domainB.sock;}server{listen 80;server_name *****b.com;# 最后,发送所有非静态文件请求到django服务器location / {# 这个uwsgi_pass对应的参数一定要和upstream定义的一样uwsgi_passdemo1site;# uwsgi_params文件地址include /usr/local/nginx/conf/uwsgi_params;      }}server {listen 80;server_namez***3.com location / {uwsgi_passdemo2site;include /usr/local/nginx/conf/uwsgi_params; }    }}

    配置完成之后,重启nginx,并启动uwsgi

uwsgi demo1.iniuwsgi demo2.ini

    访问两个域名,成功返回了各自网站的内容

    但是这样还有点小问题,就是两个网站的日志混杂在一起,检查起来不是很方便,所以可以考虑将日志处理一下,在原来的nginx的配置文件http段中,增加一行包含代码

mkdir conf.dvim nginx.confinclude conf.d/*.conf;

在conf.d目录下新建web1.conf和web2.conf文件,web1.conf文件如下

log_formatmain$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer"     "$http_user_agent" "$http_x_forwarded_for";upstream demo1site {server unix:///srv/domain3/domain3.sock;}server{listen 80;server_name ****b.com;    access_log  logs/web1.access.log  main;location / {uwsgi_passdemo1site;include /usr/local/nginx/conf/uwsgi_params;}}

web2.conf

upstream demo2site {server unix:///srv/domainB/domainB.sock;}server{listen 80;server_name ****3.com;access_loglogs/web2.access.logmain;location / {uwsgi_passdemo2site;include /usr/local/nginx/conf/uwsgi_params;}}

可以看到,两个域名的日志不再混杂了

    配置supervisor控制uwsgi。

pip3 install supervisor

    创建配置文件,只需一个supervisord进程可控制多个django项目

echo_supervisord_conf > demo_supervisor.confvim demo_supervisor.conf

主要是命名需要注意,需要保存日志的话,需要提前创建日志目录

[program:web1]command=uwsgi --ini demo1.inidirectory=/srv/domain3stdout_logfile=/srv/domain3/log/s.logstderr_logfile=/srv/domain3/log/err.log [program:web2]command=uwsgi --ini demo2.inidirectory=/srv/domainBstdout_logfile=/srv/domainB/log/s.logstderr_logfile=/srv/domainB/log/err.log

接下来就可以正常启动、管理项目了

supervisord -c demo_supervisor.confsupervisorctl -c demo_supervisor.conf

为多个网站申请SSL证书

    照例,还是使用python的方法。由于之前我在测试,80端口一直是只对固定IP开放,但申请证书必须全部放开(80,443)

pip install certbot

    standalone,运行独立的Web服务器进行身份验证;-d,DOMAINS,以逗号分隔的域列表,以获取证书;certonly,获取或续订证书

certbot certonly --standalone -d example.com -d www.example.com

    按照要求申请完证书,再来配置nginx配置文件,web1.conf文件如下

log_formatmain$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer"       "$http_user_agent" "$http_x_forwarded_for";upstream demo1site {server unix:///srv/domain3/domain3.sock;}server{listen 80;server_name ****b.com;    rewrite ^(.*) https://$host$1 permanent;}server {listen 443 ssl;  server_name ****b.com;access_loglogs/web1.access.logmain;  ssl_certificate      /etc/letsencrypt/live/****3.com/fullchain.pem;  ssl_certificate_key  /etc/letsencrypt/live/****3.com/privkey.pem;ssl_protocols TLSv1.3;ssl_session_cacheshared:SSL:1m;  ssl_session_timeout  5m;location / {uwsgi_passdemo1site;include /usr/local/nginx/conf/uwsgi_params; }}

web2.conf文件最终配置如下

upstream demo2site {server unix:///srv/domainB/domainB.sock;}server{listen 80;server_name ****3.com;rewrite ^(.*)permanent;}server {listen 443 ssl;server_name ****3.com;access_loglogs/web2.access.logmain;  ssl_certificate      /etc/letsencrypt/live/****3.com/fullchain.pem;  ssl_certificate_key  /etc/letsencrypt/live/****3.com/privkey.pem;ssl_protocols TLSv1.3;ssl_session_cacheshared:SSL:1m;  ssl_session_timeout  5m;location / {uwsgi_passdemo2site;include /usr/local/nginx/conf/uwsgi_params; }}

重启nginx

测试完成!

参考:

https://stackoverflow.com/questions/29640868/compile-failed-with-error-code-1-in-tmp-pip-build-root-uwsgi