×

从0开始搭建nginx-uWSGI-Django-python服务器

96
填坑侠
2017.03.10 13:44* 字数 2685

最新心血来潮,想玩玩python于是自己花钱,租了一台阿里云服务器玩玩.

第一次搭建, 处于摸着石头过河阶段,踩了不少坑.写一篇文章,记录一下自己搭建的过程,以便为日后搭建的做个参考.

第一步:

用终端连接到阿里云服务器:


ssh root@139.xxx.xxx.129

输入服务器的密码登录成功

第二步:

更新apt-get(为什么要更新我也不知道...)


sudo apt-get update

sudo apt-get upgrade

第三步:

安装ssh(我选的阿里云ubuntu系统应该自带了):


sudo apt-get install ssh

第四步:

安装git(非必要):


sudo apt-get install git

第五步:

安装python3:

wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz
xz -d Python-3.6.0.tar.xz
tar -xvf  Python-3.6.0.tar
cd Python-3.6.0
./configure
make
sudo make install

第六步:

因为linux系统自带了Python2.7版本,所以要切换python的默认版本, 不然每次执行python命令的时候都要用python3 很麻烦.

切换python的默认版本

sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 100
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 150

第七步:

安装pip

sudo apt-get install python3-pip

第八步:
安装MySQL

sudo apt-get install mysql-server

第九步:
安装MySQL驱动:

sudo apt-get install mysql-connector

第十步:
运行mysql安全配置向导:

sudo mysql_secure_installation

输入root密码
是否修改root密码,因为前面已经设置过了,选n

是否移除匿名用户,肯定是要选y的

是否允许远程登陆,如果选n的话,只能在本机访问数据库,建议选y

是否移除test数据库,建议选是

重新加载权限表,选y

All done!

第十一步:

安装配置VirtualEnv和VirtualEnvWrapper

VirtualEnv可以管理多个开发环境,VirtualEnvWrapper使得VirtualEnv变得更好用

sudo pip install virtualenv virtualenvwrapper

安装完成以后,需要在环境变量中加入一些配置:

下面这句话是使用python3才需要执行的,python2不需要

echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc

不管python是什么版本,都要执行下面两句:

echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc

可以重启系统激活,也可以运行:

source ~/.bashrc

然后就可以开始建立虚拟环境了

第十二步:
接下来的内容参考自uWSGI官方文档英文不好, 欢迎指正!
创建虚拟环境:
这里有个坑, 因为通过ssh连接到远程服务器以后默认是在根目录root下面, 之前不懂,在这里创建虚拟环境, 后面服务器搭建起来以后访问会出现403禁止访问的错误, 所以为了避免这一问题, 建议在home目录下面创建虚拟环境

cd /home
virtualenv uwsgi-tutorial

激活虚拟环境:

cd uwsgi-tutorial
source bin/activate

第十三步:
在虚拟环境中安装Django:
这里有个坑, 执行pip install Django命令的时候默认安装的是Django的最新版本, 而最新版本, 在后面执行的时候会出现奇怪问题(主要是因为对Django不熟悉), 所以建议安装指定版本:

pip install Django==1.10.1
django-admin.py startproject mysite
cd mysite

第十四步:
安装uWSGI:

pip install uwsgi

第十五步:
测试uWSGI:
创建test.py

vim test.py

按i进入编辑模式, 输入一下内容:

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

运行uWSGI:

uwsgi --http :8000 --wsgi-file test.py

这些选项的意思是:

--http :8000 使用http协议, 端口号8000

wsgi-file test.py 加载指定的文件test.py

当你用浏览器访问

http:139.xxx.xxx.129:8000的时候应该能看到hello word文字

这说明下面这个流程是通的:

the web client <-> uWSGI <-> Python

第十六步:

测试Django项目:

现在我们希望uWSGI运行一个Django站点来达到运行test.py时一样的效果:

首先要确保mysite项目是可以正常运行的:

python manage.py runserver 0.0.0.0:8000

在浏览器输入http://139.xxx.xxx.129:8000如果看到站点的成功提示, 就说明是没问题的.

用uWSGI运行Django项目:

uwsgi --http :8000 --module mysite.wsgi

module mysite.wsgi 指令的意思是加载指定的wsgi模块

在浏览器输入http://139.xxx.xxx.129:8000如果看到站点的成功提示, 就说明下面这个流程是通的

the web client <-> uWSGI <-> Django

通常情况下我们不会让服务器同uWSGI直接会话,那是webserver的工作.

第十七步:

安装nginx:

sudo apt-get install nginx

运行:

sudo /etc/init.d/nginx start

在浏览器输入http://139.xxx.xxx.129:80应该能看到,“Welcome to nginx!”.这说明下面这个流程是通的

the web client <-> the web server

第十八步:

为你的站点配置nginx:

你需要uwsgi_params文件, 他在/etc/nginx目录下, 把它复制到你的工程目录下

cp /etc/nginx/uwsgi_params /home/uswgi-tutorial/mysite/uwsgi_params

等会我们会让nginx引用这个文件.

现在创建mysite_nginx.conf文件

vim mysite_nginx.conf

点击i键进入编辑模式,输入下面的内容:

# mysite_nginx.conf

# the upstream component nginx needs to connect to

upstream django {

        # server unix:///path/to/your/mysite/mysite.sock; # for a file socketserver                    127.0.0.1:8001;# for a web port socket (we'll use this first)

}

# configuration of the server

server {

    # the port your site will be served on 

    listen      8000;# the domain name it will serve for

    server_name .example.com;# substitute your machine's IP address or FQDN

    charset    utf-8;

    # max upload size

    client_max_body_size 75M;# adjust to taste

    # Django media

    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 / {

        uwsgi_pass  django;

        include    /path/to/your/mysite/uwsgi_params;# the uwsgi_params file you installed

    }

}

这个配置文件告诉nginx从文件系统中提供media和static的服务来处理访问Django’s的请求.

建立从/etc/nginx/sites-enabled到mysite_nginx.conf文件的链接, 以便nginx可以使用它:

sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/

部署静态文件:

在运行nginx之前, 你需要收集static目录下的所有Django静态文件, 首先你需要编辑mysite/settings.py文件, 并在末尾加入下面一行文字:

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

然后运行

python manage.py collectstatic

指令.

第十九步:

nginx基本测试:

重启nginx:

sudo /etc/init.d/nginx restart

为了测试media文件夹能否正常提供服务, 在media目录下添加一个media.png图片.(这里有一个坑: media文件是自己手动创建的, 在mysite目录下, 前面cd到mysite文件夹下以后,运行ls指令看下子文件,发下在mysite文件夹下面还有一个mysite文件夹, 而我们现在创建的这个media文件夹是在第一个mysite文件夹下面,不是第二个mysite文件夹下面, 我之前就放在第二个mysite文件夹下面, 踩了这个坑!)

mkdir media

cd media

下载一张png图片,地址自己百度

wget http://picture.baidu.com/media.png 

在浏览器输入http://139.xxx.xxx.129:8000/media/media.png如果能看到png图片, 至少说明nginx是可以正常提供服务的.

第二十步:

通过nginx和uSWGI提供test.py服务.

用nginx通过test.py程序说hello word!

这里有个坑, 之前为了创建图片cd到了media文件下, 此时执行下面的指令需要返回 mysite目录下, 不然找不到test.py文件

uwsgi --socket :8001 --wsgi-file test.py

这和之前的指令非常相似, 除了有一个选项不同之外.

socket :8001 指令的意思是: 使用uwsgi协议 端口号8001

外界可以通过8000端口访问nginx, 此时nginx已经被配置为在8001端口上使用uwsgi进行交流(信息交换).

在浏览器中输入http://139.xxx.xxx.129:8000来检查是否正常.

如果正常则下面的流程是通的:

the web client <-> the web server <-> the socket <-> uWSGI <-> Python

于此同时你可以尝试通过http://139.xxx.xxx.129:8001来查看uwsgi的输出, 很可能什么都没有, 因为浏览器使用http协议来访问的而不是uWSGI协议, 所以你应该在你的终端中查看uwsgi的输出.

第二十一步;

使用Unix sockets代替Ports:

到目前为止,我们使用了TCP的socket端口, 因为它很简单,但事实上, 使用Unix sockets比ports更好.但是需要做一点小小的改动.

编辑mysite_nginx.conf,找到下面这段文字, 并改成下面这个样子:

server unix:///path/to/your/mysite/mysite.sock;# for a file socket

# server 127.0.0.1:8001; # for a web port socket (we'll use this first)

然后重启nginx.

运行

uwsgi --socket mysite.sock --wsgi-file test.py

这一次的socket选项告诉uWSGI使用哪一个文件.

在浏览器中输入http://139.xxx.xxx.129:8000检查是否能够正常访问.

如果不能正常访问, 运行:

uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666# (very permissive)

你也许还需要添加你的用户到nginx`s的用户组里, 以便nginx可以正确的读写你的socket.

为nginx的log新开一个终端窗口是非常值得的, 方便你可以轻松的查看遇到的问题.

第二十二步:

使用uWSGI和nginx运行Django application

uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=666

这里有一个坑, 之前按照官方文档上的664权限运行不成功, 后来改成666权限就成功了!

现在uWSGI和nginx提供的应该不再是"Hello word!"服务, 而是你的Django项目.

第二十三步:

通过配置.ini文件运行uWSGI.

在使用uWSGI的时候我们可以把同样的指令放在一个文件中, 然后让uWSGI使用这个文件来运行,这让我们管理配置的工作变的更简单.

创建一个mysite_uwsgi.ini文件.

vim mysite_uwsgi.ini

按i建进入编辑模式, 输入下面的内容(以#开头的都是注释, 可以忽略):

# mysite_uwsgi.ini file

[uwsgi]

# Django-related settings

# the base directory (full path)

chdir = /path/to/your/project

# Django's wsgi file

module = project.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

# ... with appropriate permissions - may be needed

# chmod-socket    = 664

# clear environment on exit

vacuum = true

然后使用这个文件来运行uWSGI:

这里有个坑, 按照官方文档那样运行

uwsgi --ini mysite_uwsgi.ini# the --ini option is used to specify a file

并不能像我们期望的那样工作, 但是运行

uwsgi --ini mysite_uwsgi.ini --chmod-socket=666

就可以按照我们期望的那样工作, 所以权限问题实在是一个大问题

再检查一次Django站点是否像期望的那样工作.

第二十四步:

在系统上安装uWSGI(之前的安装都是在虚拟环境下进行的, 只在当前的虚拟环境下生效):

到目前为止,我们只在当前的虚拟环境下安装了uWSGI.为了方便部署我们需要把它安装在系统上.

退出虚拟环境:

deactivate

注意: 从上面创建虚拟环境, 并进入虚拟环境到现在所在一些操作都是在虚拟环境下进行的, 请确保你在这个过程中没有退出虚拟环境.

在系统上安装uWSGI:

sudo pip install uwsgi

uWSGI的wiki描述在installation procedures,在系统上安装uWSGI之前需要考虑一下哪个版本是最合适的.

再检查一次确保uWSGI可以像之前一样正常工作.

uwsgi --ini mysite_uwsgi.ini --chmod-socket=666 # the --ini option is used to specify a file

这里有个坑, uWSGI官方文档上, 介绍了Emperor mode, 然而我按照官方文档上的描述, 继续按照Emperor mode进行, 发现行不通, 报警告重新用pcre build什么的.(对我这种小白来说真是一窍不通).其实接下来只要uWSGI在开机时启动就行了.

第二十五步:

让uWSGI在系统启动的时候启动.

最后一步是让这些都在系统启动的时候自动执行.

在很多系统里, 让程序在系统启动的时候自动启动的最简单的方式就是使用rc.local文件.

编辑/etc/rc.local文件

vim /etc/rc.local

并在exit 0这一行之前加上下面这句话

/usr/local/bin/uwsgi --ini /path/to/your/project/mysite_uwsgi.ini --chmod-socket=666

退出编辑

reboot

大功告成, uWSGI可以随系统启动了!

折腾了四五天!oh my god!

参考文章:

Ubuntu+Django+Nginx+uWSGI+Mysql搭建Python Web服务器

uWSGI官方文档

ubuntu下安装nginx时依赖库zlib,pcre,openssl安装方法

日记本
Web note ad 1