天天看點

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這些,怎麼登入,還記得我們建立的使用者嗎,登入即可。

(請問大家此時的頁面有沒有樣式呢,是下面哪樣呢。

CentOS + Python3.3 + Django1.7 + uwsgi + nginx + mysql web釋出環境搭建
CentOS + Python3.3 + Django1.7 + uwsgi + nginx + mysql web釋出環境搭建

有樣式的話,跳過,沒有的話,解決:

右鍵審查元素或者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目錄下的檔案到我們工程下,你會發現是完全對應的,

[[email protected] 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,

CentOS + Python3.3 + Django1.7 + uwsgi + nginx + mysql web釋出環境搭建

發現什麼,title,body,tiemstamp(哈哈,故意寫錯才能說明這是程式中我寫的呀),這3個變量是我們在class BlogsPost中定義的不是嗎。寫完後點選save,會提示The blogs post “BlogsPost object” was added successfully.,怎樣,是不是找到一點對應關系了呢。

CentOS + Python3.3 + Django1.7 + uwsgi + nginx + mysql web釋出環境搭建

但是你這個樣子,每次都是顯示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)      

注意每次代碼發生的變化,重新開機網站後,我們再來到網站同一位置,

CentOS + Python3.3 + Django1.7 + uwsgi + nginx + mysql web釋出環境搭建

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架構自動建成,可直接運作。非常友善。

繼續閱讀