利用nginx的fastcgi_cache缓存加速WordPress

WordPress有很多的缓存加速方案,例如插件缓存(wp-super-cache、wp-rocket等)、PHP代码缓存等等,现分享本站使用的nginx缓存。利用fastcgi_cache缓存。

未分类

在使用nginx缓存之前,必须在nginx里面加载专门的模块,这个模块叫做ngx_cache_purge。

添加ngx_cache_purge模块

下载ngx_cache_purge模块

ngx_cache_purge模块的官方地址:http://labs.frickle.com/files/。在这个地址找到最新版的模块版本 ,使用wget下载。

wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar zxvf ngx_cache_purge-2.3.tar.gz

我这里使用的就是ngx_cache_purge-2.3。

编译安装ngx_cache_purge模块

使用nginx -V命令查看nginx是否已经安装了这个模块,如果没有安装,需要重新编译安装。

使用军哥lnmp一键安装包的同学,可以在lnmp的安装目录中找到lnmp.conf这个文件,然后在nginx模块中添加ngx_cache_purge。之后重新平滑升级nginx即可。

修改ngxin配置

在使用fastcgi_cache缓存之前,必须先修改nginx配置,具体就是进入虚拟主机配置中,找到domainname.conf,然后修改里面的sever配置。

#下面2行的中的wpcache路径请自行提前创建,否则可能会路径不存在而无法启动nginx,max_size请根据分区大小自行设置
fastcgi_cache_path /tmp/wpcache levels=1:2 keys_zone=WORDPRESS:250m inactive=1d max_size=1G;
fastcgi_temp_path /tmp/wpcache/temp;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
#忽略一切nocache申明,避免不缓存伪静态等
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
#Ps:如果是多个站点,以上内容不要重复添加,否则会冲突,可以考虑将以上内容添加到nginx.conf里面,避免加了多次。
server
    {
        listen 80;
        #请修改为自己的域名
        server_name zhangge.net;
        index index.html index.htm index.php default.html default.htm default.php;
        #请修改为自己网站的存放路径
        root  /home/wwwroot/domainname.com;
        set $skip_cache 0;
        #post访问不缓存
        if ($request_method = POST) {
            set $skip_cache 1;
        }
        #动态查询不缓存
        if ($query_string != "") {
            set $skip_cache 1;
        }
        #后台等特定页面不缓存(其他需求请自行添加即可)
        if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
            set $skip_cache 1;
        }
        #对登录用户、评论过的用户不展示缓存(这个规则张戈博客并没有使用,所有人看到的都是缓存)
        if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
            set $skip_cache 1;
        }
        #这里请参考你网站之前的配置,特别是sock的路径,弄错了就502了!
        location ~ [^/].php(/|$)
            {
                try_files $uri =404;
                fastcgi_pass  unix:/tmp/php-cgi.sock;
                fastcgi_index index.php;
                include fastcgi.conf;
                #新增的缓存规则
                fastcgi_cache_bypass $skip_cache;
                fastcgi_no_cache $skip_cache;
                add_header X-Cache "$upstream_cache_status From $host";
                fastcgi_cache WORDPRESS;
                fastcgi_cache_valid 200 301 302 1d;
        }
        location / {
                #此处可以添加自定义的伪静态规则(之前你新增的伪静态规则可以添加到这,没有就不用了)
                try_files $uri $uri/ /index.php?$args;
                rewrite /wp-admin$ $scheme://$host$uri/ permanent;
         }
        #缓存清理配置(可选模块,请细看下文说明)
        location ~ /purge(/.*) {
            allow 127.0.0.1;
            allow "此处填写你服务器的真实外网IP";
            deny all;
            fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
        }
        location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
                access_log off; log_not_found off; expires max;
        }
        location = /robots.txt { access_log off; log_not_found off; }
        location ~ /. { deny  all; access_log off; log_not_found off; }
        #请注意修改日志路径
        access_log /home/wwwlogs/domainname.com.log access;

注意修改上述代码中的该修改部分,不然nginx重启会出错。当然,如果是启用了https,模块就应相应的改变。

安装Nginx-helper插件

在后台搜索nginx-helper,安装好插件。

关于插件的设置:

如果没有使用CDN就可以选择purge模式,如果使用了CDN最好选择文件模式。

由于插件作者定义的缓存路径是 /var/run/nginx-cache ,而我们可能会根据服务器实际情况来自定义缓存路径,这样一来,缓存路径的不同就会导致插件无法找到缓存文件并删除!

解决的方法:在wp-config.php中增加一行代码:

define( 'RT_WP_NGINX_HELPER_CACHE_PATH','/tmp/wpcache');

这样,就配置好了。

最新nginx内置变量

在配置基于nginx服务器的网站时,必然会用到 nginx内置变量 ,下面笔者将它整理成列表,把最新版本的变量列出来,以方便做配置时查询

nginx内置变量

内置变量存放在 ngx_http_core_module 模块中,变量的命名方式和apache 服务器变量是一致的。总而言之,这些变量代表着客户端请求头的内容,例如$http_user_agent, $http_cookie, 等等。下面是nginx支持的所有内置变量:

$arg_name

请求中的的参数名,即“?”后面的arg_name=arg_value形式的arg_name

$args

请求中的参数值

$binary_remote_addr

客户端地址的二进制形式, 固定长度为4个字节

$body_bytes_sent

传输给客户端的字节数,响应头不计算在内;这个变量和Apache的mod_log_config模块中的“%B”参数保持兼容

$bytes_sent

传输给客户端的字节数 (1.3.8, 1.2.5)

$connection

TCP连接的序列号 (1.3.8, 1.2.5)

$connection_requests

TCP连接当前的请求数量 (1.3.8, 1.2.5)

$content_length

“Content-Length” 请求头字段

$content_type

“Content-Type” 请求头字段

$cookie_name

cookie名称

$document_root

当前请求的文档根目录或别名

$document_uri

同 $uri

$host

优先级如下:HTTP请求行的主机名>”HOST”请求头字段>符合请求的服务器名

$hostname

主机名

$http_name

匹配任意请求头字段; 变量名中的后半部分“name”可以替换成任意请求头字段,如在配置文件中需要获取http请求头:“Accept-Language”,那么将“-”替换为下划线,大写字母替换为小写,形如:$http_accept_language即可。

$https

如果开启了SSL安全模式,值为“on”,否则为空字符串。

$is_args

如果请求中有参数,值为“?”,否则为空字符串。

$limit_rate

用于设置响应的速度限制,详见 limit_rate。

$msec

当前的Unix时间戳 (1.3.9, 1.2.6)

$nginx_version

nginx版本

$pid

工作进程的PID

$pipe

如果请求来自管道通信,值为“p”,否则为“.” (1.3.12, 1.2.7)

$proxy_protocol_addr

获取代理访问服务器的客户端地址,如果是直接访问,该值为空字符串。(1.5.12)

$query_string

同 $args

$realpath_root

当前请求的文档根目录或别名的真实路径,会将所有符号连接转换为真实路径。

$remote_addr

客户端地址

$remote_port

客户端端口

$remote_user

用于HTTP基础认证服务的用户名

$request

代表客户端的请求地址

$request_body

客户端的请求主体

此变量可在location中使用,将请求主体通过proxy_pass, fastcgi_pass, uwsgi_pass, 和 scgi_pass传递给下一级的代理服务器。

$request_body_file

将客户端请求主体保存在临时文件中。文件处理结束后,此文件需删除。如果需要之一开启此功能,需要设置client_body_in_file_only。如果将次文件传递给后端的代理服务器,需要禁用request body,即设置proxy_pass_request_body off,fastcgi_pass_request_body off, uwsgi_pass_request_body off, or scgi_pass_request_body off 。

$request_completion

如果请求成功,值为”OK”,如果请求未完成或者请求不是一个范围请求的最后一部分,则为空。

$request_filename

当前连接请求的文件路径,由root或alias指令与URI请求生成。

$request_length

请求的长度 (包括请求的地址, http请求头和请求主体) (1.3.12, 1.2.7)

$request_method

HTTP请求方法,通常为“GET”或“POST”

$request_time

处理客户端请求使用的时间 (1.3.9, 1.2.6); 从读取客户端的第一个字节开始计时。

$request_uri

这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI,不包含主机名,例如:”/cnphp/test.php?arg=freemouse”。

$scheme

请求使用的Web协议, “http” 或 “https”

$sent_http_name

可以设置任意http响应头字段; 变量名中的后半部分“name”可以替换成任意响应头字段,如需要设置响应头Content-length,那么将“-”替换为下划线,大写字母替换为小写,形如:$sent_http_content_length 4096即可。

$server_addr

服务器端地址,需要注意的是:为了避免访问linux系统内核,应将ip地址提前设置在配置文件中。

$server_name

服务器名,www.cnphp.info

$server_port

服务器端口

$server_protocol

服务器的HTTP版本, 通常为 “HTTP/1.0” 或 “HTTP/1.1”

$status

HTTP响应代码 (1.3.2, 1.2.2)

$tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd, $tcpinfo_rcv_space

客户端TCP连接的具体信息

$time_iso8601

服务器时间的ISO 8610格式 (1.3.12, 1.2.7)

$time_local

服务器时间(LOG Format 格式) (1.3.12, 1.2.7)

$uri

请求中的当前URI(不带请求参数,参数位于$args),可以不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改,$uri不包含主机名,如”/foo/bar.html”。

Rails Nginx 实现下载受限文件的优化

需求

在Web开发中经常遇到一些文件需要用户认证和授权才能够访问,实现这样的功能需要在App Server进行。当遇到大文件或者并发量增加的时候,容易造成性能问题。为什么会这样呢?让我们从操作系统层面来分析一下:

未分类

当下载一个文件的时候,应用程序会进行系统调用。操作系统首先会检查,是不是最近访问过此文件,文件内容是否缓存在内核缓冲区,如果是,操作系统则直接根据read系统调用提供的buf地址,将内核缓冲区的内容拷贝到buf所指定的用户空间缓冲区中去。如果不是,操作系统则首先将磁盘上的数据拷贝的内核缓冲区,这一步目前主要依靠DMA来传输,然后再把内核缓冲区上的内容拷贝到用户缓冲区中。接下来,write系统调用再把用户缓冲区的内容拷贝到网络堆栈相关的内核缓冲区中,最后socket再把内核缓冲区的内容发送到网卡上。

综上一共进行了4次数据的拷贝和4次上下文切换。那么有没有方法减少数据的拷贝和上下文切换?从Linux Kernel 2.4版本开始新增了sendfile()来实现这些过程的简化。

#include<sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

未分类

系统调用sendfile()在代表输入文件的描述符in_fd和代表输出文件的描述符out_fd之间传送文件内容(字节)。描述符out_fd必须指向一个套接字,而in_fd指向的文件必须是可以mmap的。这些局限限制了sendfile的使用,使sendfile只能将数据从文件传递到套接字上,反之则不行。

使用sendfile不仅减少了数据拷贝的次数,还减少了上下文切换,数据传送始终只发生在kernel space。

那么我们该如何在实际应用中使用sendfile()呢?幸好Rails和Nginx给我们提供高级的抽象,我们只需要简单的配置一下就可食用。

实现和配置

假设

有一个请求访问受限文件test.txt, 该文件放在/mnt/data/test.txt

GET /api/download/files/test.txt HTTP/1.1

Nginx 配置

location /_send_file_accel/{
    internal;
    alias /mnt/data/;
}

location /api {
    ...

    proxy_set_header   X-Sendfile-Type X-Accel-Redirect;
    proxy_set_header   X-Accel-Mapping /mnt/data/=/_send_file_accel/;

    ...
}

Rails 配置

只需要在production.rb的config文件中加入

config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

Rails controller 中的代码

def show
  ...
  file = user.test_file # 假设文件名为test.txt
  path = File.join('/mnt/data', file)
  send_file(path, 
    disposition: 'attachment', 
    status: 200)
end

切割Nginx日志文件

以前用Apache的时候有自带个叫rotatelogs的工具,只需要修改httpd.conf文件就可以轻松简单分割日志文件。
不过Nginx并没有自带这样的工具,还需要写脚本用crontab执行。

#!/bin/bash
#设置日志文件目录
logs_path="/home/wwwlogs/"
#设置pid文件
pid_path="/usr/local/nginx/logs/nginx.pid"

#重命名日志文件
mv ${logs_path}access.log ${logs_path}access_$(date -d "yesterday" +"%Y%m%d").log

#向nginx主进程发信号重新打开日志
kill -USR1 `cat ${pid_path}`

其中日志文件目录和pid目录请根据自已的情况更改,pid文件存放的目录打开nginx.conf就可以看到了。

平常kill命令经常拿来杀进程,在这里用了个-USR1参数,在网上查了一下,有这样一段说明:

USR1亦通常被用来告知应用程序重载配置文件;例如,向HTTP服务器发送一个USR1信号将导致以下步骤的发生:停止接受新的连接,等待当前连接停止,重新载入配置文件,重新打开日志文件,重启服务器,从而实现相对平滑的不关机的更改。

真素打开了新世界的大门

最后把上面那段脚本保存,比如我们存在/usr/local/nginx/rotatelogs.sh
然后设置每天凌晨12点执行这段脚本:

0 0 * * * bash /usr/local/nginx/rotatelogs.sh

如果你有多个网站,多个日志的话,在重命名日志文件那里多加相应的几个进去就可以了。
像博主这样VPS没有默认安装crontab的,可以yum install crontabs。
然后再使用crontab -e命令进行脚本的添加。
一般来说都会打开一个vi编辑器,具体就请参照vi编辑器的用法啦。

补充:

在crontab中%是有特殊含义的,表示换行的意思。如果要用的话必须进行转义%,如经常用的date ‘+%Y%m%d’在crontab里是不会执行的,应该换成date ‘+%Y%m%d’。
我们的脚本里也有类似的表示日期的,不过不是直接写在crontab里就不用考虑转义了。

参考:

nginx日志切割

NGINX 已支持 SERVER PUSH

2018-02-20 刚刚更新的 nginx-1.13.9 已支持 HTTP/2 的特性 Server Push ,这个特性目的是让服务端将部分资源主动推送给浏览器,节约浏览器需要使用这些资源时再次发送 Get 请求的时间。很长的一段时间内 Nginx 都是不支持这个特性的,不过在新版本中已经可以使用,详细改动可以查看 http://hg.nginx.org/nginx/rev/641306096f5b

Nginx 中的 Server Push 提供两个选项:

直接指定需要推送的资源,Nginx 会直接推送(只能使用相对链接)。

http2_push  /css/style.css;

使用 W3C文档 规定的 Link 字段作为 HTML 响应。

Link: </style.css>; as=style; rel=preload;

然后在配置中开启

http2_push_preload on;

为了方便,我选择第一种方式,直接指定需要推送的资源文件。之后在 Chrome 的 Developer Tools —— Network 面板中可以看到我指定推送的资源状态为 Push 。

Nginx 配置 HTTP 跳转 HTTPS

本文介绍 Nginx 访问 HTTP 跳转 HTTPS 的 4 种配置方式。

1. rewrite

Nginx rewrite 有四种 flag:

  • break:在一个请求处理过程中将原来的 url 改写之后,再继续进行后面的处理,这个重写之后的请求始终都是在当前这一个 location 中处理
  • last:相当于一个新的 request,需要重新走一遍 server,提供了一个可以转到其他 location 的机会
  • redirect:表示 302 temporarily redirect
  • permanent:表示 301 permanently redirect

要使用 HTTP 跳转 HTTPS,当然是需要 301 跳转,即使用 permanent 这个标签:

rewrite  ^(.*)  https://$server_name$1 permanent;

提醒:以上配置涉及到三个本文并未提及的点:rewrite 用法、全局变量、正则匹配。

2. 301 状态码

Nginx 使用 ruturn ${http_code} 指定对应状态码的处理。这里我们使用 return 301 指定 301 重定向的目标:

return  301  https://$server_name$request_uri;

3. 497 状态码

当 server 只允许 HTTPS 请求时,基于 HTTP 的访问会被 Nginx 返回 497 错误。这时我们使用 error_page 将访问重定向至 HTTPS 上:

error_page  497  https://$server_name$request_uri;

4. meta

还有一种方式是,返回一个写入 meta 标签的 html 页面,让浏览器跳转。和上面三种方式不同,此方案不在 Nginx 上进行跳转,节约服务器资源,而缺点是不能写入 $request_uri 变量,只能跳转到固定地址。

server {
    ...

    index  meta.html;
    error_page 404 meta.html;
}

在要返回的 meta.html 中写入:

<html>
  <meta http-equiv="refresh" content="0; url=${你要跳转的目标地址}">
</html>

本站就使用这个方案,所以我是这样写的:

<html>
  <meta http-equiv="refresh" content="0; url=https://sometimesnaive.org/">
</html>

nginx配置正向代理支持HTTPS

未分类

nginx当正向代理的时候,通过代理访问https的网站会失败,而失败的原因是客户端同nginx代理服务器之间建立连接失败,并非nginx不能将https的请求转发出去。因此要解决的问题就是客户端如何同nginx代理服务器之间建立起连接。有了这个思路之后,就可以很简单的解决问题。我们可以配置两个SERVER节点,一个处理HTTP转发,另一个处理HTTPS转发,而客户端都通过HTTP来访问代理,通过访问代理不同的端口,来区分HTTP和HTTPS请求。

#HTTP
server{
resolver 8.8.8.8;
access_log /data/logs/nginx/access_proxy.log main;
listen 80;
location / {
root html;
index index.html index.htm;
proxy_pass $scheme://$host$request_uri;
proxy_set_header HOST $http_host;
proxy_buffers 256 4k;
proxy_max_temp_file_size 0k;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_next_upstream error timeout invalid_header http_502;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#HTTPS
server{
resolver 8.8.8.8;
access_log /data/logs/nginx/access_proxy.log main;
listen 443;
location / {
root html;
index index.html index.htm;
proxy_pass https://$host$request_uri;
proxy_buffers 256 4k;
proxy_max_temp_file_size 0k;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_next_upstream error timeout invalid_header http_502;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

如果访问HTTP网站,可以直接这样的方式: curl –proxy proxy_server:80 http://www.taobao.com/
如果访问HTTPS网站,例如https://www.alipay.com,那么可以使用nginx的HTTPS转发的server:
curl –proxy proxy_server:443 http://www.alipay.com

2013年12月9日补记:

之前nginx配置透明代理的时候,没有特别针对端口的配置,如果之前的url是http://www.test.com:8080/这样的地址过来,通过nginx转发之后实际到了http://www.test.com:80/上面,为了修复这个问题,增加如下配置:

proxy_pass http://$host:$cookie_passport$request_uri;

其中$cookie_是获取请求中cookie的信息,这个passport的cookie值是原URL中端口号。由此可以看出,如果要通过该NGINX转发,需要首先设置一个cookie,这个cookie名为passport,cookie的值为原url中的端口号。

如果使用CURL命令请求链接,可以这样子:

curl -b passport=80 --proxy proxy_server:80 http://www.taobao.com/

其中-b参数是为了添加cookie

nginx 出现504 Gateway Time-out的解决方法

本文介绍nginx出现504 Gateway Time-out问题的原因,分析问题并提供解决方法。

1. 问题分析

nginx访问出现504 Gateway Time-out,一般是由于程序执行时间过长导致响应超时,例如程序需要执行90秒,而nginx最大响应等待时间为30秒,这样就会出现超时。

通常有以下几种情况导致

1.程序在处理大量数据,导致等待超时。
2.程序中调用外部请求,而外部请求响应超时。
3.连接数据库失败而没有停止,死循环重新连。

出现这种情况,我们可以先优化程序,缩短执行时间。另一方面,可以调大nginx超时限制的参数,使程序可以正常执行。

对于访问超时的设定,nginx与php都有相关的设置,可以逐一进行修改。

2. 解决方法

nginx配置

nginx.conf中,设置以下几个参数,增加超时时间

fastcgi_connect_timeout 

fastcgi连接超时时间,默认60秒

fastcgi_send_timeout 

nginx 进程向 fastcgi 进程发送请求过程的超时时间,默认值60秒

fastcgi_read_timeout 

fastcgi 进程向 nginx 进程发送输出过程的超时时间,默认值60秒

php配置

php.ini

max_execution_time 

php脚本最大执行时间

php-fpm

request_terminate_timeout 

设置单个请求的超时时间

php程序中可加入set_time_limit(seconds)设置最长执行时间

例如 set_time_limit(0) 表示不超时。

NGINX实现图片防盗链(REFERER指令)

Nginx referer指令简介

nginx模块ngx_http_referer_module通常用于阻挡来源非法的域名请求.我们应该牢记,伪装Referer头部是非常简单的事情,所以这个模块只能用于阻止大部分非法请求.我们应该记住,有些合法的请求是不会带referer来源头部的,所以有时候不要拒绝来源头部(referer)为空的请求.

图片防盗链一般配置:

location ~* .(jpg|jpeg|bmp|gif|png|css|js|ico|webp|tiff|ttf|svg) {
    valid_referers none blocked *.wuditnt.com wuditnt.com ~.google. ~.baidu.;
    if ($invalid_referer) {
        return 403;
        #rewrite ^/ http://XXXX/403.gif; ##这个图片不能被防盗链,不然显示不正常。除非把上面的GIF过滤删除。
    }
    expires 30d;
}

以上所有来至*.wuditnt.com和域名中包含google和baidu的站点都可以访问到当前站点的图片,如果来源域名不在这个列表中,那么$invalid_referer等于1,在if语句中返回一个403给用户,这样用户便会看到一个403的页面,如果使用下面的rewrite,那么盗链的图片都会显示403.gif。如果用户直接在浏览器输入你的图片地址,那么图片显示正常,因为它符合none这个规则.

!!!!!!!!!

注意: http://XXXX/403.gif; ##这个图片不能被防盗链,不然显示不正常,会出现重复过滤。

除非把上面(jpg|jpeg|bmp|gif|png|css|js|ico|webp|tiff|ttf|svg) 中的gif过滤删除。

不过这个不是真正的防盗链方式,右键点击保存图片链接,还是可以在浏览器中显示的。

网上有的人说把none blocked删除掉,就形成了真正的防盗链方式,还有待测试。

!!!!!!!!!!

疑问:

经过测试,这个设置方式对Google Chrome的隐身模式和手机的Chrome浏览器似乎无效,一样可以看到图片。

其他浏览器如猎豹、微软的Edge、IE都有效果。

语法说明

valid_referers none | blocked | server_names | string …;
默认值: —
配置段: server, location
指定合法的来源’referer’, 它决定了内置变量$invalid_referer的值,如果referer头部包含在这个合法网址里面,这个变量被设置为0,否则设置为1.记住,不区分大小写的.

参数说明

none:“Referer” 来源头部为空的情况
blocked:“Referer”来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都不以http://或者https://开头.
server_names:“Referer”来源头部包含当前的server_names(当前域名)
arbitrary string:任意字符串,定义服务器名或者可选的URI前缀.主机名可以使用*开头或者结尾,在检测来源头部这个过程中,来源域名中的主机端口将会被忽略掉
regular expression:正则表达式,~表示排除https://或http://开头的字符串.

宝塔部署ubuntu+nginx+flask环境

准备

  1. 搭建好宝塔的vps,我用的是vultr
  2. flask应用在本地运行成功

在宝塔界面添加网站

  1. 设置好域名,数据库,php版本不管,或者在软件管理中卸载php
  2. 创建的web文件在/www/wwwroot/目录下
  3. 在本地的flask应用文件打包上传到刚刚创建的web文件中,解压

创建Python环境

$ sudo apt install python3-venv
$ python3 -m venv venv
# 如果venv/bin/下没有activate,就表示没有成功,解决如下
$ export LC_ALL="en_US.UTF-8"
$ export LC_CTYPE="en_US.UTF-8"
$ sudo dpkg-reconfigure locales
# 进入虚拟环境
$ source venv/bin/activate
# 安装uWSGI和requirements
$ pip install uwsgi
$ pip install -r requirements.txt
# 退出虚拟环境
$ deactivate

配置uwsgi

在应用根目录创建config.ini文件,内容如下

[uwsgi]
# uwsgi 启动时所使用的地址与端口
socket = 127.0.0.1:8386
# 指向网站目录
chdir = /www/wwwroot/www.itswcg.site
# python 启动程序文件
wsgi-file = main.py
# python 程序内用以启动的 application 变量名
callable = app 
# 处理器数
processes = 4
# 线程数
threads = 2
#状态检测地址
stats = 127.0.0.1:9191

配置nginx

在宝塔面板中,管理网站,设置,配置文件修改如下,
或者在/www/server/panel/vhost/nginx/.conf下修改

server {
  listen  80; 如有多个web应用,都是80端口监听
  server_name resume.itswcg.com; #地址
  location / {
    include      uwsgi_params;
    uwsgi_pass   127.0.0.1:8386;  # 指向uwsgi 所应用的内部地址,所有请求将转发给uwsgi 处理
    uwsgi_param UWSGI_PYHOME /www/wwwroot/www.itswcg.site/venv; # 指向虚拟环境目录
    uwsgi_param UWSGI_CHDIR  /www/wwwroot/www.itswcg.site; # 指向网站根目录
    uwsgi_param UWSGI_SCRIPT main:app; # 指定启动程序
  }
}

重启

$ sudo service nginx restart

这时候运行如下,不出错,输入网址就成功了

$ uwsgi config.ini

配置supervisor

supervisor能同时启动多个应用,能自动重启应用,保证可用性。
安装

$ sudo apt-get install supervisor

在/etc/supervisor/conf.d下添加.conf文件(resume.conf),内容如下

[program:resume] #resume是<name>
##注意项目目录和uwsgi的配置文件地址
command=/www/wwwroot/www.itswcg.site/venv/bin/uwsgi /www/wwwroot/www.itswcg.site/config.ini
directory=/www/wwwroot/www.itswcg.site
autostart=true
autorestart=true
user = root
##log文件的位置
stdout_logfile=/www/wwwroot/www.itswcg.site/logs/uwsgi_supervisor.log

启动

supervisord -c /etc/supervisor/supervisord.conf

客户端管理

$ supervisorctl

这样你就不用每次重启时都运行$ uwsgi config.ini,supervisor帮你自动重启

还有别忘了在宝塔面板安全中,放行端口

未分类