> CentOS > CentOS教程 >

CentOS部署flask cms

最近,学习了python,但是苦于没任何编程经验,没有办法实践,所以准备自己打一个python框架的网站来玩一玩,巩固巩固知识~
参考了网上各位给的初学者的意见最后选择了flask比较适合初学者的web框架
所以就找到了这个项目:https://github.com/quokkaproject/quokka
好了,开始搭建

1、运行环境

我的系统环境

虚拟机
system: CentOS release 6.4 (Final)
kernel: 2.6.32-504.23.4.el6.x86_64
Memory: 997MB

i 下载安装新版的Python

[root@linux2 tmp]# wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tgz
...
[root@linux2 tmp]# tar zxf Python-2.7.10.tgz
[root@linux2 tmp]# cd Python-2.7.10
[root@linux2 Python-2.7.10]# ./configure
[root@linux2 Python-2.7.10]# make && make install

ii 安装python-pip与virtualenv

参考:https://pip.pypa.io/en/stable/installing/

[root@linux2 tmp]# wget https://pypi.python.org/packages/source/p/pip/pip-7.1.2.tar.gz #下载pip源码包
[root@linux2 pip-7.1.2]# wget https://bootstrap.pypa.io/get-pip.py #下载安装脚本
[root@linux2 pip-7.1.2]# python get-pip.py  #会更新安装setuptools、wheel等包
[root@linux2 pip-7.1.2]# pip install virtualenv

iii 更新新版git

linux自带的git版本太低,后续用到的命令参数不支持,所以这里更新一下git命令

[root@linux2 pip-7.1.2]# yum clean all
[root@linux2 pip-7.1.2]# rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
[root@linux2 pip-7.1.2]# rpm -i http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
[root@linux2 pip-7.1.2]# yum --enablerepo=rpmforge-extras update git

2、安装mongodb

[root@linux2 tmp]# curl -O  https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.0.6.tgz
[root@linux2 tmp]# tar zxvf mongodb-linux-x86_64-rhel62-3.0.6.tgz 
[root@linux2 tmp]# mv mongodb-linux-x86_64-rhel62-3.0.6 /usr/local/mongodb
[root@linux2 mongodb]# vim /etc/mongodb.conf
port=10101
dbpath=/data/db/data
logpath=/data/db/log/mongodb.log
logappend=true  #日志追加非覆盖
fork=true  #后台运行
[root@linux2 mongodb]# mkdir -p /data/db/data /data/db/log #创建数据文件夹与日志文件夹
[root@linux2 mongodb]# /usr/local/mongodb/bin/mongod -f /etc/mongodb.conf #启动mongodb,注意内存要富裕

标注:mongo数据库操作写入数据既创建数据库,所以这里不需要单独创建数据库,只要有程序去写入数据库,它就会去新建一个数据库

3、安装配置quokka

[root@linux2 ~]# virtualenv -p /usr/local/bin/python2.7 quokka-env #指定python版本的绝对路径
[root@linux2 ~]# source quokka-env/bin/activate   #需要退出vir环境可用deactivate命令(不加参数)
(quokka-env)[root@linux2 www]# git clone https://github.com/quokkaproject/quokka --branch development --single-branch #只获取这个分支的内容,
(quokka-env)[root@linux2 www]# cd quokka/quokka/
(quokka-env)[root@linux2 quokka]# cp example.local_settings.py local_settings.py 
(quokka-env)[root@linux2 quokka]# vim local_settings.py #配置mongodb数据库
...
MONGODB_DB = "quokka_db"
MONGODB_HOST = 'localhost'
MONGODB_PORT = 10101
MONGODB_USERNAME = None   #这里我的数据库就在本地,所以我可以不设置密码
MONGODB_PASSWORD = None
...
(quokka-env)[root@linux2 quokka]# cd ..
(quokka-env)[root@linux2 quokka]# pip install -r requirements/requirements.txt 读取txt中的安装包列表

创建管理员和运行quokka

i 创建一个超级管理员 (需要登录管理界面)

$ python manage.py accounts_createsuperuser
you@email.com
P4$$W0Rd

ii 填充示例数据 (可选,如果你想要示例数据)

$ python manage.py populate

credentials for /admin will be email: admin@example.com passwd: admin

iii 运行测试

$ python manage.py runserver --host 0.0.0.0 --port 5000
  • Site on http://localhost:5000

  • Admin on http://localhost:5000/admin

更多安装方法参考这里:https://github.com/quokkaproject/quokka
至此,quokka部分安装成功~如遇其他页面不正常显示等问题,可以询问项目负责人:https://github.com/quokkaproject/quokka/issues
接下来,安装http server

4、配置nginx+Gunicorn

裸着用flask内置的web(上条命令)来跑web也可以,但是毕竟不是专业的web server,建议还是用主流web server,我这里选用的为nginx。
关于python的其他部署方法,可参考这里:http://lutaf.com/141.htm

i 下载并安装配置nginx

如果要nginx支持谷歌性能模块,需要先安装google-perftools

下载链接:
http://download.savannah.gnu.org/releases/libunwind #libunwind库为基于64位CPU和操作系统的程序提供了基本函数调用链和函数调用寄存器功能
http://https://github.com/gperftools/gperftools/releases #google性能库

安装libunwind
(quokka-env)[root@linux2 tmp]# tar zxf libunwind-1.1.tar.gz 
(quokka-env)[root@linux2 tmp]# cd libunwind-1.1
(quokka-env)[root@linux2 libunwind-1.1]# CFLAGS=-fPIC ./configure 
(quokka-env)[root@linux2 libunwind-1.1]# make CFLAGS=-fPIC
(quokka-env)[root@linux2 libunwind-1.1]# make CFLAGS=-fPIC install
安装google-perftools
(quokka-env)[root@linux2 tmp]# wget  https://github.com/gperftools/gperftools/releases/download/gperftools-2.4/gperftools-2.4.tar.gz
(quokka-env)[root@linux2 gperftools-2.4]# ./configure
(quokka-env)[root@linux2 gperftools-2.4]# make && make install

为google-perftools添加线程目录

[root@localhost home]#mkdir /tmp/tcmalloc  
[root@localhost home]#chmod 0777 /tmp/tcmalloc

安装nginx

(quokka-env)[root@linux2 nginx]# yum install -y gcc-c++ gcc automake autoconf libtool make
(quokka-env)[root@linux2 tmp]# curl -O http://nginx.org/download/nginx-1.8.0.tar.gz  #下载最新稳定版nginx
(quokka-env)[root@linux2 tmp]# tar zxvf nginx-1.8.0.tar.gz 
(quokka-env)[root@linux2 tmp]# cd nginx-1.8.0
(quokka-env)[root@linux2 nginx-1.8.0]# groupadd www
(quokka-env)[root@linux2 nginx-1.8.0]# useradd -s /sbin/nologin -g www www
(quokka-env)[root@linux2 nginx-1.8.0]# ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module  --with-google_perftools_module --with-http_gzip_static_module --with-http_sub_module 
(quokka-env)[root@linux2 nginx-1.8.0]# make && make install

nginx编译模块说明:
--with-http_stub_status_module: 提供查看服务器统计信息的能力
--with-http_ssl_module: 支持 HTTPS/SSL
--with-http_gzip_static_module: 提供预压缩的静态文件
--with-google_perftools_module: 支持 Google 性能工具
--with-http_sub_module: 可以替换页面中的文本
更多请参考这篇博客:http://www.zicheng.net/article/42.htm

配置nginx

(quokka-env)[root@linux2 conf]# vim nginx.conf
worker_processes  1;
google_perftools_profiles /tmp/tcmalloc; #增加线程目录
events {
worker_connections  1024;
}
http {
include   mime.types;
default_type  application/octet-stream;
sendfileon;
keepalive_timeout  65;
upstream quokka {
server unix:/tmp/quokka.sock fail_timeout=0;
}
server {
listen 80 default_server;
return 444;  #当请求不匹配server_name 返回http code 444
}
server { #配置没有主机头
    listen       80;
    server_name  *.eason.wang;
    return       301 https:/eason.wang$request_uri;
}
server {
listen   80;
client_max_body_size 4G;
server_name  eason.wang; #server name 也就是你的域名
keepalive_timeout 5;
root /data/www/quokka; #暂时没搞明白为什么要配置这个路径
location / {
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass   http://quokka;
}
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}
}
}

安装配置gunicorn
一个python WSGI的HTTP Server,具体我也不知道该怎么说.可以参考官网

(quokka-env)[root@linux2 logs]# pip install gunicorn
(quokka-env)[root@linux2 quokka]# cd /data/www/quokka/
(quokka-env)[root@linux2 quokka]# vim start_gunicorn.sh  #启动脚本
#!/bin/bash
NAME='quokka'   #应用的名称
FLASKDIR=/data/www/quokka  #django项目的目录
SOCKFILE=/tmp/quokka.sock   #使用这个sock来通信
USER=www #运行此应用的用户
NUM_WORKERS=3  #gunicorn使用的工作进程数
DJANGO_WSGI_MODULE=wsgi  #wsgi模块

echo "starting $NAME as `whoami`"
#激活python虚拟运行环境
cd $FLASKDIR
source /root/quokka-env/bin/activate

#启动flask

exec /root/quokka-env/bin/gunicorn \
--workers $NUM_WORKERS \
-u www \
--bind=unix:$SOCKFILE \
wsgi

运行

(quokka-env)[root@linux2 quokka]# ./start_gunicorn.sh &

遇到的问题
1、安装pip时,执行python get-pip.py后成功,但是没有pip命令。
反复确认,执行这条安装命令并没有出错,我想可能是Python版本的问题,因为linux默认是python 2.6.6,而我要使用virtualenv所以我也懒得做环境变量了,所以我用绝对路径方法指定新版本python重新安装解决。

[root@linux2 pip-7.1.2]# /usr/local/bin/python2.7 get-pip.py --force-reinstall

2、mongodb遇到要删除数据库操作时,删除命令为下

[root@linux2 shell]# /usr/local/mongodb/bin/mongo 127.0.0.1:10101
> use xxx #选择要删除的数据库
> db.dropDatabase() #删除数据库

3、当执行pip安装时报错“Could not find a version that satisfies the requirement ...”时,使用-v参数查看详细原因并解决。例:

[root@linux2 www]# pip install pyshorteners==0.5.5 -v
Collecting pyshorteners==0.5.5
  Getting page https://pypi.python.org/simple/pyshorteners/
  Starting new HTTPS connection (1): pypi.python.org
  "GET /simple/pyshorteners/ HTTP/1.1" 404 28063
  Could not fetch URL https://pypi.python.org/simple/pyshorteners/: 404 Client Error: Not Found - skipping
  1 location(s) to search for versions of pyshorteners:
  * https://pypi.python.org/simple/pyshorteners/
  Getting page https://pypi.python.org/simple/pyshorteners/
  "GET /simple/pyshorteners/ HTTP/1.1" 404 28063
  Could not fetch URL https://pypi.python.org/simple/pyshorteners/: 404 Client Error: Not Found - skipping
  Could not find a version that satisfies the requirement pyshorteners==0.5.5 (from versions: )
Cleaning up...
No matching distribution found for pyshorteners==0.5.5
Exception information:
Traceback (most recent call last):
  File "/root/quokka-env/lib/python2.7/site-packages/pip/basecommand.py", line 211, in main
status = self.run(options, args)
  File "/root/quokka-env/lib/python2.7/site-packages/pip/commands/install.py", line 305, in run
wb.build(autobuilding=True)
  File "/root/quokka-env/lib/python2.7/site-packages/pip/wheel.py", line 705, in build
self.requirement_set.prepare_files(self.finder)
  File "/root/quokka-env/lib/python2.7/site-packages/pip/req/req_set.py", line 334, in prepare_files
functools.partial(self._prepare_file, finder))
  File "/root/quokka-env/lib/python2.7/site-packages/pip/req/req_set.py", line 321, in _walk_req_to_install
more_reqs = handler(req_to_install)
  File "/root/quokka-env/lib/python2.7/site-packages/pip/req/req_set.py", line 461, in _prepare_file
req_to_install.populate_link(finder, self.upgrade)
  File "/root/quokka-env/lib/python2.7/site-packages/pip/req/req_install.py", line 250, in populate_link
self.link = finder.find_requirement(self, upgrade)
  File "/root/quokka-env/lib/python2.7/site-packages/pip/index.py", line 571, in find_requirement
'No matching distribution found for %s' % req
DistributionNotFound: No matching distribution found for pyshorteners==0.5.5

通过上边可以看到,获取连接404了,所以我们来验证下是真的404还是pip有问题,可以直接访问web或者使用curl来验证

(quokka-env)[root@linux2 www]# curl -I https://pypi.python.org/simple/pyshorteners/
HTTP/1.1 404 Not Found

页面404就属于项目负责人在调整页面或者撤销的问题了。
如果想尽快解决,在github搜索该项目,一般README文档会有本地怎么安装。

4、解决nginx启动时报错

nginx: error while loading shared libraries: libprofiler.so.0: cannot open shared object file: No such file or directory
nginx: error while loading shared libraries: libunwind.so.8: cannot open shared object file: No such file or directory

以上两个错误均属于因为目前是64位操作系统导致的,解决方法即为找到两个lib文件,将它们软连接到/usr/lib64

(quokka-env)[root@linux2 ~]# whereis libprofiler.so.0 libunwind.so.8 #找到两个lib文件位置
libprofiler.so: /usr/lib64/libprofiler.so.0 /usr/local/lib/libprofiler.so.0 /usr/local/lib/libprofiler.so
libunwind.so: /usr/lib64/libunwind.so.8 /usr/local/lib/libunwind.so.8 /usr/local/lib/libunwind.so
(quokka-env)[root@linux2 ~]# ln -s /usr/local/lib/libprofiler.so.0 /usr/lib64/
(quokka-env)[root@linux2 ~]# /usr/local/nginx/sbin/nginx -V
/usr/local/nginx/sbin/nginx: error while loading shared libraries: libunwind.so.8: cannot open shared object file: No such file or directory
(quokka-env)[root@linux2 ~]# ln -s /usr/local/lib/libunwind.so.8 /usr/lib64/

5、解决指定gunicorn -u 没有权限问题

(quokka-env)[root@linux2 quokka]# gunicorn -u www --workers 3 --bind unix:/tmp/quokka.sock -m 007 wsgi
[2015-09-24 10:53:57 +0000] [28230] [INFO] Starting gunicorn 19.3.0
[2015-09-24 10:53:57 +0000] [28230] [INFO] Listening at: unix:/tmp/quokka.sock (28230)
[2015-09-24 10:53:57 +0000] [28230] [INFO] Using worker: sync
[2015-09-24 10:53:57 +0000] [28235] [INFO] Booting worker with pid: 28235
[2015-09-24 10:53:57 +0000] [28235] [ERROR] Exception in worker process:
Traceback (most recent call last):
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/arbiter.py", line 507, in spawn_worker
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/workers/base.py", line 118, in init_process
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 65, in load
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 52, in load_wsgiapp
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/util.py", line 355, in import_app
  File "/data/www/quokka/wsgi.py", line 4, in <module>
from werkzeug.serving import run_simple
ImportError: No module named werkzeug.serving
Traceback (most recent call last):
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/arbiter.py", line 507, in spawn_worker
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/workers/base.py", line 118, in init_process
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 65, in load
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 52, in load_wsgiapp
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/util.py", line 355, in import_app
  File "/data/www/quokka/wsgi.py", line 4, in <module>
from werkzeug.serving import run_simple
ImportError: No module named werkzeug.serving
[2015-09-24 10:53:57 +0000] [28235] [INFO] Worker exiting (pid: 28235)
Traceback (most recent call last):
  File "/root/quokka-env/bin/gunicorn", line 11, in <module>
sys.exit(run())
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 74, in run
WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/base.py", line 189, in run
super(Application, self).run()
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/app/base.py", line 72, in run
Arbiter(self).run()
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/arbiter.py", line 174, in run
self.manage_workers()
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/arbiter.py", line 477, in manage_workers
self.spawn_workers()
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/arbiter.py", line 541, in spawn_workers
time.sleep(0.1 * random.random())
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/arbiter.py", line 214, in handle_chld
self.reap_workers()
  File "/root/quokka-env/lib/python2.7/site-packages/gunicorn/arbiter.py", line 459, in reap_workers
raise HaltServer(reason, self.WORKER_BOOT_ERROR)
gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>

根据执行的命令和堆栈跟踪来看,基本上确定两个错误信息:

  • ImportError: No module named werkzeug.serving导入模块错误,检查是不是模块问题。

  • 大面积的File "/root ...",env文件夹在/root账号下要检查www账号是不是有权限问题。

下面检查这两个错误:

(quokka-env)[root@linux2 tmp]# python
Python 2.7.10 (default, Sep 21 2015, 17:31:07) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from werkzeug.serving import run_simple

没有报错,看来模块是没有问题的

(quokka-env)[root@linux2 tmp]# gunicorn --workers 3 --bind unix:/tmp/quokka.sock -m 007 wsgi       
[2015-09-24 11:36:19 +0000] [28350] [INFO] Starting gunicorn 19.3.0
[2015-09-24 11:36:19 +0000] [28350] [INFO] Listening at: unix:/tmp/quokka.sock (28350)
[2015-09-24 11:36:19 +0000] [28350] [INFO] Using worker: sync
[2015-09-24 11:36:19 +0000] [28355] [INFO] Booting worker with pid: 28355
[2015-09-24 11:36:19 +0000] [28356] [INFO] Booting worker with pid: 28356
[2015-09-24 11:36:19 +0000] [28357] [INFO] Booting worker with pid: 28357

去掉-u www可以正常启动,那么看来就是权限惹的问题~
解决方法:

[root@linux2 /]# ll
...
drwxr-----. 14 root root  4096 9月  23 19:50 root
...
[root@linux2 /]# chmod g+x root

这里为什么要加属组的执行权限,是因为我们执行gunicorn命令的权限是当前用户和当前用户组(可以通过-g改变),而我们改变了启动的用户为www,所以它会尝试用www用户权限,www没有这个权限,它又会去尝试当前用户组权限(既root组),所以要给root组有执行权限即可



(责任编辑:IT)