从零开始在 Ubuntu 下部署 Nginx__uWSGI__Django 服务器

0 环境:

Ubuntu 16.04

1 准备工作

2 安装并配置虚拟环境(本机)

2.1 更新软件源

sudo apt-get update
sudo apt-get upgrade
  • update是更新软件列表
  • upgrade是对比本地软件版本和线上最新软件版本,然后升级

2.2 安装虚拟环境

sudo pip2 install virtualenv
  • virtualenv是虚拟环境安装包,创建虚拟环境可以更好地控制包的版本,包的版本不会因为2.1中的升级操作而升级,保证了项目的稳定性
  • 不同虚拟环境之间的运行环境相互独立,互不干扰
sudo pip2 install virtualenvwrapper
  • virtualenvwrappervirtualenv的扩展管理包,可以将所有的虚拟环境整合在一个目录下
  • 使用前需要先进行以下配置
  1. 创建虚拟环境管理目录
mkdir ~/.virtualenvs
  1. 打开.bashrc
sudo vi ~/.bashrc 
  1. .bashrc的末尾增加以下内容
export WORKON_HOME=$HOME/.virtualenvs  # 所有虚拟环境存储的目录
source /usr/local/bin/virtualenvwrapper.sh
  1. 启用配置文件
source ~/.bashrc

2.3 创建虚拟环境

mkvirtualenv django_blog
  • 创建虚拟环境需要联网
  • 创建完虚拟环境之后会自动进入虚拟环境,可以通过命令行前缀(下图红框)判断是否在虚拟环境内
  • 虚拟环境常用命令
# 创建虚拟环境
mkvirtualenv <name>

# 列出所有虚拟环境
workon TAB*2

# 进入虚拟环境
workon <name>

# 退出虚拟环境
deactivate

# 删除虚拟环境
rmvirtualenv <name>

2.4 安装django包

pip install django==1.8.2
  • 包后面加==用来选择包的版本

3 创建一个django演示项目(本机)

3.1 创建项目

django-admin startproject project_test
  • 项目建立在home目录或其子目录,以免权限问题带来的不便

3.2 创建应用

  • 进入项目目录并查看项目结构
cd project_test/
tree
  • 项目目前结构如下
  1. 创建应用
python manage.py startapp app_test
  • 创建应用后项目结构如下

3.3 修改项目配置

3.3.1 修改环境变量

  • 打开IDE(此处使用的是Pycharm)
  • 选择File/Settings,进入Project Interpreter,选择虚拟环境内的python版本
  • 如果选项内没有,就点击右侧的齿轮,选择Add Local,
    选择所在虚拟环境下的python版本,如/home/python/.virtualenvs/django_blog/bin/python2.7

3.3.2 创建模板文件夹、静态文件文件夹和应用urls

  • 在项目根目录分别创建statictemplates文件夹
  • static文件夹下创建jscssimg三个文件夹,以后用来存放静态文件
  • templates文件夹下创建app_test(应用名)文件夹,以后用来存放模板文件
  • 在应用文件夹下创建urls.py文件,以后用来存放应用的urls映射表
  • 创建完成之后的目录结构如下:

3.3.3 修改settings

  • 打开/project_test下的settings.py
  • 添加应用__在INSTALLED_APPS中将我们刚创建的应用加到最后面
  • 修改模板路径__在TEMPLATES里的DIRS修改为'DIRS': [BASE_DIR, 'templates'],
  • 修改静态文件路径__在最后添加
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

3.4 创建页面

3.4.1 修改项目urls

  • 打开/project_test下的urls.py,在urlpatterns内添加一行,意思是只要不是匹配到admin,都转到app_test应用
url(r'^', include('app_test.urls')),
  • 打开/app_test下的urls.py,添加以下内容:
#coding=utf-8
from django.conf.urls import  url
from . import views  # 从当前文件夹内引入views

urlpatterns = [
    url(r'^$', views.index),  # 匹配到根目录,就执行views文件内的index函数
]
  • 打开/project_test下的views.py,添加刚才urls.py内提到的index函数
#coding=utf-8
from django.shortcuts import render

# Create your views here.
def index(request):
    return render(request, 'app_test/index.html')
    # 对请求值不做任何处理,直接跳转到模板目录下app_test文件夹下的index.html页面
  • 将一张图片放在/static/img文件夹内
  • templates/app_test文件夹下,创建模板文件index.html,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
    <h1>下面有一张图片</h1>
    <img src="/static/img/test.jpg" alt="">  // 寻找static(settings里面的STATIC_URL)文件夹下img文件夹里的test.jpg图片
</body>
</html>

3.5 打开页面

  • 在项目根目录文件夹下,在终端内(确保已进入虚拟环境)
python manage.py runserver
  • 终端显示如下(红色字体暂不用管,因为我们并没有创建models):

  • 打开红框内显示的IP地址(127.0.0.1:8000)

  • 浏览器成功显示创建的页面

4 将项目上传至服务器(本机 & 服务器)

4.1 导出虚拟环境内的包(本机)

pip freeze > plist.txt
  • 此操作将虚拟环境内所有的包都保存在了list.txt里面

4.2 将项目文件夹整体上传至服务器

  • 传输文件可以用samba,ftp,scp等等,此处使用的是scp
scp -r <YOUR_LOCAL_PROJECT_DIR> <SERVER_USERNAME>@<SERVER_IP>:<YOUR_SERVER_PROJECT_DIR>

4.3 在服务器上安装虚拟环境(服务器)

  • 在服务器上重复2.1~2.3的步骤,安装虚拟环境
  • 进入虚拟环境,进入项目目录,根据本地计算机提供的包列表安装所需要的包
pip install -r plist.txt

5 安装uWSGI(服务器)

  • 安装Python开发版本(因为安装uWSGI过程中需要编译)
sudo apt-get install python-dev
  • 安装gcc(因为安装uWSGI过程中需要C编译器)
sudo apt-get install gcc
  • 安装uWSGI
pip install uwsgi
  • 使用uwsgi --version命令查看版本号,确认已正确安装

6 配置Django(服务器)

  • 配置项目settings,修改以下一项
ALLOWED_HOSTS = ['*', ]
  • 在项目根目录文件夹下,在终端内(确保已进入虚拟环境)
python manage.py runserver 0:8000
  • 在本地计算机浏览器中输入以下地址以测试Django在服务器上是否正常运行
<YOUR SERVER IP>:8000

2017.06.08更新
* 如果不能正常显示页面,一般为以下两个原因:

1.请检查防火墙状态,保证8000端口是能够被访问的,代码如下( 更多防火墙设置可以参考我这篇文章https://t.cn/RSuX8Qj

# 检查防火墙状态
sudo ufw status

# 可以临时关闭防火墙
sudo ufw disable

# 或者保持防火墙开启,允许8000端口连接
sudo ufw allow 8000

2.请检查服务器安全组规则,如阿里云服务器,可以在进入管理控制台后,按以下步骤设置( 如要了解更多服务器安全组规则设置,请参见阿里云官方文档https://t.cn/RST7Sgz

3.重启服务,再次在本地计算机浏览器中查看

  • 确定服务器正常后,打开settings,修改以下一项
DEBUG = False

7 配置uWSGI(服务器)

7.1 打通uWSGI和Python

  • 在项目根目录创建test.py文件,内容如下
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return ["Hello World"]  # python2
    # return [b"Hello World"]  # python3
  • 运行uWSGI(表示使用http协议,并使用8000端口,加载指定文件test.py)
uwsgi --http :8000 --wsgi-file test.py
  • 打开浏览器,输入
127.0.0.1:8000
  • 若显示’Hello World’则表示运行正常,说明以下三个环节是相通的
web client <-> uWSGI <-> Python

7.2 打通uWSGI和Django

  • 在项目根目录创建文件my_uwsgi.ini,并写入以下内容
[uwsgi]
# 使用nginx连接时使用
# socket = 0:8001

# 直接做web服务器使用
http = 0:8080

# 项目目录
chdir = /home/python/Desktop/project_test

# 项目中wsgi.py文件的目录
wsgi-file = /home/python/Desktop/project_test/project_test/wsgi.py

# 主进程
master = true

# 多进程&多线程
processes = 6
threads = 2

# .sock文件目录需与Nginx文件内的配置相同
# socket = /home/python/Desktop/project_test/my_sock.sock
# chmod-socket = 666

# 以守护进程的方式启动
vacuum = true


# 存储pid进程
pidfile=uwsgi.pid

# 存储log日志
daemonize=uwsgi.log
  • 启动uWSGI服务
uwsgi --ini my_uwsgi.ini
  • 终端显示以下内容即代表开启成功
[uWSGI] getting INI configuration from my_uwsgi.ini
  • 打开浏览器,地址栏输入以下地址
<YOUR_SERVER_IP>:8080
  • 可以看到,文字正常显示,图片无法显示,这是正常现象

  • 以上步骤说明以下三个环节是相通的

web client <-> uWSGI <-> Django
  • 停止uWSGI服务
uwsgi --stop uwsgi.pid

8 配置Nginx(服务器)

8.1 安装Nginx

  • 安装Nginx
sudo apt-get install nginx
  • Nginx安装成功后,系统会自动开启 Nginx 服务,默认使用80端口,打开浏览器并输入你服务器的IP地址,就可以看到 nginx 的测试页面
Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.
  • 说明以下两个环节是相通的
web client <-> the web server(Nginx)

8.2 配置Nginx

  • /etc/nginx/目录下的uwsgi_params复制到项目文件夹,对此文件不做任何改动
cp /etc/nginx/uwsgi_params .
  • 在项目根目录创建文件my_nginx.conf,并写入以下内容
upstream django {
    server    127.0.0.1:8001;
    # server      unix://home/python/Desktop/project_test/my_sock.sock;
}

server {
    listen      8000;  # 端口号
    server_name 127.0.0.1;  # 服务器 ip 或是域名
    charset     utf-8;  # 字符集

    # 最大上传限制
    # client_max_body_size 75M;

    location /media  {
        alias /home/python/Desktop/project_test/media_common;  # 媒体文件所在文件夹
    }

    location /static {
        alias /home/python/Desktop/project_test/static_common;  # 静态文件所在文件夹
    }


    # 将所有非媒体请求转到Django服务器上
    location / {
        uwsgi_pass      django;  # 最上方已定义
        # 将所有参数都转到uwsgi下
        include         /home/python/Desktop/project_test/uwsgi_params; # uwsgi_params的路径
    }
}

  • 这个配置文件表示将静态文件和媒体文件由Nginx处理,而其它的请求转入uWSGI处理

  • 与Nginx配置目录建立软链接

sudo ln -s /home/python/Desktop/project_test/my_nginx.conf /etc/nginx/sites-enabled/
  • 创建静态文件与媒体文件存放目录
sudo mkdir static_common
sudo mkdir media_common
  • 如果出现权限问题,将权限改下就好
chmod 777 static_common
chmod 777 media_common
  • 修改项目settings,在最后面添加
STATIC_ROOT = os.path.join(BASE_DIR, 'static_common')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media_common')
  • 进入项目根目录,执行静态文件迁移命令
python manage.py collectstatic
  • 提示输入选项时选yes即可

  • 重启Nginx服务

sudo /etc/init.d/nginx restart

9 Nginx & uWSGI & Django(服务器)

9.1 测试Nginx

  • 在浏览器内输入<YOUR_SERVER_IP>:8000/static/admin/css/base.css,检查是否能正常显示这个css文件

  • 将一张测试图片test.jpg放入media_common文件夹中,在浏览器中输入<YOUR_SERVER_IP>:8000/media/test.jpg,如果出现403则将图片的权限改为666,成功显示图片

9.2 测试uWSGI

  • 回到项目根目录,输入以下命令
uwsgi --socket :8001 --wsgi-file test.py
  • 打开浏览器,地址栏输入<YOUR_SERVBER_IP>,看是否能正常显示’Hello World’

9.3 用UNIX socket取代TCP port

  • 修改my_nginx.conf最终版如下:
upstream django {
    # server    127.0.0.1:8001;
    server      unix:///home/python/Desktop/project_test/my_sock.sock;
}

server {
    listen      8000;  # 端口号
    server_name songmingyao.com;  # 服务器 ip 或是域名
    charset     utf-8;  # 字符集

    # 最大上传限制
    # client_max_body_size 75M;

    location /media  {
        alias /home/python/Desktop/project_test/media_common;  # 媒体文件所在文件夹
    }

    location /static {
        alias /home/python/Desktop/project_test/static_common;  # 静态文件所在文件夹
    }


    # 将所有非媒体请求转到Django服务器上
    location / {
        uwsgi_pass      django;  # 最上方已定义
        # 将所有参数都转到uwsgi下
        include         /home/python/Desktop/project_test/uwsgi_params; # uwsgi_params的路径
    }
}
  • 修改my_uwsgi.ini最终版如下
[uwsgi]
# 使用nginx连接时使用
# socket = 0:8001

# 直接做web服务器使用
# http = 0:8080

# 项目目录
chdir = /home/python/Desktop/project_test

# 项目中wsgi.py文件的目录
wsgi-file = /home/python/Desktop/project_test/project_test/wsgi.py

# 主进程
master = true

# 多进程&多线程
processes = 6
threads = 2

# .sock文件目录需与Nginx文件内的配置相同
socket = /home/python/Desktop/project_test/my_sock.sock
chmod-socket = 666

# 以守护进程的方式启动
vacuum = true

# 存储pid进程
pidfile=uwsgi.pid

# 存储log日志
daemonize=uwsgi.log
  • 重启Nginx和uWSGI
sudo /etc/init.d/nginx restart

uwsgi --stop uwsgi.pid
uwsgi --ini my_uwsgi.ini
  • 打开浏览器,地址栏输入网址<YOUR_SERVER_IP>:8000,查看图片和文字是否显示正常

  • 此时以下环节已全部打通

web client <-> web server(nginx) <-> the socket <-> uwsgi <-> Django

9.4 服务器开机自启

  • 修改/etc/rc.local,添加以下内容到exit 0之前
/usr/local/bin/uwsgi --ini /home/python/Desktop/project_test/my_uwsgi.ini

说点什么

  Subscribe  
提醒