`

CentOS + Python3.3 + Django1.7 + uwsgi + nginx + mysql web发布环境搭建

 
阅读更多

文章源路径:http://f4d3.cn/220.html

目录:

  1. CentOS上升级Python
  2. 安装easy_install和pip
  3. uwsgi安装及测试
  4. Django安装及测试
  5. 连接uwsgi与Django
  6. nginx安装及测试
  7. 连接uwsgi与nginx
  8. 连接uwsgi与Django与nginx
  9. uwsgi ini
  10. mysql安装设置
  11. python3 Django mysql连接及测试
  12. 快速搭建blog测试
  13. Pycharm开发

如果只是想学习django开发直接用django本身自带的开发用服务器即可。

1. CentOS上升级Python

用的系统是CentOS 6.4,其上python版本是2.6,而Django支持的版本是2.7+,又考虑到网页语言用UTF-8,而python3+默认字符已变为Unicode,所以选择python3版本,小菜理解,不知对错。

前后安装python一共4遍,每次到后面就会遇到因为编译时缺少某某模块的问题,不得不又安装了模块重新编译,这几个模块是,

yum install zlib zlib-devel
yum install bzip2 bzip2-devel
yum install openssl openssl-devel
yum install sqlite-devel

安装完之后再tar it,这里要说的是,因为有自带的pyhton了,所以我们安装到新的目录,不要覆盖。

./configure --prefix=/usr/local/python3.3 && make && make install

在/usr/bin下我们可以看到有python,python2,python2.6,其实都是一个文件,我们把自己的ln过去,

ln -s /usr/local/python3.3/bin/python3.3 /usr/bin/python
python -V

可以看到版本改变了。但是这时用了yum发现报错了,唉,

vim /usr/bin/yum
#! /usr/bin/python 改为 #! /usr/bin/python2.6

如此即可,CentOS下python安装告一段落。
(注:如果接下来不想频繁做ln -s链接,就把/usr/local/python3.3/bin设置为环境变量吧,自行网补。)

2. 安装easy_install和pip

可能对各位很简单,但是对我来说太难了,

wget https://bootstrap.pypa.io/ez_setup.py
python ez_setup.py
ln -s /usr/local/python3.3/bin/easy_install /usr/bin/easy_install
wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
python get-pip.py

像教程上说的那样,这样安装完成后应该可以直接执行pip -V了,结果我就是找不到命令,还是pip本来就不给自动设置成为命令,去python目录下看看也找不到pip文件,该ln哪个文件,于是半天未果后,就采取了这样的办法,

(注:想要yum安装pip还要先安装EPEL,详见http://xmodulo.com/how-to-set-up-epel-repository-on-centos.html,选择相应版本,相应解决方案。有时侯windows下配置简单,有时候又必须选择linux。)

yum install python-pip
pip -V

然后报错了,人总是让现实搞的追求越来越低,能报错太高兴了,说明已经有这个命令了。查看错误是版本冲突,因为我们上面安装过1.5.6(目前最新),yum安装的1.3几吧,于是我查看下pip文件,出于本能
把1.3.几全改成了1.5.6,

vim /usr/bin/pip
修改后:
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.5.6','console_scripts','pip'
__requires__ = 'pip==1.5.6'
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.exit(
        load_entry_point('pip==1.5.6', 'console_scripts', 'pip')()
    )

机智的我备份了下,然后yum remove python-pip,果然pip没了,我把备份还原过来,pip终于正常使用了。真难!

3. uwsgi安装及测试

搞了许久后终于来到正题,为什么选择uwsgi呢,是因为apache的mod_wsgi配置太难了,网上找到的资料,各人有各人的步骤,各人有各人的路径,这我学这个不像,学那个不像,只学一个人的行吗,遇到问题还是要去的别人的,毕竟每个人遇到的问题不同。在这长达一天的start:邂逅问题,查找问题,解决问题,goto start中发现了uwsgi,号称专治mod_wsgi各种顽疾,又是搭配nginx,于是就来搭建这个吧。

pip install uwgsi
ln -s /usr/local/python3.3/bin/uwsgi /usr/bin/uwsgi

现在来测试一下,

vim test.py
# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2
uwsgi --http :8001 --wsgi-file test.py

此时访问http://localhost:8001可见Hello World,成功。

(补:成功不易啊。为什么到处的教程都是写的return “xxxxx”,结果网页无输出,我跋山涉水找到官网才发现要加b,原因当然是版本不同,其中的[]加不加无所谓,但是在python3中,因为字符默认是unicode了,所以必须进行编码。其中的b”xxx”也可以换为”xxx”.encode(‘utf-8′),但是在文前加上#-*- coding: UTF-8 -*-却不行呢。

在python3中文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。

uwsgi -s :8001 –wsgi-file test.py,访问时会出现invalid request block size: 21573 (max 4096)…skip,因为usgi参数-s表示以socket方式提供通信端口,默认的协议是tcp。当通过nginx访问uwsgi,就无所谓了。)

4. Django安装及测试

此处测试用到sqlite模块。

pip install django
cd /usr/local/python3.3/bin/
python django-admin.py startproject myproject
cd myproject
python manage.py runserver 0.0.0.8002

打开浏览器访问http://localhost:8002显示It worked!..,成功。现在学聪明了,多看几个教程,联系着来,不容易出错。

5. 连接uwsgi与Django

不要看到一些教程上有就也跟着建立个django_wsgi,现在版本不需要了,直接myproject.wsgi即可。

uwsgi --http :8004 --chdir /home/wwwroot/default/myproject --module myproject.wsgi

成功可见It worked!。

6. nginx安装及测试

yum install nginx
service nginx start

浏览器访问localhost,可见Welcome to nginx on EPEL!,成功。但是不要用这种方式,它自动安装的相关配置我们不清楚,所以一定要选择源码安装。因为我之前的贪简单,后面遇到很多permission问题,最后又重装了下,但是下面的很多章节都是在上面的配置方式下进行的,懒得修改了。

在这之前,有相当多的环境要安装,尤其是Pcre。

yum install patch make cmake gcc gcc-c++ gcc-g77 flex bison file libtool libtool-libs autoconf kernel-devel libjpeg libjpeg-devel libpng libpng-devel libpng10 libpng10-devel gd gd-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glib2 glib2-devel bzip2 bzip2-devel libevent libevent-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel vim-minimal nano fonts-chinese gettext gettext-devel ncurses-devel gmp-devel pspell-devel unzip libcap diffutils
wget http://soft.vpser.net/web/pcre/pcre-8.30.tar.gz
tar it configure make make install
groupadd www
useradd -s /sbin/nologin -g www www
wget http://soft.vpser.net/web/nginx/nginx-1.6.2.tar.gz
tar it
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-ipv6
make && make install

安装完成后,启动方法有2个:

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/nginx

我懂得不深,所以用第一个,因为每次都会重读配置文件。这时又提示找不到libpcre.so.1,于是我们可以

find / -name "libpcre.so.*"

你会发现/lib64下有libpcre.so.0.0.1,32位就是/lib下面,我们做一下ln,

ln -s /lib64/libpcre.so.0.0.1 /lib64/libpcre.so.1

这时再次启动nginx,没有错误,打开浏览器访问http://localhost,可见Welcome to nginx on EPEL!,成功。

7. 连接uwsgi与nginx

nginx用户权限很愁人啊,但是网上很少有人遇到我的问题,一开始想变更日志路径,nginx.conf中可见user是nginx,我甚至把一个文件夹权限改成a+rwx,属主改为nginx仍然permission denied。而且每次启动总找不到/var/run/nginx.pid,所以service nginx start各种不能用。最后无奈启动方法变为/usr/sbin/nginx -c /etc/nginx/nginx.conf即可。

一开始选择在conf.d目录下写myproject.conf的做法,但是为了避免到处permission denied,本着最小改动的原则,仅修改nginx.conf如下:

vim /etc/nginx/nginx.conf
在http{}中添加如下:
    upstream django {
        server 127.0.0.1:8001; # for a web port socket
    }

    server {
        listen      8000;
        server_name xqlm.com; # substitute your machine's IP address or FQDN
        charset     utf-8;

        client_max_body_size 75M;   # adjust to taste

        #location /media  {
        #    alias /path/to/your/mysite/media;  # your Django project's media files - amend as required
        #}

        #location /static {
        #    alias /path/to/your/mysite/static; # your Django project's static files - amend as required
        #}

        # Finally, send all non-media requests to the Django server.
        location / {
            root        /你的工程目录/myproject;
            uwsgi_pass  django;
            include     uwsgi_params; # the uwsgi_params file you installed
        }
    }
修改完成后,
uwsgi --socket :8001 --wsgi-file test.py

浏览器访问http://localhost:8000,出现Hello world!,表示成功。这里有必要说明这几个端口的关系,用户的访问是8000,对应着nginx.conf中的sever listen,然后nginx会把这些信息转达给nginx.conf中的django 8001,也就是uwsgi命令启动时监听的端口。那么直接转发给uwsgi不就可以吗,为什么中间还要插个nginx?我只好用网上的回答搪塞下“单单只有uWSGI是不够的,在实际的部署环境中,Nginx是必不可少的工具。nginx具备优秀的静态内容处理能力,然后将动态内容转发给uWSGI服务器,这样可以达到很好的客户端响应。”。上面的server中你会发现注释掉的location /static和/media,分别是表示静态内容和动态内容,但是现在我们是个空项目,用不到,后面用到再说。

8. 连接uwsgi与Django与nginx

uwsgi --socket :8001 --module myproject.wsgi 
(如果出现permisson问题酌情添加 --chmod-socket=664 或 666,一般是因为用mysite.sock才会引起,指定端口不会。)

前面每步都测试,每步都正确,到现在应该没有问题了,直接浏览器访问http://localhost:8000,现在是It worked!了。

9. uwsgi ini

有没有觉得每次uwsgi跟一长串路径不方便,那就写成一个ini文件吧,xml也可以,这里只给出ini版本的,

vim myproject_uwsgi.ini

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /home/wwwroot/default/myproject
# Django's wsgi file
module          = myproject.wsgi
# the virtualenv (full path)
# home          = /path/to/virtualenv

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe)
# socket        = /path/to/your/project/mysite.sock
socket          = :8001
# ... with appropriate permissions - may be needed
# chmod-socket  = 664
# clear environment on exit
vacuum          = true

上面就是来自官网常用的而且非常全的配置,根据需要自行调节即可。现在启动只需如下,

uwsgi --ini myproject_uwsgi.ini

浏览器访问8000,It worked!。

10. mysql安装设置

mysql的安装不多说,

yum install mysql mysql-devel mysql-server
/etc/rc.d/init.d/mysqld start
/usr/bin/mysqladmin -u root password yourpassword

这里我们新建一个用户给django使用。

mysql -u root -p
mysql> create database myprojectdb;
mysql> use mysql;
mysql> insert into user (Host,User,Password) values ('localhost','niger',password('niger'));
mysql> flush privileges;
mysql> grant all privileges on myprojectdb.* to 'niger'@'localhost' identified by 'niger';

11. python3 Django mysql连接及测试

首先安装python和mysql的连接模块,目前就python3,我选择了mysql-connector-python,接下来到myproject目录下设置django的settings.py文件,百度上面真的找不到想找的,谷歌一下问题迎刃而解。

pip install --allow-all-external mysql-connector-python
vim myproject/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'mysql.connector.django',
        'NAME': 'myprojectdb',
        'USER': 'niger',
        'PASSWORD': 'niger',
    }
}

其中database如上设置即可,engine是我们安装的mysql.connector下的django模块,其它看名字就知道意思了。现在来测试下是否成功,

python manage.py migrate
Operations to perform:
  Apply all migrations: contenttypes, admin, auth, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying sessions.0001_initial... OK

如上所示说明正常运行(第一次运行会创建一个管理用户,记住),查看数据库如下,

mysql> use myprojectdb;
mysql> show tables;
+----------------------------+
| Tables_in_myprojectdb      |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
10 rows in set (0.00 sec)

12. 快速搭建blog

我们利用django自带的admin后台来快速搭建一个blog,至于每句代码的意思,写得多了慢慢就知道了,

python manage.py startapp blog

我们发现myproject目录下有了blog文件夹,进入,修改其中的models.py,

vim models.py
from django.db import models

# Create your models here.
class BlogsPost(models.Model):
    title = models.CharField(max_length = 150)
    body = models.TextField()
    tiemstamp = models.DateTimeField()

创建BlogsPost类,继承django.db.models.Model父类,定义三个变量,title (博客标题),body(博客正文),tiemstamp(博客创建时间)(注意我这里time写成tiem了,后面会一直错下去。)
我们要记清楚django这个目录结构,现在回到myproject/myproject/settings.py,加上我们的app:blog,

vim settings.py
# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
)

再看myproject/myproject/urls.py,如下,admin这一项要存在,

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'mysite.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),
)

再回到blog/models.py,这时将数据添加到admin后台,相应变更

vim models.py
from django.db import models
from django.contrib import admin

# Create your models here.
class BlogsPost(models.Model):
    title = models.CharField(max_length = 150)
    body = models.TextField()
    timestamp = models.DateTimeField()

admin.site.register(BlogsPost)

还记得我们初始过数据库,在相应改变之后要再初始一下,

python manage.py makemigrations
python manage.py migrate

现在就成功变更数据库了。

接下来,启动网站(uwsgi –int myproject_uwsgi.ini,后面就不再附此命令了,当然要保证nginx在运行。)访问http://localhost:8000/admin/,可见登录窗口Django administration,username,password,log in这些,怎么登录,还记得我们创建的用户吗,登录即可。

(请问大家此时的页面有没有样式呢,是下面哪样呢。

QQ截图20141204190723 QQ图片20141204190703

有样式的话,跳过,没有的话,解决:
右键审查元素或者firebug,调到控制台窗口,刷新页面,发现css错误,点开可见找不到路径,所以导致没有样式加载。我们查看错误,是访问localhost:8000/static/admin/css下的样式,各种查资料,现在用到了我们的static了。在myproject下新建static,然后nginx进行设置,将css代码(请教别人得知在django目录下)转移过来,

mkdir static
vim /etc/nginx/nginx.conf
释放static的注释,并修改
location /static {
    alias /你的项目路径/myproject/static; # your Django project's static files - amend as required
}
find / -name django
/usr/share/doc/python-mako-0.3.4/examples/bench/django
/usr/lib/python2.6/site-packages/mysql/connector/django
/usr/local/python3.3/lib/python3.3/site-packages/mysql/connector/django
/usr/local/python3.3/lib/python3.3/site-packages/django
/root/download/mysql-connector-python-2.0.2/lib/mysql/connector/django
/root/download/mysql-connector-python-2.0.2/build/lib/mysql/connector/django

从结果中找符合的,答案很明显,我们去复制下django目录下的文件到我们工程下,你会发现是完全对应的,

[root@localhost myproject]# cp -rf /usr/local/python3.3/lib/python3.3/site-packages/django/contrib/admin/static/admin/ static/

相关目录结构多看看了解下。这时我们重启nginx,启动网站,

/etc/rc.d/init.d/nginx stop
/usr/sbin/nginx -c /etc/nginx/nginx.conf

为什么我要这样停止又那样启动,因为我即使把nginx.conf中user改为root,仍然是各种permission denied,唯独这样不报错。这时访问网站可见样式正常加载了。)

登录之后我们写一篇blog,

QQ截图20141204195252

发现什么,title,body,tiemstamp(哈哈,故意写错才能说明这是程序中我写的呀),这3个变量是我们在class BlogsPost中定义的不是吗。写完后点击save,会提示The blogs post “BlogsPost object” was added successfully.,怎样,是不是找到一点对应关系了呢。

QQ截图20141204195835

但是你这个样子,每次都是显示BlogsPost object,不好吧,怎么知道是哪篇文章,于是再来models.py,

from django.db import models
from django.contrib import admin

# Create your models here.
class BlogsPost(models.Model):
    title = models.CharField(max_length = 150)
    body = models.TextField()
    tiemstamp = models.DateTimeField()

class BlogPostAdmin(admin.ModelAdmin):
    list_display = ('title','tiemstamp')
    
admin.site.register(BlogsPost,BlogPostAdmin)

注意每次代码发生的变化,重启网站后,我们再来到网站同一位置,

QQ截图20141204200800

so,写错的tiemstamp说明了一切。简单的后端我们处理完了,现在该去看看我们前端如何了。

从Django的角度看,一个页面具有三个典型的组件:
一个模板(template):模板负责把传递进来的信息显示出来。
一个视图(view):视图负责从数据库获取需要显示的信息。
一个URL模式:它负责把收到的请求和你的视图函数匹配,有时候也会向视图传递一些参数。

创建模板

在blog项目下创建templates目录,在目录下创建模板文件archive.html,内容如下:

{% for post in posts %}
    <h2>{{ post.title }}</h2>
    <p>{{ post.tiemstamp }}</p>
    <p>{{ post.body }}</p>
{% endfor%}

设置模板路径,打开myproject/myproject/settings.py文件,在文件底部添加模板路径:

#template
TEMPLATE_DIRS=(
    '/你的工程路径/myproject/blog/templates',
)

创建视图函数

打开myproject/blog/views.py文件:

from django.shortcuts import render
from django.template import loader,Context
from django.http import HttpResponse
from blog.models import BlogsPost

# Create your views here.
def archive(request):
    posts = BlogsPost.objects.all()
    t = loader.get_template("archive.html")
    c = Context({'posts':posts})
    return HttpResponse(t.render(c))

posts = BlogPost.objects.all() :获取数据库里面所拥有BlogPost对象
t = loader.get_template(“archive.html”):加载模板
c = Context({‘posts’:posts}):模板的渲染的数据是有一个字典类的对象Context提供,这里的是一对键值对。

创建blog的URL模式

在myproject/urls.py文件里添加blog的url:

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'mysite.views.home', name='home'),
    
    url(r'^blog/', include('blog.urls')),
    url(r'^admin/', include(admin.site.urls)),
)

在myproject/blog/目录下创建urls.py文件:

from django.conf.urls import *
from blog.views import archive

urlpatterns = patterns('',
                      url(r'^$',archive),
                      )

之所以在blog应用下面又创建urls.py文件,是为了降低耦合度。这样myproject/urls.py文件针对的是每个项目的url。重启网站,访问http://localhost:8000/blog/,现在可见最简单的页面了。

是不是觉得页面有点单调,怎么调呢?这就要添加样式了。
(css文件统一放在static/admin/css/下,这里内嵌就好了。)

添加样式

在myproject/blog/templates目录里创建base.html的模板:

<html>
      <style type="text/css">
        body{color:#efd;background:#453;padding:0 5em;margin:0}
        h1{padding:2em 1em;background:#675}
        h2{color:#bf8;border-top:1px dotted #fff;margin-top:2em}
        p{margin:1em 0}
      </style>
     
      <body>
        <h1>Niger blog</h1>
        <h3>From Team Fith4_D3vil</h3>
        {% block content %}
        {% endblock %}
      </body>
</html>

修改archive.html模板,让它引用base.html模板和它的“content”块。

{% extends "base.html" %}
  {% block content %}
      {% for post in posts %}
      <h2>{{  post.title }}</h2>
      <p>{{ post.tiemstamp | date:"1,F jS"}}</p>
      <p>{{ post.body }}</p>
      {% endfor %}
  {% endblock %}

再次刷新页面,将看到不一样的风格。

13.pycharm开发

为什么上面要搭建那么复杂的环境,那是因为它是网站发布环境,对于django开发人员来说,上面所做的一切是万万不需要的。只需要一个pycharm,现在pycharm 4.0集成django开发,不管windows下还是linux下,只需要安装python,安装django(甚至不需要,pycharm会自动帮你安装),打开pycharm,默认页面是新建工程,选择django,输入工程名,app名即可。整个django框架自动建成,可直接运行。非常方便。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics