目标:一台云服务器,两个域名,通过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 certbotstandalone,运行独立的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