Django博客系统部署小结

上次总结了Django博客系统的开发,这次接着总结程序部署的相关内容。这几天我折腾了个够,尝试各种组合来搭环境,从一开始的Apache + mod_wsgi,之后的Nginx + uWSGI,再后来的Lighttpd + FastCGI,最后采用的是Lighttpd + Apache + FastCGI。

最后还是加上了Apache,是因为我发现Lighttpd自带的mod_compress貌似只对静态文件有用,我的博客动态输出的页面怎么都不会被gzip。

Django提供FastCGI服务要用到flup这个库,wget下来setup.py install就装好了。之后就可以参考Django官方文档写脚本来启动fastcgi了(我的博客根目录是/home/jerry/www/blog):

#!/bin/bash

PROJDIR="/home/jerry/www/blog"
PIDFILE="$PROJDIR/blog.pid"
SOCKET="$PROJDIR/blog.sock"

cd $PROJDIR

if [ -f $PIDFILE ]; then
        kill `cat -- $PIDFILE`
        rm -f -- $PIDFILE
fi

exec python manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE

运行完这段脚本,ps看下进程可以发现fastcgi已经以prefork模式在跑了。这里有个需要注意的地方:启动web服务和fastcgi的用户如果不在一个组后面会出现permission deny。这个问题困扰我很久,后来干脆把apache从www-data改到jerry帐号启动就好了。

apache支持fastcgi需要装mod_fastcgi,同样先wget下来解压,把Makefile.AP2重命名为Makefile,用vim打开,找到top_dir,把默认的“/usr/local/apache2”改为“/usr/share/apache2”,make && make install就编好了。去apache配置里启用这个模块,重启下apache,如果没出现错误这一步算是搞定。

接下来在apache配置里把所有请求都rewrite给fastcgi,以下是关键配置:

<VirtualHost *:8080>
    ServerName www.imququ.com
    DocumentRoot "/home/jerry/www/blog/"

    FastCGIExternalServer /home/jerry/www/blog/blog.fcgi -socket /home/jerry/www/blog/blog.sock

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/(.*)$ /blog.fcgi/$1 [QSA,L]
</VirtualHost>

现在可以测试下通过8080端口是否能成功访问到网站,如果出现500看下log多半能发现原因。

最后搭Lighttpd用来提供80端口对外服务,还是贴关键配置:

server.modules = ("mod_compress","mod_proxy","mod_rewrite","mod_expire")

compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ("text/plain", "text/html", "application/javascript", "text/css")

$HTTP["host"] == "www.imququ.com" {
    server.port = 80
    server.document-root = "/home/jerry/www/blog"

    dir-listing.activate = "disable"

    expire.url = (
        "https://imququ.com/static/" => "access plus 1 years",
    )

    url.rewrite-once = ( 
        "^/favicon.ico$" => "https://imququ.com/static/favicon.ico", 
        "^/robots.txt$" => "https://imququ.com/static/robots.txt", 
        "^(/static.*)$" => "$1",
    )

    $HTTP["url"] !~ "https://imququ.com/static/.*" {
        proxy.server = (
            "" => ((
                "host" => "127.0.0.1",
                "port" => 8080        
            ))
        )
    }
}

所有静态资源都在/static目录下,mod_compress模块负责对它们gzip和cache,mod_expire模块会给响应加上一年的缓存头;static之外的请求则通过mod_proxy模块原封不动的转给apache,apache再继续转给fastcgi。考虑到apache不直接对外提供服务,我把apache上127.0.0.1之外的请求都deny掉了。

到这里就差不多了,用YSlow和Page Speed跑下分数,与server端有关的优化基本都是满分,除了cdn这个不是我能搞定的。

总的来说,python的web环境搭建相比php要复杂一些,不是把文件丢到web目录直接就能跑那么简单。不过,借这个机会把三大web server都了解一番也挺不错的。人生的意义不就是在于折腾么~

更新:通过Django内置的GZip Middleware搞定了动态页面压缩问题,这样Apache就不需要了。@3.27

更新后的lighttpd配置如下:

$HTTP["host"]=~ "^(www\.|)imququ.com$" {
    server.document-root = "/home/jerry/www/blog"
    server.error-handler-404 = "blog.fcgi/404.html"

    expire.url = (
        "https://imququ.com/static/" => "access plus 1 years",
    )

    $HTTP["host"] =~ "^([^.]+\.[^.]+)$" {
        url.redirect = (
            ".*" => "http://www.%1"
        )
    }

    fastcgi.server = (
        "/blog.fcgi" => (
            "main" => (
                "socket" => "/home/jerry/www/blog/blog.sock",
                "check-local" => "disable",
            )
        ),
    )

    url.rewrite-once = ( 
        "^/favicon.ico$" => "https://imququ.com/static/favicon.ico", 
        "^/robots.txt$" => "https://imququ.com/static/robots.txt", 
        "^(/static.*)$" => "$1",
        "^(/.*)$" => "/blog.fcgi$1",
    )
}

本文链接:参与评论 »

--EOF--

提醒:本文最后更新于 2084 天前,文中所描述的信息可能已发生改变,请谨慎使用。

专题「Web 服务器」的其他文章 »

Comments