Django博客系统部署小结

953次阅读  |  发布于5年以前

上次总结了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打开,找到t op_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模块会给响应加上一年的缓存头;stat ic之外的请求则通过mod_proxy模块原封不动的转给apache,apache再继续转给fastcgi。考虑到apache不直接对外提供服务,我把apa che上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",
        )
    }

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

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8