安装
- 我用的ubuntu,源码安装,下载源码后解压
- 进入刚才解压得到的文件夹
- 执行./configure --prefix=/usr/local/nginx, --prefix是配置安装目录
- 如果上一步报错,可能是缺少依赖或编译器,执行sudo apt-get install gcc libpcre3-dev zlib1g-dev,执行时ubuntu可能报错:有几个软件包无法下载,要不运行 apt-get update 或者加上 --fix-missing 的选项再试试?此时需执行sudo apt-get update后再执行刚才的命令
- 执行su -切换到root用户(因sudo也不行),进入第二步的文件夹,执行make && make install
- 进入/usr/local/nginx/sbin,执行sudo ./nginx启动nginx(已退出root用户,若未退出不用加sudo),可通过执行ps -ef | grep nginx查看是否启动成功
- 浏览器进入127.0.0.1,看是否有nginx默认页面
配置
一.将nginx添加到系统服务
如果安装的步骤做完后拍了快照,或者重启,那在进行这里的配置前最好再做一次安装中的第六步,否则可能出现下面的问题:
- 做完配置的第四步,执行service nginx status显示未运行,执行ps -ef | grep nginx的结果里也没master process和worker process字样,nginx默认页面打不开
- 接着执行service start nginx,然后service nginx status显示已运行,但再执行ps -ef | grep nginx的结果里仍没master process和worker process字样,nginx默认页面打不开
解决方法如前所说,因执行sudo ./nginx后,再执行ps -ef | grep nginx的结果里有master process和worker process字样,有这两项才能访问nginx默认页面。
- 在/etc/init.d目录内添加名为nginx的文件(添加和编辑都加sudo),内容如下
-
#!/bin/sh # # nginx Start up the nginx server daemon # # chkconfig: 2345 55 25 # Description: starts and stops the nginx web server # ### BEGIN INIT INFO # Provides: nginx # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Description: starts and stops the nginx web server ### END INIT INFO # To install: # copy this file to /etc/init.d/nginx # shell> chkconfig --add nginx (RedHat) # shell> update-rc.d -f nginx defaults (debian) # To uninstall: # shell> chkconfig --del nginx (RedHat) # shell> update-rc.d -f nginx remove PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin NAME=nginx DAEMON=/usr/local/nginx/sbin/$NAME CONFIGFILE=/usr/local/nginx/conf/$NAME.conf PIDFILE=/usr/local/nginx/logs/${NAME}.pid ULIMIT=10240 set -e [ -x "$DAEMON" ] || exit 0 do_start() { echo "Starting $NAME ..." ulimit -SHn $ULIMIT $DAEMON -c $CONFIGFILE } do_stop() { echo "Shutting down $NAME ..." $DAEMON -s stop } do_reload() { echo "Reloading $NAME ..." $DAEMON -s reload } case "$1" in start) [ ! -f "$PIDFILE" ] && do_start || echo "nginx already running" echo -e ".\ndone" ;; stop) do_stop || echo "nginx not running" echo -e ".\ndone" ;; reload) do_reload || echo "nginx not running" echo -e ".\ndone" ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|reload}" >&2 exit 1 ;; esac exit 0
- 进入/etc/init.d,给文件添加可执行权限,sudo chmod +x nginx
- 添加开机自启,并注册到系统服务中,sudo update-rc.d nginx defaults,其实是将刚才的nginx脚本在不同的运行模式启动脚本目录创建软链接(详情在服务添加.wmv中)。如果报错The disable|enable API is not stable and might change in the future.就将命令手打一遍再执行,多试几次,或者重启,复制粘贴后整条命令处于白色状态,再回车执行可能报这个错,第七条的命令也是
- 做了上一步后才能用service nginx [start | stop | restart | status],查看服务状态也可以用sudo systemctl status nginx
- 若之前添加的nginx脚本内容有更新,之后需执行sudo systemctl daemon-reload,使系统重新加载init.d内的脚本
- 若想删除手动添加的服务,执行sudo update-rc.d -f nginx remove
通过系统管理(执行过第四步后也可以这样管理nginx)
- systemctl status nginx 查看nginx状态
- systemctl start nginx 启动nginx服务
- systemctl stop nginx 关闭nginx服务
- systemctl enable nginx 设置开机自启
- systemctl disable nginx 禁止开机自启
二.初级网站配置(这里执行命令时加sudo)
- 进入/usr/local/nginx/conf,在nginx主配置文件nginx.conf的最后一个大括号的前面添加include vhost/*.conf;
- 进入/usr/local/nginx/conf,创建vhost文件夹,sudo mkdir vhost,v表示virtual
- 在vhost文件夹中创建一个新的虚拟主机配置文件,名字为网址+.conf,使人知道是哪个网站的配置文件,如sudo vim www.blog.com.conf
- 里面写上一个server,即代表一个虚拟主机(一个网站),内容如下
-
server { listen 80; server_name www.blog.com blog.com; # 写上blog.com可以在访问时不加www. location / { root html/blog; # 网站的代码文件的位置,后面的步骤会创建这个目录 index index.html; # 默认显示的页面 } }
- 在/usr/local/nginx/html目录内创建blog文件夹,blog里创建index.html,内容写Hello World,这两项对应上面代码里的配置
- 重启nginx,使配置文件生效
- 用配置文件里的域名访问网站,默认显示刚才创建的index.html里的内容,即Hello World。若域名无法解析,执行sudo vim /etc/hosts,在里面添加域名,使之解析到本地
三.进阶网站配置
进入/usr/local/nginx/html/blog,创建blog.py
from flask import Flask
app=Flask(__name__)
@app.route('/')
def index():
return 'Hello Flask'
if __name__=='__main__':
app.run()
若用虚拟环境,切换到虚拟环境,安装uwsgi(flask的runserver用的自带的测试服务器,正式上线不能用测试服务器),安好后输入uw按tab会自动补全。
(还是注意虚拟环境)使用uwsgi --http 127.0.0.1:5000 --wsgi-file blog.py --callable app启动项目,访问域名显示Hello World,用127.0.0.1:5000访问显示Hello Flask。这是以http协议启动uwsgi,下面是以socket协议启动uwsgi。无论以哪种协议启动,及是否使用配置文件(见第四部分),启动前都需先进入项目所在目录,如blog.py所在目录,再执行启动代码。若uwsgi装在虚拟环境里,还需先切换到虚拟环境。
进入/usr/local/nginx/conf/vhost修改配置文件,再重启nginx
server {
listen 80;
server_name www.blog.com blog.com; # 写上blog.com可以在访问时不加www.
location / {
# 下面是以http协议启动uwsgi用的
# root html/blog; # 网站的代码文件的位置,后面的步骤会创建这个目录
# index index.html; # 默认显示的页面
# 下面是以socket协议启动uwsgi用的
include uwsgi_params; # /usr/local/nginx/conf/uwsgi_params里是请求带的参数,为了防止出错可以写绝对路径
uwsgi_pass 127.0.0.1:5000; # 将所有的请求转发到这里,由于上一行引入了参数,所以转发请求时带参数
}
}
(还是注意虚拟环境)使用uwsgi --socket 127.0.0.1:5000 --wsgi-file blog.py --callable app启动项目,访问域名显示Hello Flask,不知道为什么访问不了127.0.0.1:5000,火狐显示连接被重置,所以可能是配置文件里又将这个地址转给它自己的原因。
若是CentOS,需执行yum install uwsgi-plugin-python,再uwsgi --socket 0.0.0.0:5000 --plugin python --wsgi-file blog.py --callable app,否则报错,--plugin python是告诉uWSGI在使用python插件。参考链接1,参考链接2,参考链接3,参考链接4
uwsgi: unrecognized option '--wsgi-file'
getopt_long() error
无论以哪种协议启动(注意不同协议对应的配置文件里的配置不同,还有防火墙设置),写0.0.0.0:5000可以使所有人能访问这个网站,前提是有公网IP,或访问者与服务器处于同一局域网内(访问内网IP,且需在server_name后添加内网服务器ip)。
执行流程:
- 客户端到服务器(nginx):浏览器访问域名,请求到达nginx。由于设置了host,将域名解析到本地,所以去nginx主配置文件(含引入的配置文件)里找是哪个server监听了这个域名,找到后把请求交给它。
- 服务器到uWSGI:由于这个server设置了把80端口(如果有https那也写上443)来的数据转发到127.0.0.1:5000,就再看谁监听这个地址和端口,由于用uwsgi启动项目时设置了监听这个地址和端口,所以请求以socket协议转发到了uwsgi。
- uWSGI到web框架:uwsgi解析请求,将请求和带的参数交给启动时设置的对象,这个对象是web框架里的。如前面是交给blog.py中的app对象。
uwsgi启动参数
- http # 采用http协议启动
- socket # 采用socket协议启动
- wsgi-file # 将数据交给哪个模块(文件)处理
- callable # 模块(文件)里具体可调用的对象,该对象处理接收到的(客户端发来的)请求
- chdir # uwsgi启动后的当前目录,也就是项目所在文件夹
- daemonize # 后台运行,需要指定一个日志文件,且文件要有相应权限。不后台运行的话会占用一个终端窗口,这个窗口无法继续输入其他命令,ctrl+c除外
- processes # 指定程序运行的进程数
- threads # 指定程序运行的线程数,如异步发邮件时不能为1
- pidfile # 指定一个文件,里面是uwsgi的进程号,停止运行uwsgi时用到这个文件
四.高级网站配置
前面用uwsgi启动项目,命令太长,可以用配置文件启动。在/usr/local/nginx/html/blog新建uwsgi.ini
[uwsgi]
socket=127.0.0.1:5000 # 若需除本机外的机器访问,写成0.0.0.0:5000
wsgi-file=blog.py
callable=app
daemonize=/var/log/uwsgi.log # 因其他log也在这个目录,所以将uwsgi的设在这里
pidfile=uwsgi.pid # 最好在启动uwsgi前手动创建这个文件,并给予666权限,否则可能因权限原因无法自动创建这个文件
执行sudo touch /var/log/uwsgi.log和sudo chmod 666 /var/log/uwsgi.log,创建文件并给予读写权限。试了660不行,uwsgi启动不了,报权限错误,可能是因为执行ll uwsgi.log显示root root,而uwsgi可能不属于root用户与组。权限相关参考链接1,参考链接2,参考链接3。
执行sudo touch /usr/local/nginx/html/blog/uwsgi.pid和sudo chmod 666 /usr/local/nginx/html/blog/uwsgi.pid,原因在前面注释里。
权限的三个数字分别对应文件所有者的权限、与文件所有者同用户组的用户的权限、其他用户的权限。具体数值,如1x2^2+1x2^1+0x2^0=6
- - - - 0 0 0 0
- - - x 0 0 1 1
- - w - 0 1 0 2
- - w x 0 1 1 3
- r - - 1 0 0 4
- r - x 1 0 1 5
- r w - 1 1 0 6
- r w x 1 1 1 7
用uwsgi [--ini] uwsgi.ini启动,配置文件也可以写绝对路径,防止出错。无论是否用绝对路径,启动前都需先进入项目所在目录,如blog.py所在目录,再执行启动代码。若uwsgi装在虚拟环境里,还需先切换到虚拟环境。访问域名显示Hello Flask,不知道为什么访问不了127.0.0.1:5000,火狐显示连接被重置,所以可能是配置文件里又将这个地址转给它自己的原因。
用uwsgi --stop uwsgi.pid停止运行uwsgi。
用uwsgi --reload uwsgi.pid重启uwsgi。参考链接
五.静态文件的处理
没有必要将所有的请求都转发给uWSGI,如请求静态文件时即便将请求转发过去,返回的还是这个静态文件,并未对它做其他处理,所以设置访问静态文件时不转发,直接返回给客户端(浏览器)。
进入/usr/local/nginx/conf/vhost修改配置文件
server {
listen 80;
server_name www.blog.com blog.com; # 写上blog.com可以在访问时不加www.
location / {
# 下面是以http协议启动uwsgi用的
# root html/blog; # 网站的代码文件的位置,后面的步骤会创建这个目录
# index index.html; # 默认显示的页面
# 下面是以socket协议启动uwsgi用的
include uwsgi_params; # /usr/local/nginx/conf/uwsgi_params里是请求带的参数,为了防止出错可以写绝对路径
uwsgi_pass 127.0.0.1:5000; # 将所有的请求转发到这里,由于上一行引入了参数,所以转发请求时带参数
}
location /static { # 路由转发时遵循最大前缀匹配规则,如访问的路由中有/static时不会匹配到前面写的location / {},而是匹配这里的location /static {}
root html/blog; # static目录内是静态文件,无需转发,所以直接由nginx返回给客户端(浏览器)
# alias html/blog/static; # 也可以这样写
}
}
进入/usr/local/nginx/html/blog创建static文件夹,在里面放入一张图片,再重启nginx
启动uwsgi,访问域名/static/图片文件名,如www.blog.com/static/1.jpeg,显示图片。
附
根据上面的配置,我在虚拟机ubuntu里搭建好了,内网设备都能通过ubuntu的ip访问网站,也能直接访问域名(需修改本地hosts,使域名解析到ubuntu ip)。但放在新买的腾讯云CentOS却不行(已放行端口),不能通过服务器公网ip访问(可能当时已经在server_name处写了服务器公网ip,写这句时记不清当时的情况了,总之当时尝试了很久都不行),可我看的2020年的视频,里面是阿里云,就能直接通过服务器ip访问,不知道视频里的服务器是否已备案,反正到这里我的未备案。然后把配置文件放在别人的腾讯云服务器(有域名,已备案)上,能通过域名访问,于是我买了域名并备案,备案通过后我也能通过域名访问了。由于我用宝塔配置的腾讯云,配置时没设置将ip指向哪个网站,所以不能通过服务器ip访问,宝塔会提示没有找到对应的站点。