当前位置: 澳门新濠3559 > 编程 > 正文

只是用户并非真实的在与8000端口交流,把djsite项

时间:2019-11-08 04:40来源:编程
还有问题? 你可能发现了,你网页上的静态资源无法访问!!比如说admin页面,会特别简陋,这是因为nginx+uwsgi+Django时,Django对静态资源的处理nginx不能代理(可能吧)。总之这种事不

还有问题?

你可能发现了,你网页上的静态资源无法访问!!比如说admin页面,会特别简陋,这是因为nginx+uwsgi+Django时,Django对静态资源的处理nginx不能代理(可能吧)。总之这种事不该让Django做,因为nginx在处理静态资源上能力更强,对于静态资源,就让nginx处理吧。 
通常来说,你会有两种静态资源/media/开头的链接和/static/开头的。static用来处理一些网站原始图片,视频,js,css文件,Django是自己就支持这种链接的。那么如何关闭让Django处理/static/开头的文件呢,很简单,在setting.py中将DEBUG值改为False,这时,Django就不去处理/static/文件了。 
那么/media/呢?一般来说,用户上传的图片,我们会保存起来,在网页上显示时候就用/media/,在setting.py中设置

MEDIA_URL = '/media/' #访问的前缀链接
MEDIA_ROOT = os.path.join(BASE_DIR, '../media') #存放文件的具体位置

再在url.py中添加

from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 

这里的意思是在DEBUG=True时,会解析/media/文件,文件存放的位置是第二个参数。 
如此一来当即在部署为生产环境时,只需要吧DEBUG改为False,Django就不会去处理staticmedia了。

加速静态资源

1、修改nginx配置djsite.voidking.com.conf:

server {
    listen      80;
    server_name djsite.voidking.com;
    charset     utf-8;

    location / {
        uwsgi_pass     127.0.0.1:8000;
        include        uwsgi_params;
    }

    location /static {
        alias /root/djsite/collectedstatic;
    }
}

2、修改nginx.conf

user root;

3、重启nginx
./nginx -s reload

前言

《Django开发简单Blog系统》系列中,我们已经完成了一个迷你Web项目。那么,怎么把这个项目发布到线上呢?怎样给它一个域名呢?

思路:nginx + uwsgi

试一下:

只是用户并非真实的在与8000端口交流,把djsite项目部署到/home/web目录中。如何安装?

pip install uwsgi

守护uwsgi

1、在/etc/supervisor中新建djsite.conf文件:

[program:djsite]
command=/root/.pyenv/versions/3.6.1/bin/uwsgi --http :8000 --chdir /home/web/djsite/ --module django_wsgi --static-map=/static=static
directory=/home/web/djsite/
startsecs=0
stopwaitsecs=0
autostart=true
autorestart=true

2、重启supervisor

ps aux | grep supervisord
systemctl stop supervisord
systemctl start supervisord

附:重启djsite命令

supervisorctl -c /etc/supervisord.conf restart djsite

3、测试访问
http://ip:8000/blog/index
页面显示正常,至此守护进程配置成功。

4、djsite.conf可以精简修改为:

[program:djsite]
command=/root/.pyenv/versions/3.6.1/bin/uwsgi --ini uwsgi.ini
directory=/home/web/djsite/
startsecs=0
stopwaitsecs=0
autostart=true
autorestart=true

安装pyenv

为了使用supervisor,我们需要python2.7的环境。而多版本python的管理,推荐使用pyenv。

1、安装pyenv套装
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
内容除了包含 pyenv 以外,还包含如下插件:

  • pyenv-doctor
  • pyenv-installer
  • pyenv-update
  • pyenv-virtualenv
  • pyenv-which-ext

2、路径添加
vim ~/.bash_profile,添加:

export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

3、使配置立即生效
source ~/.bash_profile

4、查看安装情况
pyenv -v

5、常用命令

  • 查看可安装的python版本列表:pyenv install -l
  • 安装指定版本的python:pyenv install 2.7.3
  • 查看已安装的python:pyenv versions
  • 查看当前设为默认的python版本:pyenv version

Debian 和Ubuntu:

为何还需要这东西

简单来说,nginx属于反向代理服务器,他能做什么事呢?监听一个端口,比如说80,可以配置一个反向代理端口,比如8000,这样,所有外部用户对80端口的访问实际上都是请求了8000端口的数据,只是用户并非真实的在与8000端口交流,而是通过了80这座桥梁。目前自己只觉得这样能隐藏自己的真实端口,大家有什么高见请留言指出。 
既然如此,那么实际上还是只能单用户访问,所以我们需要一个可以多用户并发访问的工具,那么便是uwsgi了。

启动项目

1、启动命令
python manage.py runserver

2、服务器测试访问
curl localhost:8000/blog/index

3、本地测试访问
使用浏览器查看 http://ip:8000/blog/index ,无法访问。
启动命令改为:python manage.py runserver 0.0.0.0:8000,此时即可在浏览器看到部署好的项目。

如果还是不能访问,尝试先关闭防火墙:systemctl stop firewalld

启动项目

# mysite_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    # 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)
}

# 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
    }
}

uwsgi

高级启动

1、新建uwsgi.ini,与manage.py在同一级目录。

[uwsgi]
http = :8000
chdir = /home/web/djsite/
wsgi-file = django_wsgi.py
static-map = /static=static

2、启动uwsgi
uwsgi uwsgi.ini

3、测试访问
http://ip:8000/blog/index

数据库问题

cd djsite
python manage.py runserver

报错:

File "/usr/local/python3/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 36, in <module>
    raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None

解决办法:

vim /usr/local/python3/lib/python3.6/site-packages/django/db/backends/mysql/base.py

进入vim命令模式,输入/version,按N查找下一个,找到:

if version < (1, 3, 3):
    raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)

注释掉它,问题解决。

如果你的Django工程叫abc,我建议你把它的全部内容都拷贝到/var/www/中。然后你的工程的manage.py文件就在/var/www/abc/中,这样可以避免因文件权限,带来的一些不能提供服务的问题。

收集静态文件

Django有一个工具可以将应用里用到的所有静态文件收集起来,方便nginx解析。具体: 
setting.py中设置STATIC_ROOT = os.path.join(BASE_DIR, '../collectedstatic') 
这样收集的静态文件就都放进上面的目录里了。如何运行这个工具?python3 manager.py collectstatic

配置supervisor

1、开机启动
systemctl enable supervisord

2、生成配置文件

mkdir -p /etc/supervisor/
echo_supervisord_conf > /etc/supervisord.conf

3、修改配置文件
vim /etc/supervisord.conf,添加:

[include]
files = /etc/supervisor/*.conf

4、运行
supervisord -c /etc/supervisord.conf

高级启动

1、新建uwsgi.ini,与manage.py在同一级目录。

[uwsgi]
http = :8000
chdir = /root/djsite/
wsgi-file = django_wsgi.py
static-map = '/static=static'

2、启动uwsgi
uwsgi uwsgi.ini

3、测试访问
http://ip:8000/blog/index

用你的Django工程代替test.py

配置nginx解析静态文件

同样,nginx.conf 
首先,在文件顶部加入 
user root 
声明让root用户跑nginx,否则访问静态文件可能提示没有权限 
其次,在上面说的配置文件location /前加入以下带内容

        location /static/ {
            autoindex on;
            alias /root/SchoolBuyWeb/collectedstatic/;
        }

        location /media/ {
            autoindex on;
            alias /root/SchoolBuyWeb/media/;
        }

注意alias后对应好自己设定的目录即可! 
重启nginx,现在已经ok了~~

supervisor

uwsgi

pip install uwsgi

编写测试:

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

启动测试:
uwsgi --http :8001 --wsgi-file test.py

报错:uwsgi: command not found,看来我们需要把python3/bin加入到path。
vim /etc/profile,在文件最底部找到PATH,添加:

:/usr/local/python3/bin

使配置生效:source /etc/profile

访问 http://ip:8001 ,即可看到Hello World 。

配置 nginx

配置nginx

找到nginx.conf,写入如下内容

    server {
        #这里是访问时用到的端口
    listen       80;
        server_name  localhost;

        charset UTF-8;
        #这块存让日志文件
        access_log  /var/log/nginx/SchoolBuy_access.log;
        error_log   /var/log/nginx/SchoolBuy_error.log;


        client_max_body_size 75M;
        location / {
                include uwsgi_params;
                #同uwsgi内容
                uwsgi_pass 127.0.0.1:8001;
                #链接超时时间
                uwsgi_read_timeout 30;
        }
    }

 

如此一来,重启你的nginx,访问80端口,就能看到效果了。

安装uwsgi

pip install uwsgi

编写测试:

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

启动测试:
uwsgi --http :8001 --wsgi-file test.py

访问 http://ip:8001 ,即可看到Hello World 。

项目部署

为了测试我们是不是可以提供访问媒体文件的服务,找张图片比如"abc.png",放到你的Django工程中的媒体目录下,比如/var/www/project/project/media。然后访问

配置文件

首先给大家看看我项目的文件状态:

FlyCold
├── FlyCold
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── SchoolBuy
│   ├── admin.py
│   ├── forms.py
│   ├── __init__.py
│   ├── models.py
│   ├── urls.py
│   └── views.py
└── templates

 

解释以下,这个是精简后的目录树,创建的项目名为FlyCold,生成的FlyCold子目录及SchoolBuy子目录。我的主要代码在SchoolBuy里,setting.py在Flycold子目录里,manager.py在FlyCold根目录里。 
安装之后来一个配置文件,内容如下

# myweb_uwsgi.ini file
[uwsgi]

# Django-related settings

socket = :8080
#真实服务的端口

# Django项目根目录 (绝对路径)
chdir           = /home/lyt/FlyCold

# wsgi.py文件在项目中的位置
module          = FlyCold.wsgi

# process-related settings
# master
master          = true

# 运行的进程数
processes       = 4

# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true

 

这个.ini文件可以放在任何地方,启动的时候uwsgi --ini ***.ini

数据库准备

1、创建数据库

# mysql -uroot -p
mysql> create database `djsite` default character set utf8 collate utf8_general_ci; 

2、修改mysql的binlog格式为混合模式:

mysql> set global binlog_format=mixed;
mysql> exit;

3、修改djsite/djsite/settings.py中的数据库配置
vim djsite/djsite/settings.py

4、创建表结构

python manage.py makemigrations
python manage.py migrate

nginx和mysql

参考《在CentOS7上配置PHP运行环境》,安装好了nginx和mysql。

sudo yum install nginx
sudo service nginx start

静态资源问题(可忽略)

假设,uwsgi.ini为:

[uwsgi]
http = :8000
chdir = /home/web/djsite/
wsgi-file = django_wsgi.py

静态资源就无法访问了。在不添加static-map的情况下,需要修改两个文件:
(1)修改djsite/djsite/settings.py文件,添加:

STATIC_ROOT = '/home/web/djsite/static/'

(2)修改djsite/djsite/settings.py文件为:

from django.conf.urls import url,include
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^blog/', include('blog.urls', namespace='blog')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

数据库准备

1、创建数据库

# mysql -uroot -p
mysql> create database `djsite` default character set utf8 collate utf8_general_ci; 
mysql> exit;

2、修改djsite/djsite/settings.py中的数据库配置
vim djsite/djsite/settings.py

3、创建表结构

python manage.py makemigrations
python manage.py migrate

报错:

django.db.utils.InternalError: (1665, 'Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.')

修改mysql的binlog格式为混合模式:

# mysql -uroot -p
mysql> set global binlog_format=mixed;

删除数据库djsite中的所有表,然后再次执行:

python manage.py migrate

编辑我们刚才的nginx配置文件mysite_nginx.conf,做以下更改:

前言

《Django部署到线上》一文中,很多步骤不是必须的,有些部分甚至是错误的,本文就精简修改一下。
目标:把djsite项目部署到/home/web目录中,并且给它分配一个域名为djsite.voidking.com。

uwsgi

创建一个测试文件test.py:

nginx配置

1、首先,在万网上配置域名解析,添加A记录,解析到阿里云服务器IP。假设解析好的域名为django.voidking.com。

2、在nginx的vhost中,添加django.voidking.com.conf,内容为:

server {
    listen 80;
    server_name django.voidking.com;
    charset utf-8;
    location /{
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
        client_max_body_size       1024m;
        client_body_buffer_size    128k;
        client_body_temp_path      data/client_body_temp;
        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;
        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
        proxy_temp_path            data/proxy_temp;

        proxy_pass http://127.0.0.1:8000;
    }
}

3、重启nginx,./nginx -s reload

4、测试访问
服务器:curl django.voidking.com/blog/index
本地浏览器:http://django.voidking.com/blog/index

至此,django项目已经部署成功,没有用到uwsgi。如果给django添加守护进程,那么我们的部署就接近完美了。那么,uwsgi又能干什么呢,我们继续研究。

安装虚拟环境

1、新建supervisor虚拟环境
pyenv virtualenv 2.7.13 supervisor

2、激活虚拟环境
source /root/.pyenv/versions/2.7.13/envs/supervisor/bin/activate supervisor
或者source activate supervisor

3、安装supervisor
yum install supervisor
pip install supervisor

4、生成配置文件

mkdir -p /etc/supervisor/
echo_supervisord_conf > /etc/supervisord.conf

5、修改配置文件
vim /etc/supervisord.conf,添加:

[include]
files = /etc/supervisor/*.conf

6、运行
/root/.pyenv/versions/2.7.13/envs/supervisor/bin/supervisord -c /etc/supervisord.conf

7、编辑supervisord.service
vi /usr/lib/systemd/system/supervisord.service,修改为:

[Unit]
Description=Process Monitoring and Control Daemon
After=rc-local.service nss-user-lookup.target

[Service]
Type=forking
ExecStart=/root/.pyenv/versions/2.7.13/envs/supervisor/bin/supervisord -c /etc/supervisord.conf  
ExecReload=/root/.pyenv/versions/2.7.13/envs/supervisor/bin/supervisorctl reload       
ExecStop=/root/.pyenv/versions/2.7.13/envs/supervisor/bin/supervisorctl shutdown      

[Install]
WantedBy=multi-user.target

8、重启supervisor

ps aux | grep supervisord
systemctl stop supervisord
systemctl start supervisord

9、开机启动
systemctl enable supervisord

现在应该在浏览器中能看到你的工程了。

python虚拟机

1、安装pyenv套装
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
内容除了包含 pyenv 以外,还包含如下插件:

  • pyenv-doctor
  • pyenv-installer
  • pyenv-update
  • pyenv-virtualenv
  • pyenv-which-ext

2、路径添加
vim ~/.bash_profile,添加:

export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

3、使配置立即生效
source ~/.bash_profile

4、查看安装情况
pyenv -v

5、常用命令

  • 查看可安装的python版本列表:pyenv install -l
  • 安装指定版本的python:pyenv install 3.6.1
  • 查看已安装的python:pyenv versions
  • 查看当前设为默认的python版本:pyenv version

supervisor

关闭shell后,uwsgi服务就很快关闭了。为了让它后台运行,需要让它变成守护进程。

nginx的安装和基本配置:

supervisor

1、安装

yum install python-pip
yum install supervisor
pip install supervisor

2、创建sock

touch /tmp/supervisor.sock
chmod 777 /tmp/supervisor.sock

代码准备

1、克隆项目到服务器
git clone https://github.com/voidking/djsite.git

2、安装django
pip install django

3、安装pymysql
pip install pymysql

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

nginx+uwsgi

以上,我们的djsite项目已经通过uwsgi方式启动起来,并且可以保持后台运行。nginx配置不改变的情况下,我们可以正常访问 http://django.voidking.com/blog/index 。此时,nginx作为反向代理,和uwsgi间通过http交互。

接下来,就配置下nginx和uwsgi通过socket结合的方式。原理:用户发送http请求到nginx,nginx通过socket把请求交给uwsgi,uwsgi拿到django的处理结果,通过socket返还给nginx,nginx通过http返回结果给用户。

1、因为nginx和uwsgi通过socket方式交互,我们需要修改uwsgi.ini的配置为:

[uwsgi]
socket = :8000
chdir = /home/web/djsite/
wsgi-file = django_wsgi.py
static-map = /static=collectedstatic
master = true
processes = 2
enable-threads = true
daemonize = /home/web/djsite/uwsgi.log

2、重启supervisor
systemctl stop supervisord
systemctl start supervisord

3、修改nginx配置djsite.voidking.com.conf:

server {
    listen      80;
    server_name djsite.voidking.com;
    charset     utf-8;

    location / {
        uwsgi_pass     127.0.0.1:8000;
        include        uwsgi_params;
    }
}

5、重启nginx
./nginx -s reload

6、测试访问
此时,访问 http://ip:8000/blog/index 失败,访问 http://django.voidking.com/blog/index 正常。因为8000端口不再提供http服务,而是一个和nginx连接的socket。

环境准备

如果你还没有pip,那么装上它:

admin静态资源问题

如果以python manage.py runserver启动django,那么静态资源没有问题。

如果以uwsgi启动django,静态资源看起来没有问题,但是,如果访问 http://ip:8000/admin ,就会发现这个页面的静态资源无法获取。

一个Django应用,一般有两类静态文件。一是应用内的静态文件,二是Django自带的静态文件。应用内的静态文件在djsite/static目录下。此外,在INSTALLED_APPS中配置了django.contrib.admin, 则还会有另外一组静态文件,在Django安装位置里。

例如,一个root在Python 3.6版本安装的Django,admin的静态文件在: /usr/local/lib/python3.6/site-packages/django/contrib/admin/static/admin/。

最终,在STATIC_URL里,会有两类静态文件, /static/*/static/admin/*

了解原理,原因就很显然了。python manage.py runserver知道静态文件的位置,而uWSGI不知道静态文件在什么位置。

解决办法如下:
(1)修改djsite/djsite/settings.py文件:

SITE_ROOT = os.path.dirname(os.path.abspath(__file__))
SITE_ROOT = os.path.abspath(os.path.join(SITE_ROOT, '../'))
STATIC_ROOT = os.path.join(SITE_ROOT, 'collectedstatic')

(2)收集所有静态文件到collectedstatic目录
python manage.py collectstatic

(3)修改uwsgi.ini配置

[uwsgi]
http = :8000
chdir = /home/web/djsite/
wsgi-file = django_wsgi.py
static-map = /static=collectedstatic

查看效果

cd djsite
python manage.py runserver

启动成功,在服务器上测试访问:
curl localhost:8000/blog/index

使用浏览器查看 http://ip:8000/blog/index ,却无法访问。这是因为在settings.py中,ALLOWED_HOSTS的配置为:

ALLOWED_HOSTS = []

官方文档说:

When DEBUG is True and ALLOWED_HOSTS is empty, the host is validated against ['localhost', '127.0.0.1', '[::1]'].

修改ALLOWED_HOSTS的配置为:

ALLOWED_HOSTS = ['*']

然后启动命令改为:python manage.py runserver 0.0.0.0:8000,此时即可在浏览器看到部署好的项目。

如果还是不能访问,尝试先关闭防火墙:systemctl stop firewalld

如果能看到Hell World,说明我们打通的桥梁变成:

项目部署

安装supervisor

pip install supervisor

报错,因为supervisor不支持python3:
Supervisor requires Python 2.4 or later but does not work on any version of Python 3. You are using version 3.6.1 (default, Dec 6 2017, 12:03:59)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]. Please install using a supported version.
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-y9wv4fmm/supervisor/

去吃饭了

一般启动

1、编写wsgi.py文件
编写django_wsgi.py文件,将其放在与文件manage.py同一个目录下。

#!/usr/bin/env python
# coding: utf-8

import os,django
from django.core.handlers.wsgi import WSGIHandler

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djsite.settings")
django.setup()
application = WSGIHandler()

2、启动项目
uwsgi --http :8000 --chdir /home/web/djsite/ --module django_wsgi

3、查看启动结果
lsof -i :8000ps aux | grep uwsgi

4、测试访问
http://ip:8000/blog/index
此时,页面是没有样式的,也就是说静态资源加载失败。

5、配置静态资源
uwsgi --http :8000 --chdir /home/web/djsite/ --module django_wsgi --static-map=/static=static
此时,页面样式就正常了。

url问题

cd djsite
python manage.py runserver

再次报错:

File "/root/djsite/djsite/urls.py", line 21, in <module>
    url(r'^blog/', include('blog.urls', namespace='blog')),
  File "/usr/local/python3/lib/python3.6/site-packages/django/urls/conf.py", line 39, in include
    'Specifying a namespace in include() without providing an app_name '
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.

解决办法:

vim /usr/local/python3/lib/python3.6/site-packages/django/urls/conf.py

找到:

if namespace and not app_name:
    raise ImproperlyConfigured(
        'Specifying a namespace in include() without providing an app_name '
        'is not supported. Set the app_name attribute in the included '
        'module, or pass a 2-tuple containing the list of patterns and '
        'app_name instead.',
    )

注释掉它,问题解决。

首先确信一下我们的工程本身能正常运行,在终端进入你的工程目录,然后敲入:

安装python3.6

1、配置pyenv下载源为本地目录(可选操作,不做的话下载速度会很慢)

mkdir /root/python/ && cd /root/python/

# 设置变量
export PYTHON_BUILD_CACHE_PATH=/root/python

# 设置变量
export PYTHON_BUILD_MIRROR_URL=/root/python

# 查看变量设置
env | grep PYTHON_BUILD_MIRROR_URL

wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz

2、安装python3.6.1,pyenv install 3.6.1
报错,ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib? 需要安装依赖包:

yum install readline readline-devel readline-static -y
yum install openssl openssl-devel openssl-static -y
yum install sqlite-devel -y
yum install bzip2-devel bzip2-libs -y

3、改变全局版本
pyenv global 3.6.1python -V

附:改变回原版本
pyenv global systempython -V

4、刷新数据库
python rehash

安装python2.7环境

1、配置pyenv下载源为本地目录(可选操作,不做的话下载速度会很慢)

mkdir /root/python/ && cd /root/python/

# 设置变量
export PYTHON_BUILD_CACHE_PATH=/root/python

# 设置变量
export PYTHON_BUILD_MIRROR_URL=/root/python

# 查看变量设置
env | grep PYTHON_BUILD_MIRROR_URL

wget https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tar.xz

2、安装python2.7.13
pyenv install 2.7.13

3、改变全局版本
pyenv global 2.7.13python -V

附:改变回原版本
pyenv global systempython -V

4、刷新数据库
python rehash

前面nginx已经被设置好在8001端口与uWSGI通信,同时在外界服务被布置在8000端口,访问:

环境准备

nginx+uwsgi

以上,我们的djsite项目已经通过uwsgi方式启动起来,并且可以保持后台运行。nginx配置不改变的情况下,我们可以正常访问 http://django.voidking.com/blog/index 。此时,nginx作为反向代理,和uwsgi间通过http交互。

接下来,就配置下nginx和uwsgi通过socket结合的方式。原理:用户发送http请求到nginx,nginx通过socket把请求交给uwsgi,uwsgi拿到django的处理结果,通过socket返还给nginx,nginx通过http返回结果给用户。

1、因为nginx和uwsgi通过socket方式交互,我们需要修改uwsgi.ini的配置为:

[uwsgi]
socket = :8000
chdir = /root/djsite/
wsgi-file = django_wsgi.py
static-map = '/static=static'
master = true
processes = 2
enable-threads = true
# daemonize = /root/djsite/uwsgi.log

2、/etc/supervisor/djsite.conf,修改为

[program:djsite]command=/usr/local/python3/bin/uwsgi uwsgi.ini
directory=/root/djsite/
startsecs=0
stopwaitsecs=0
autostart=true
autorestart=true

3、重启supervisor
systemctl stop supervisord
systemctl start supervisord

4、修改nginx配置djsite.voidking.com.conf:

server {
    listen      80;
    server_name djsite.voidking.com;
    charset     utf-8;

    location / {
        uwsgi_pass     127.0.0.1:8000;
        include        uwsgi_params;
    }

    location /static {
        alias /root/djsite/static;
    }
}

5、重启nginx
./nginx -s reload

6、测试访问
此时,访问 http://ip:8000/blog/index 失败,访问 http://django.voidking.com/blog/index 正常。因为8000端口不再提供http服务,而是一个和nginx连接的socket。

7、static
请问,此时的静态资源,是通过uwsgi获取的?还是通过nginx直接获取的?做一个测试即可,修改uwsgi为:

[uwsgi]
socket = :8000
chdir = /root/djsite/
wsgi-file = django_wsgi.py
# static-map = '/static=static'
master = true
processes = 2
enable-threads = true
# daemonize = /root/djsite/uwsgi.log

此时,uwsgi不再提供静态资源。重启supervisor,页面样式正常,可见,静态资源是通过nginx获取的。之所以可以获取到,是因为我们之前在djsite/settings.py中配置了:

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)
uwsgi --socket :8001 --wsgi-file test.py

代码准备

1、在/home/web目录中,执行命令克隆项目
git clone https://github.com/voidking/djsite.git

2、安装django
pip install django==1.11.7

3、安装pymysql
pip install pymysql

一般启动

1、编写wsgi.py文件
编写django_wsgi.py文件,将其放在与文件manage.py同一个目录下。

#!/usr/bin/env python
# coding: utf-8

import os,django
from django.core.handlers.wsgi import WSGIHandler

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djsite.settings")
django.setup()
application = WSGIHandler()

2、启动项目
uwsgi --http :8000 --chdir ~/djsite/ --module django_wsgi

3、查看启动结果
lsof -i :8000ps aux | grep uwsgi

4、测试访问
http://ip:8000/blog/index
此时,页面是没有样式的,也就是说静态资源加载失败。

5、配置静态资源
uwsgi --http :8000 --chdir ~/djsite/ --module django_wsgi --static-map=/static=static
此时,页面样式就正常了。

基本nginx测试

小结

至此,django部署完毕,我们实现了三种部署方法:

  • nginx + django(http方式)
  • nginx + uwsgi(http方式)
  • nginx + uwsgi(socket方式)

python

升级python到3.6.1,统一线上和本地python环境。

1、下载python3.6.1源码
wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz

2、解压源码

xz -d Python-3.6.1.tar.xz
tar -xvf Python-3.6.1.tar

3、编译源码

mkdir /usr/local/python3
cd Python-3.6.1
./configure --prefix=/usr/local/python3 --enable-optimizations
make && make install

如果编译失败,需要先更新编译环境:

gcc -v 
g++ -v

yum install gcc
yum install gcc-c++

注:我的环境版本为 gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) 。

4、替换python

cd /usr/bin
mv python python.bak
ln -s /usr/local/python3/bin/python3.6 /usr/bin/python
ll python*
python -V

5、解决遗留问题
所有python相关的应用,如果使用/usr/bin/python开头的脚本,替换为/usr/bin/python2.7。比如:

vim /usr/bin/yum
vim /usr/libexec/urlgrabber-ext-down

部署静态文件

书签

使用uWSGI提供静态文件 (更新至1.9)

解决uWSGI里的Django静态文件丢失

nginx配置

1、首先,在万网上配置域名解析,添加A记录,解析到阿里云服务器IP。假设解析好的域名为django.voidking.com。

2、在nginx的vhost中,添加django.voidking.com.conf,内容为:

server {
    listen 80;
    server_name django.voidking.com;
    charset utf-8;
    location /{
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
        client_max_body_size       1024m;
        client_body_buffer_size    128k;
        client_body_temp_path      data/client_body_temp;
        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;
        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
        proxy_temp_path            data/proxy_temp;

        proxy_pass http://127.0.0.1:8000;
    }
}

3、重启nginx,./nginx -s reload

4、测试访问
服务器:curl django.voidking.com/blog/index
本地浏览器:http://django.voidking.com/blog/index

至此,django项目已经部署成功,没有用到uwsgi。如果给django添加守护进程,那么我们的部署就接近完美了。那么,uwsgi又能干什么呢,我们继续研究。

可能你还需要把当前用户加入nginx用户组,反之也需要把nginx加入你当前用户的用户组。这样nginx应该就有权限访问socket文件了。

uwsgi

守护uwsgi

1、在/etc/supervisor中新建djsite.conf文件:

[program:djsite]
command=/usr/local/python3/bin/uwsgi --http :8000 --chdir /root/djsite/ --module django_wsgi --static-map=/static=static
directory=/root/djsite/
startsecs=0
stopwaitsecs=0
autostart=true
autorestart=true

2、重启supervisor

systemctl stop supervisord
systemctl start supervisord

附:重启djsite命令

supervisorctl -c /etc/supervisord.conf restart djsite

3、测试访问
http://ip:8000/blog/index
页面显示正常,至此守护进程配置成功。

4、退出supervisor环境
source deactivate,守护进程并没有受到影响。

 (注意冒号是英文的冒号)

服务器

阿里云服务器,centos7系统。

sudo pip install uwsgi

书签

Python Web部署方式总结

Python网络框架——Web服务器

Django在生产环境中的部署

Django 部署(Nginx)

使用Supervisor管理SpiderKeeper和Scrapyd

apt-get groupinstall "Development Tools"

小结

至此,django部署完毕,我们实现了三种部署方法:

  • nginx + django(http方式)
  • nginx + uwsgi(http方式)
  • nginx + uwsgi(socket方式)

在此过程中,解决了一些奇怪的bug,学习了升级python的方法,学习了使用pyenv安装多版本python的方法(类似的还有anaconda),学习了给django或者uwsgi添加守护进程的方法,收获颇丰。

那么现在我们的桥梁变成了:客户端——服务器(nginx)

基本试验

在 Debian 和 Ubuntu系统中使用:

停下刚才的uWSGI服务,输入以下命令重新开启:

sudo service nginx restart
或者
systemctl restart nginx.service

这份配置文件告诉nginx从文件系统中建立媒体和静态文件服务,同时也处理Django应用中的请求。对于大型的部署而言,让一个服务器处理静态/媒体文件,另一个处理Django应用,会有很好的表现。不过现在,我们这么做也没问题。

如果可以正常运行,停掉它然后执行下面的代码,把nidegongchenming改成你的工程名:

server{}中的server_name可以接IP地址,比如:server_name  219.242.174.48,测试的话用你本机的吧,搭好了之后方便在同网段内使用其它机器测试。

我们最后要完成的工作基本是这样的:

那可能需要更改socket的权限,以便nginx可以使用它。

这些内容我可能会在下一篇博客里写,想先了解的同学请移步:
这个文档相当全面,而且重要的是没有拼写错误这种情况。

5、socket是用来实现进程间通信的,在我们这里用作实现nginx和uWSGI之间的通信

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

uWSGI的安装和基本配置:

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——Django的桥梁,恭喜。

如果服务没能正常运行,查看一次啊nginx的错误日志,在/var/log/nginx/error.log。如果错误日志像是这样:

uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664
sudo yum install python-pip

注意:Centos7.0及以上yum版本为3.4.X以上,yum groupinstall "Development Tools"是没用的,跳过这句,安装下面的python-devel就可以了

文件名是uwsgi_params,没有后缀。把它放到你的Django工程中,和manage.py同目录。下面我们来配置nginx,并告诉它引用uwsgi_params文件。

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
python manage.py runserver 0.0.0.0:8000
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return ["Hello World"] # python2
    #return [b"Hello World"] # python3

前言

客户端(浏览器)——服务器(nginx)——socket——uWSGI——python

然后运行

python manage.py collectstatic
STATIC_ROOT = os.path.join(BASE_DIR, "static/")

4、Django是采用MVC设计模式的开源Web应用框架。

进入你的Django工程目录,创建一个文件 mysite_nginx.conf,里面敲入:

以后再运行 uswgi就可以使用:

创建一个文件命名为'mysite_uwsgi.ini'

sudo ln -s mysite_nginx.conf /etc/nginx/sites-enabled/
uwsgi --ini mysite_uwsgi.ini

现在我们可以尝试一下用uwsgi和nginx来运行我们的Django应用了。

注意mysite.wsgi要改成你的工程名。

在工程目录下运行:

激动人心的时候要到了

在运行nginx之前,必须把所有的Django静态文件收集到一个静态文件夹中,首先在settings.py中写入:

安装 nginx

1、WSGI是一种Web服务器网关接口。它是Web服务器(如nginx)与应用服务器(如uWSGI服务器)通信的一种规范。

yum install -y python-devel

nginx和uWSGI是Django部署的不错选择,但并非唯一的,它们都是可以替代的,欢迎进行其它尝试。

然后执行下面的命令,让nginx知道有这么一个配置文件:

Fedora,CentOS:

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

代码的意思是使用http协议,端口8000,载入我们的测试文件。如果一切正常,访问:

同时你也可以访问

进一步我们还可以让uWSGI运行在上帝模式,设置开机自动启动以及限制最大访问,工程文件大小之类的配置。

sudo apt-get install nginx
sudo /etc/init.d/nginx start
uwsgi --socket mysite.sock --wsgi-file test.py

下面的内容很多来源于

如果你使用了virtualenv,home那个位置就不能注释掉。

到现在我们都是在使用TCP port socket,这样开始的时候会容易些,不过实际上使用Unix sockets 会更好些,会有较小的开销。

粗略的介绍我们需要使用到的部件之后,我们来具体说明搭建的步骤(请认真看,务求一次做对)

这个文件中的内容我保留了英文文档中的注释,比较详细,可能会对你有一些意外的帮助。

sudo apt-get install python-pip

module *.wsgi是载入wsgi模块的意思,请放心这个模块你已经有了的。

我们使用pip包管理工具来安装uWSGI:

首先我们需要一份uwsgi_params文件,这个文件一般会在你的nginx目录中,比如我的在/etc/nginx/里,当然,没找到的话,你也可以去,copy一份,或者复制下面的内容

运行uWSGI

在pip安装uwsgi的过程中如果提示有依赖没有安装:

2、uWSGI它实现了WSGI、uwsgi、http等协议。

Fedora中,service nginx start会被重定向到systemctl start nginx.service。

sudo /etc/init.d/nginx restart

或者:

在 Fedora 和 CentOS系统中使用:

如果一切正常(默认的80端口没有被占用),此时在浏览器中访问127.0.0.1你会看到“Welcome to nginx on XXX”

好了可以停掉服务了,我们继续。

Ubuntu 和 Debian:

connect() to unix:///path/to/your/mysite/mysite.sock failed (13: Permission
denied)

背景知识简要介绍:

用ini文件来配置uWSGI

apt-get install python-devel

你会看到熟悉且可爱的Hello World。这也就说明我们打通了客户端——uWSGI——Python的桥梁。

客户端(进行web请求) —— 服务器(这里使用的是nginx) —— socket(自动生成的通信文件)—— uwsgi —— Django

如果端口被Apache或者其它什么占用了,导致nginx服务不能成功启动也没关系,下面我们介绍怎么配置nginx来监听其它端口。

Fedora 和CentOS:

yum groupinstall "Development Tools"

重启nginx服务

3、Nginx是高性能的HTTP和反向代理服务器(我们使用Nginx是因为其高效的处理静态文件请求的能力)

uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664 # (more sensible)

Fedora 和CentOS

Ubuntu,Debian:

nginx和uWSGI以及test.py的沟通

mysite.sock文件会被自动建立,用做通信,你可以当它是个临时文件。当然不喜欢这个文件名,你也可以更改。用浏览器再访问一次8000端口,看看结果。

# 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

编辑:编程 本文来源:只是用户并非真实的在与8000端口交流,把djsite项

关键词:

  • 上一篇:没有了
  • 下一篇:没有了