Django定时任务-基于crontab的简单版

需求场景

web应用中常常会有定时处理某项任务的需求,flask框架比较灵活,简单的需求中可以低耦合的使用APScheduler,复杂的需求也很容易集成进celery。但是在django中,定制起来就比较麻烦,django现有较为成熟的定时任务组建django-crontab和django-celery。前者基于crontab,后者基于celery。
先说说较为简单的crontab。

安装django-crontab

pip install django-crontab

在配置文件中加入django-crontab

setting.py

INSTALLED_APPS = [
    ...
    'django_crontab',
]
CRONJOBS = [
    ('* * * * *', 'django.core.management.call_command', 
    ['task'], {}, ">> task.log"),
]   # 与crontab定时器规则一样, []中写入任务名称,{}中可传入参数

这里使用了自定义的manage指令,本片中不做深入说明。也可以替换为要运行的py代码,写清楚详细路径即可。

添加crontab

现在就可以将任务添加进系统的crontab中了

python manage.py crontab add

收到下面的提示就算提交成功了,也可以通过 crontab -l查看当前有效的定时任务

bash -cl "/bin/python /home/hsm/Dropbox/Python2/project/manage.py crontab add /home/hsm/Dropbox/Python2/project"
  adding cronjob: (5137385ee17caca44bc53c1bef979825) -> ('* * * * *', 'django.core.management.call_command', ['task'], {}, '>> task.log')

删除crontab

要删除crontab,可执行

python manage.py crontab remove

supervisor 和gunicorn部署django项目

安装使用到的基本软件nginx、supervisor、gunicorn

vi /etc/supervisor/conf.d/django_project.conf
[program:django_project]
command=gunicorn xxx.wsgi:application -b 127.0.0.1:8080 -w 8
user=user #当前用户
directory=/home/user/django_project
stdout_logfile=/tmp/var/logs/supervisor/%(program_name)s-stdout.log
stderr_logfile=/tmp/var/logs/supervisor/%(program_name)s-stderr.log
killasgroup=true
stopasgroup=true
autorstart=true
autorestart=true

# rq队列的配置

[program:rqworker]
command=python manage.py rqworker default low
user=user
directory=/home/django_project/platform
stdout_logfile=/tmp/var/logs/supervisor/%(program_name)s-stdout.log
stderr_logfile=/tmp/var/logs/supervisor/%(program_name)s-stderr.log
killasgroup=true
stopasgroup=true
autorstart=true
autorestart=true```

再在nginx配置中的location,添加

proxy_pass http://127.0.0.1:8080;

另外静态文件的代理可以添加下面的配置

location /static/ {

alias /django_project/statics/;

}

[Django笔记] uwsgi + nginx 配置

安装nginx

安装配置uwsgi

pip install uwsgi

回想php-fpm安装完直接启动就完事了,好像只要配置php的路径
uwsgi的启动需要一大堆参数,可以写好一个配置文件 uwsgi_conf.ini,下面是一个demo:

# uwsig使用配置文件启动
[uwsgi]
# 项目目录
chdir=/var/www/path/to/django/
# 指定项目的application(django 目录的 wsgi.py)
module=pics.wsgi:application
# 指定sock的文件路径       
socket=/var/www/path/to/django/script/uwsgi.sock
# 进程个数       
workers=5
pidfile=/var/www/path/to/django/script/uwsgi.pid
# 指定IP端口       
http=127.0.0.1:80
# 指定静态文件
static-map=/static=/var/www/path/to/django/static
# 启动uwsgi的用户名和用户组
uid=root
gid=root
# 启用主进程
master=true
# 当服务停止的时候自动移除unix Socket和pid文件
vacuum=true
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置自中断时间
harakiri=30
# 设置缓冲
post-buffering=4096
# 设置日志目录
daemonize=/var/www/path/to/django/script/uwsgi.log

配置文件解释:

  • 通过 uwsgi [xxx.ini]来启动服务

  • pid, sock, log 三个文件跟这个 ini 文件可以统一在 django 目录下面新建一个script 文件夹存放

  • nginx 是读取sock 来连接 uwsgi

  • pid 文件非常重要, uwsgi 通过 uwsgi –stop [xxx.pid]和uwsgi –reload [xxx.pid] 来停止和重启服务

  • 因为uwsgi 是给nginx 做桥接,ip 为127.0.0.1. 我的http端口不是80,因此这里可以使用80

启动后,可以通过http://127.0.0.1来测试访问 django. (我在linux直接curl 127.0.0.1测试)

nginx.conf 配置 uwsgi

本机配置了一个php服务,想通过子路径/pics来访问 django:

# 指定项目路径uwsgi
location /pics { 
    include uwsgi_params; # 导入一个Nginx模块他是用来和uWSGI进行通讯的
    uwsgi_connect_timeout 30; # 设置连接uWSGI超时时间
    uwsgi_pass unix:/var/www/path/to/django/script/uwsgi.sock; # 指定uwsgi的sock文件所有动态请求就会直接丢给     
}
# 指定静态文件     
location /pics/static/ {
    alias /var/www/path/to/django/static/;
    index index.html index.htm;
}

重启nginx nginx -s reload ,大功告成

未分类

使用 Nginx 和 Gunicorn 部署 Django 博客

我们博客的基础功能已经开发的基本差不多了,虽然还有很多地方可以完善,但我们还是希望早点把博客部署到服务器上,让他人可以通过外网访问。至于有待完善的地方,可以等部署完后一点点地迭代和改进。现在就让我们来把博客部署到服务器上吧!

注意:本文的每一个步骤都在真实环境下验证无误。除非你知道自己在做什么,否则我们建议每一步均严格按照教程的指导来,这样能保证你顺利完成部署。

部署前准备

我们将使用比较流行的 Nginx + Gunicorn 的方式将 Django 开发的博客部署到自己的服务器,让别人能够通过域名访问你的博客。至于 Nginx、Gunicorn 是什么暂时放到一边,读完本教程后你就会知道它们的作用和使用方法了。
为了部署我们的博客,需要满足以下两个条件:

  1. 有一台可以通过外网访问的服务器。
  2. 有一个域名。

如果你已经满足以上条件,可以直接跳到后面的搭建服务器部分。这里简单介绍一下我目前所知的以最低成本满足以上两个条件的方式。

购买服务器

如果你是学生,推荐购买阿里云服务器,学生优惠价是 9.9 元/月,而且服务器性能比较高。购买地址:阿里云服务器学生专区。具体的购买步骤这里就不赘述了,根据网站的指引相信你肯定能够购买成功。只是注意一点的是在选服务器类型的时候选择公共镜像,这样系统比较纯净。操作系统建议选 ubuntu 14.04 64位,这是本教程使用的服务器环境。

如果你不是学生,推荐购买搬瓦工 vps。目前最便宜的是 19.9美元/年,缺点是服务器性能没有阿里云高,但优点是顺带可以用它来搭梯子,从此访问 google、youtube 不是梦(基于 shadowsocks 只需简单几步就可以搭建起自己的梯子服务器)。同样购买的过程就不赘述了,搬瓦工 vps 中文网 有超级详细的指引。只是注意安装操作系统时建议选 ubuntu 14.04 64位,这是本教程使用的服务器环境。

如果你不差那点钱,随意选择一个云服务器提供商购买一个云服务器即可。

购买域名

域名服务商很多,我这里使用的是 阿里云域名注册系统。域名是网站的门牌,如果打算长期运营这个网站建议多考虑考虑,选一个适当的域名。如果只是为了测试,随便注册一个域名即可,一些非常见后缀的域名非常便宜,一般 10元/年就能搞定。但注意一点根据工信部规定,以下后缀的域名需要实名认证后才能使用:

.cn/.com/.net/.top/.xyz/.vip/.club/.ren/.wang/.shop/.xin/.中国/.信息/.公司/.网络/.广东/.佛山

如果你购买的是上述后缀的域名,意味着需要提交个人的身份资料实名认证后才能正常使用,这通常需要花费几天的时间。所以如果只为了测试和学习部署的话,最好避开上述后缀的域名。

搭建服务器

本教程使用的本地环境为 Windows 10,服务器环境为 ubuntu 14.04(64 位)。如果你的环境和我的有所差异导致一些命令无法执行,将这些命令转换为你所在环境的命令执行即可。

远程登录到服务器

服务器通常位于云端,需要使用远程登录工具登录后才能对服务器进行操作。我使用的是 Xshell,Windows 下百度 Xshell 下载安装即可,软件对学校和个人用户是免费的。
如何远程登录到服务器这里就不赘述了,相信你参考网上的一些教程肯定能够顺利登录。假如你和我一样使用 Xshell 的话,这里有一篇很详细的教程可以参考:教你怎么使用xshell远程连接linux服务器。

安装软件

顺利连接到远程服务器了。如果是一台全新服务器的话,通常我们是以 root 用户登录的。在 root 下部署代码不安全,最好是建一个新用户(如果你已经以非 root 用户登录的话可以跳过这一步)。下面的一些列命令将创建一个拥有超级权限的新用户:

# 在 root 用户下运行这条命令创建一个新用户,yangxg 是用户名
# 因为我叫杨学光,所以我取的用户名是 yangxg
# 选择一个你喜欢的用户名,不一定非得和我的相同
root@localhost:~# useradd -m -s /bin/bash yangxg

# 把新创建的用户加入超级权限组
root@localhost:~# usermod -a -G sudo yangxg

# 为新用户设置密码
# 注意在输密码的时候不会有字符显示,不要以为键盘坏了,正常输入即可
root@localhost:~# passwd yangxg

# 切换到创建的新用户
root@localhost:~# su - yangxg

# 切换成功,@符号前面已经是新用户名而不是 root 了
yangxg@localhost:~$

新用户创建并切换成功了。如果是新服务器的话,最好先更新一下系统,避免因为版本太旧而给后面安装软件带来麻烦。运行下面的两条命令:

yangxg@localhost:~$ sudo apt-get update
yangxg@localhost:~$ sudo apt-get upgrade

接下来就可以安装必要的软件了,这里我们需要用到的软件有 Nginx、Pytohn3、Git、pip 和 virtualenv。

yangxg@localhost:~$ sudo apt-get install nginx
yangxg@localhost:~$ sudo apt-get install git python3 python3-pip
yangxg@localhost:~$ sudo pip3 install virtualenv

解析域名到服务器的 IP 地址

将域名和服务器的 IP 地址绑定后,用户就可以通过在浏览器输入域名来访问服务器了。

各大域名服务商都提供了域名解析服务,但其配置界面各有差异,请依据其指引完成域名解析。下面是我使用的阿里云域名解析页面。

未分类

启动 Nginx 服务

Nginx 是用来处理静态文件请求的。比如当我们访问一个博客文章详情页面时,服务器会接收到下面两种请求:

  • 显示文章的详情信息,这些信息通常保存在数据库里,因此需要调用数据库获取数据。
  • 图片、css、js 等存在服务器某个文件夹下的静态文件。

对于前一种请求,博客文章的数据需要借助 Django 从数据库中获取,Nginx 处理不了,它就会把这个请求转发给 Django,让 Django 去处理。而对于后一种静态文件的请求,只需要去这些静态文件所在的文件夹获取,Nginx 就会代为处理,不再麻烦 Django。

用 Django 去获取静态文件是很耗时的,但 Nginx 可以很高效地处理,这就是我们要使用 Nginx 的原因(当然其功能远不止这些)。

通过前面的步骤我们已经安装了 Nginx,并且已经把域名和服务器 IP 绑定了。运行下面的命令启动 Nginx 服务:

yangxg@localhost:~$ sudo service nginx start

在浏览器输入域名,看到如下页面说明 Nginx 启动成功了。

未分类

部署代码

部署前的项目配置

Django 项目中会有一些 CSS、JavaScript 等静态文件,为了能够方便地让 Nginx 处理这些静态文件的请求,我们把项目中的全部静态文件收集到一个统一的目录下,这个目录通常位于 Django 项目的根目录,并且命名为 static。为了完成这些任务,需要在项目的配置文件里做一些必要的配置:

blogproject/settings.py

# 其他配置...

STATIC_URL = '/static/'
# 加入下面的配置

STATIC_ROOT = os.path.join(BASE_DIR, ‘static’)STATIC_ROOT 指明了静态文件的收集目录,即项目根目录(BASE_DIR)下的 static 文件夹。

为了安全起见,在生产环境下需要关闭 DEBUG 选项以及设置允许访问的域名。打开 settings.py 文件,找到 DEBUG 和 ALLOWED_HOSTS 这两个选项,将它们设置成如下的值:

blogproject/settings.py

DEBUG = False

ALLOWED_HOSTS = [‘127.0.0.1’, ‘localhost ‘, ‘.zmrenwu.com’]ALLOWED_HOSTS 是允许访问的域名列表,127.0.0.1 和 localhost 是本地访问的域名,.zmrenwu.com 是访问服务器的域名(换成你自己的域名)。域名前加一个点表示允许访问该域名下的子域名,比如 www.zmrenwu.com、test.zmrenwu.com 等二级域名同样允许访问。如果不加前面的点则只允许访问 zmrenwu.com。

项目还会依赖一些第三方 Python 库,为了方便在服务器上一次性安装,我们将全部依赖写入一个叫 requirements.txt 的文本文件中。激活本地的虚拟环境(如果你使用了虚拟环境的话),并进入项目的根目录,运行 pip freeze > requirements.txt 命令:

(blogproject_env) C:UsersyangxgWorkspaceblogproject>
pip freeze > requirements.txt

这时项目根目录下会生成了一个 requirements.txt 的文本文件,其内容记录了项目的全部依赖。

将代码上传到 GitHub

将代码上传到 GitHub 等代码托管平台,这样我们就可以方便地把代码拉取到服务器了。Git 和 GitHub 的使用相信你已经很熟悉了,这里就不赘述过程。如果不知道如何使用地话可以自行百度相关教程。
注意数据库文件不要上传!

设置服务器目录结构

接下来需要把代码上传到服务器了。我服务器上存放代码的目录结构一般是这样的:

/home/yangxg/
    sites/
        demo.zmrenwu.com/
            env/
            django-blog-tutorial/

一台服务器可能部署多个网站,所有网站代码都放在 sites/ 目录下。demo.zmrenwu.com/ 这个文件夹以网站的域名命名,便于区分。env/ 是 python 虚拟环境目录。django-blog-tutorial/ 是 Django 博客项目目录。

因此先来创建这个目录结构,注意目录名替换为你自己的域名,以后涉及到 demo.zmrenwu.com 的地方通常都要替换你自己的域名,后面就不再一一指出了,运行下面的命令,

yangxg@localhost:~$ mkdir -p ~/sites/demo.zmrenwu.com

这里 ~ 代表当前用户的 home 目录,即 /home/yangxg/。

接下来创建虚拟环境,先进入到 demo.zmrenwu.com 目录下,然后运行 virtualenv 命令创建虚拟环境:

yangxg@localhost:~$ cd ~/sites/demo.zmrenwu.com
yangxg@localhost:~/sites/demo.zmrenwu.com$ virtualenv --python=python3 env

注意这里使用 –python=python3 来指定克隆 Python3 的环境。因为 ubuntu 系统默认安装了 Python2,如果不特别指定的话 Virtualenv 默认克隆的是 Python2 的环境。

检查一下虚拟环境是否创建成功,运行 ls 命令列出当前目录下的文件和文件夹,看到 env 这个文件夹说明虚拟环境创建成功。

yangxg@localhost:~/sites/demo.zmrenwu.com$ ls
env

接着再从代码仓库把项目代码拉取过来,把 git clone 后的地址换成你自己的 GitHub 仓库地址!

yangxg@localhost:~/sites/demo.zmrenwu.com$ git clone https://github.com/zmrenwu/django-blog-tutorial.git

运行 ls 命令检查一下是否拉取成功:

yangxg@localhost:~/sites/demo.zmrenwu.com$ ls
django-blog-tutorial  env

多了 django-blog-tutorial 文件夹(文件夹名称由你的 GitHub 仓库名决定),说明拉取成功了。

安装项目依赖

激活虚拟环境,再进入到项目根目录,即 requirements.txt 所在的目录,安装项目的全部依赖:

yangxg@localhost:~/sites/demo.zmrenwu.com$ source env/bin/activate
(env) yangxg@localhost:~/sites/demo.zmrenwu.com$ cd django-blog-tutorial/
(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ pip install -r requirements.txt

收集静态文件

虚拟环境下继续运行 python manage.py collectstatic 命令收集静态文件到 static 目录下:

(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py collectstatic

生成数据库

虚拟环境下继续运行 python manage.py migrate 命令创建数据库文件:

(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py migrate

创建超级用户

虚拟环境下继续运行 python manage.py createsuperuser 命令创建一个超级用户,方便我们进入 Django 管理后台。这和本地开发时是一样的,具体请参照:在 Django Admin 后台文章。

(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py createsuperuser

配置 Nginx

接下是配置 Nginx 来处理用户请求。

先在服务器的 /etc/nginx/sites-available/ 目录下新建一个配置文件,文件名我一般就设置为域名。写上下面的配置内容:
/etc/nginx/sites-available/demo.zmrenwu.com

server {
    charset utf-8;
    listen 80;
    server_name demo.zmrenwu.com; ①

    location /static { ②
        alias /home/yangxg/sites/demo.zmrenwu.com/django-blog-tutorial/static; 
    }

    location / { ③
        proxy_set_header Host $host;
        proxy_pass http://unix:/tmp/demo.zmrenwu.com.socket;
    }
}

① 服务的域名为 demo.zmrenwu.com。

② 所有URL 带有 /static 的请求均由 Nginx 处理,alias 指明了静态文件的存放目录。

③ 其它请求转发给 Django 处理。proxy_pass 后面使用了 unix 套接字,其作用是防止端口冲突,这里就不再详述。

至于怎么在服务器新建文件和写文件,请自行学习一点点 vi 编辑器的用法,这里也不一一讲解了。

我们在 /etc/nginx/sites-available/ 放置了配置文件,接下来需要创建一个符号链接,把这个配置文件加入到启用的网站列表中去,被启用网站的目录在 /etc/nginx/sites-enabled/,你可以理解为从 sites-available/ 目录下发送了一个配置文件的快捷方式到 sites-enabled/ 目录。具体命令如下:

(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ sudo ln -s /etc/nginx/sites-available/demo.zmrenwu.com /etc/nginx/sites-enabled/demo.zmrenwu.com

使用 Gunicorn

Gunicorn 一般用来管理多个进程,有进程挂了Gunicorn 可以把它拉起来,防止服务器长时间停止服务,还可以动态调整 worker 的数量,请求多的时候增加 worker 的数量,请求少的时候减少。
在虚拟环境下,安装 Gunicorn:

(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ pip install gunicorn

用 Gunicorn 启动服务器进程:

(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ gunicorn --bind unix:/tmp/demo.zmrenwu.com.socket blogproject.wsgi:application

浏览器输入域名,可以看到访问成功了!

自动启动 Gunicorn

现在 Gunicorn 是我们手工启动的,万一哪天服务器崩溃重启了又得重新手工启动。为此我们写一个自动启动脚本,这样当服务器重新启动后,脚本会帮我们重启 Gunicorn。先按 Ctrl + c 停止刚才启动的服务器进程。

写一个启动脚本,这样当服务器重启后能自动引导 Gunicorn 的启动。脚本位于 /etc/init/ 目录下,且脚本文件名必须以 .conf 结尾:

/etc/init/gunicorn-demo.zmrenwu.com.conf

start on net-device-up ①
stop on shutdown

respawn ②

setuid yangxg ③
chdir /home/yangxg/sites/demo.zmrenwu.com/django-blog-tutorial ④

exec ../env/bin/gunicorn --bind unix:/tmp/demo.zmrenwu.com.socket blogproject.wsgi:application ⑤

① start on net-device-up 确保只在服务器联网时才启动 Gunicorn。

② 如果进程崩溃了(比如服务器重启或者进程因为某些以外情况被 kill),respawn 将自动重启 Gunicorn。

③ setuid 确保以 yangxg 用户的身份(换成你自己的用户名)运行 Gunicorn 进程。

④ chdir 进入到指定目录,这里进入项目的根目录。

⑤ exec 执行进程,即开启服务器进程。

现在可以用 start 命令启动 Gunicorn 了:

sudo start gunicorn-demo.zmrenwu.com

以后如果更新了代码,只要运行下面的命令重启一下 Nginx 和 Gunicorn 就可以使新的代码生效了:

sudo service nginx reload
sudo restart gunicorn-demo.zmrenwu.com

使用 CDN 加快 Bootstrap 和 jQuery 的加载速度

我们的项目使用了 Bootstrap 和 jQuery,这两个文件我们是从本地加载的。如果服务器性能比较差的话,加载需要耗费很长的时间,网站打开的速度就变得无法忍受。我们使用 CDN 来加快加载速度。具体来说,替换 base.html 的几个静态文件的加载标签:

base.html

- <link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
- <script src="{% static 'blog/js/jquery-2.1.3.min.js' %}"></script>
- <script src="{% static 'blog/js/bootstrap.min.js' %}"></script>
+ <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
+ <script src="https://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script>
+ <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

这样网站访问的速度将大大提升!

部署过程自动化

在整个部署过程中我们运行了十几条命令,手动输入了 N 个字符。如果每次更新代码都要远程连接到服务器执行这些命令的话将变得非常麻烦。接下来的教程我们将介绍使用 Fabric 自动化整个部署过程。写好部署脚本后,只需要执行一条命令,就可以非常方便地自动完成整个部署。

nginx+uwsgi+django部署python项目

初次部署nginx+uwsgi+django真是经历了千难万险,因此在这里整理分享一下,希望在这条路上行走的你有所帮助。

我使用的系统是fedora27,已经安装了python3和pip3,这两个没有安装的各位先自行安装。

Nginx

  • 安装
dnf install nginx
  • 配置
location / {
    uwsgi_pass  127.0.0.1:9090;
    include     uwsgi_params; # the uwsgi_params file you installed
}

nginx的配置只需要改这些

Django

  • 安装
dnf install setuptools
pip3 install django
pip3 install PyMySQL
pip3 install mysqlclient
#安装mysqlclient可能会遇到以下下问题,
dnf install mysql-devel # 解决 OSError: mysql_config not found
dnf install gcc # 解决 unable to execute 'gcc': No such file or directory
dnf install redhat-rpm-config # 解决gcc: 错误:/usr/lib/rpm/redhat/redhat-hardened-cc1:No such file or directory
#python-devel for python2.x
#python3-devel for python3.x
dnf install python3-devel 解决 致命错误:Python.h:No such file or directory
  • 启动
#在你的项目目录下
[jeffery@localhost pythontest]$ python3 manage.py runserver 0.0.0.0:8000
Performing system checks...

System check identified no issues (0 silenced).
November 30, 2017 - 08:11:58
Django version 1.11.7, using settings 'pythontest.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

这样django就启动成功了,可以在浏览器中用8000端口访问一下项目

uwsgi

  • 安装
pip3 install uwsgi
  • django_socket.ini配置
[uwsgi]
socket = 127.0.0.1:9090
chdir = /projects/pythontest
module = pythontest.wsgi
processes = 2
pidfile = uwsgi.pid
daemonize = /var/log/uwsgi/uwsgi9090.log

chdir——你的项目根目录
module——入口文件,即wsgi.py相对于项目根目录的位置,“.”相当于一层目录。如果是用django创建的项目,wsgi.py这个文件是自动生成的,自己找一下。
daemonize——作为后台进程执行,日志输出的地方,目录没有的自己创建下

  • wsgi.py
import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pythontest.settings")

application = get_wsgi_application()
  • 启动
uwsgi --ini django_socket.ini

启动完我们就可以去上面daemonize 配置的日志中看看是否启动成功
Nginx中配置的地址端口要和django_socket.ini中保持一致
接下来用浏览器访问下Nginx,有人应该已经能够成功看到自己的python项目了

不行的请继续往下看

VirtualEnv

VirtualEnv的作用:创建隔离的Python环境,解决模块或库的版本冲突或依赖。(我的系统中既有python2.7又有python3.6)

  • 安装
pip3 install virtualenv
  • 创建虚拟环境
virtualenv mytest

mytest是我这边起的名字,可以随便起
创建不了的看下自己当前用户权限够不够, 不是root用户就到 /home目录下找你现在登录的角色的目录,然后进入用户目录下再执行上面的安装命令,执行完以后用ls看下有没有mytest这个文件夹,进入mytest的bin中

[jeffery@localhost /]$ cd /home/jeffery/mytest/bin/
[jeffery@localhost bin]$ ls
activate          django-admin      pip          python         wheel
activate.csh      django-admin.py   pip3         python3
activate.fish     easy_install      pip3.6       python3.6
activate_this.py  easy_install-3.6  __pycache__  python-config
  • 激活mytest虚拟环境
[jeffery@localhost bin]$ source ./activate
(mytest) [jeffery@localhost bin]$ 

此时我们看到命令行前面加上了(mytest),这代表我们在mytest的虚拟环境中,这个时候按照上面django的安装配置重新配置一次,最后在这个虚拟环境中启动django。(我们上面启动的可以不要了,虚拟环境中启动就可以了)

  • 修改django_socket.ini
[uwsgi]
socket = 127.0.0.1:9090
chdir = /projects/pythontest
module = pythontest.wsgi
processes = 2
pidfile = uwsgi.pid
daemonize = /var/log/uwsgi/uwsgi9090.log
home = /home/jeffery/mytest

这里面我们加上了最后一行,也就是配置home——虚拟环境mytest的根目录。

重新启动uwsgi,用浏览器访问Nginx,成功访问python项目。

Django+Nginx+uWSGI部署

一、介绍

Django的部署有多种方式,采用Nginx+uWSGI的方式是最常见的一种方式。在这种方式中,将Nginx作为服务器前端,接收Web的所有请求,统一管理请求。Nginx自己处理所有静态请求,所有非静态请求通过uWSGI传递给Django,由Django来进行处理,从而完成一次Web请求。

二、安装配置

环境:Python(3.5.2)、Django(1.11.6)

1. 安装pip

root@787c084a44e4:~# apt-get install -y python3-pip 

2. 安装uWSGI

root@787c084a44e4:~# python3 -m pip install uWSGI 

3. 安装Django

root@787c084a44e4:~# python3 -m pip install Django 

4. 安装Nginx

root@787c084a44e4:~# apt-get install -y nginx 

5. 通过文件配置uwsgi

新建文件/root/web/uwsgi.ini

[uwsgi]
# 监听IP和端口
socket = 127.0.0.1:9090
# 项目主目录
chdir = /root/web/Django
# uwsgi文件路径
module = Django.wsgi:application
# 允许主进程存在
master = True
# 开启的进行数
workers = 1
# 服务器退出时自动清楚环境
vacuum = True
# 设置工作进程请求上限
max-requests = 1000
# 记录主进行的pid
pidfile = /var/uwsgi.pid
# 使进程在后台运行
daemonize = /var/uwsgi.log

6. 配置nginx虚拟主机

新建文件/etc/nginx/sites-

enabled/django.conf
# nginx需要连接的后端代理
upstream django {
    server 127.0.0.1:9090;
}

# 虚拟主机配置
server {
    # 监听端口
    listen 8080;
    # 域名
    server_name 127.0.0.1;
    # 编码
    charset utf-8;
    # 静态文件路径
    location /static {
        alias /root/web/Django/static;
    }
    # 将动态请求转发到uwsgi运行的django程序
    location / {
        uwsgi_pass django;
        include /etc/nginx/uwsgi_params;
    }
}

7. 修改nginx默认运行用户

修改/etc/nginx/nginx.conf文件,user www-data修改为user root

三、验证部署

运行工程

root@787c084a44e4:~/web# uwsgi --ini uwsgi.ini & nginx

访问地址http://127.0.0.1:8080/list,数据和页面css样式正常

未分类

四、异常情况

1. 出现DisabllowedHost

未分类

修改Django/Django/settings.py文件

ALLOWED_HOSTS = ["*"] 

2. 出现静态文件403异常

未分类

Nginx使用www-data用户运行,无web目录读取权限,修改/etc/nginx/nginx.conf文件,user www-data修改为user root

从零开始使用 Docker 打包 Django 开发环境 (3) Docker Compose

1. 基本概念

Docker Compose 是一个用来定义和运行复杂应用的 Docker 工具。使用 Docker Compose,可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

Docker Compose 定位是 ‘defining and running complex applications with Docker’,前身是 Fig,兼容 Fig 的模板文件。

Docker Compose 发展至今,有 Version 1、Version 2、Version 3 三个大版本。如果不声明版本,默认为 Version 1。Version 1 不能使用 volumes,、networks、 build参数。Version 2,必须在版本中申明,所有的服务,都必须申明在 service 关键字下。Version 3 删除了 volume_driver、volumes_from、cpu_shares、cpu_quota、cpuset、mem_limit、memswap_limit、extends、group_add关键字,新增了 deploy,全面支持 Swarm mode。更详细的比较可以查看参考链接。

本文中主要以 Version 2 为例学习 Docker Compose 容器的编排。

2. 工作原理

Docker Compose 将所管理的容器分为三层,工程(project),服务(service)以及容器(contaienr)。Docker Compose 运行的目录下的所有文件(docker-compose.yml、extends文件、环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。

一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。一个服务当中可包括多个容器实例,Docker Compose 并没有解决负载均衡的问题,因此需要借助其他工具实现服务发现及负载均衡。

Docker Compose 的工程配置文件默认为 docker-compose.yml,可通过环境变量 COMPOSE_FILE 或 -f 参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。以下是一个简单的配置文件:

version: '2'  
services:  
    web:
        build: .
        ports:
          - "80:90"
        volumes:
          - .:/code
        links:
          - redis
    redis:
        image: redis

其定义了两个服务 web 和 redis。web 服务的镜像需要使用当前目录的 Dockerfile 实时构建,其容器运行时需要在宿主机开放端口 80 并映射到容器端口 90 ,并且挂载存储卷 /code 以及关联服务 redis。redis 服务通过镜像 redis 启动。

Docker Compose 是由 Python 语言实现的,它通过调用 docker-py 库(可参考
https://github.com/docker/docker-py )与 docker engine 通信实现构建 docker 镜像,启动停止 docker 容器等。Docker-py 库调用 docker remote API(可参考 https://docs.docker.com/reference/api/docker_remote_api/ )与 Docker Daemon 通信,可通过 DOCKER_HOST 配置本地或远程 Docker Daemon 的地址。

3. Docker Compose 常用命令

未分类

4. YAML 常用关键字

4.1 build

指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。

build: /path/to/build/dir  

4.2 command

覆盖容器启动后默认执行的命令。

command: echo "hello world"  

4.3 dockerfile

如果需要指定额外的编译镜像的 Dockefile 文件,可以通过该指令来指定。例如:

dockerfile: Dockerfile-alternate  

注意,该指令不能跟 image 同时使用,否则 Compose 将不知道根据哪个指令来生成最终的服务镜像。

4.4 env_file

从文件中获取环境变量,可以为单独的文件路径或列表。

如果通过 docker-compose -f FILE 方式来指定 Compose 模板文件,则 env_file 中变量的路径会基于模板文件路径。

如果有变量名称与 environment 指令冲突,则按照惯例,以后者为准。

env_file: .env

env_file:  
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

环境变量文件中每一行必须符合格式,支持 # 开头的注释行。

# common.env: Set development environment
PROG_ENV=development  

4.5 environment

设置环境变量。你可以使用数组或字典两种格式。

只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。例如:

environment:  
  RACK_ENV: development
  SESSION_SECRET:

或者

environment:  
  - RACK_ENV=development
  - SESSION_SECRET

注意,如果变量名称或者值中用到 true|false,yes|no 等表达布尔含义的词汇,最好放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。

http://yaml.org/type/bool.html 中给出了这些特定词汇,包括

 y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

4.6 expose

暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数

expose:  
 - "3000"
 - "8000"

4.7 image

指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。例如:

image: ubuntu  
image: orchardup/postgresql  
image: a4bc65fd  

4.8 links

链接到其它服务中的容器。使用服务名称(同时作为别名)或服务名称:服务别名 (SERVICE:ALIAS) 格式都可以。

links:  
 - db
 - db:database
 - redis

使用的别名将会自动在服务容器中的 /etc/hosts 里创建。例如:

172.17.2.186  db  
172.17.2.186  database  
172.17.2.187  redis  

被链接容器中相应的环境变量也将被创建。

4.9 volumes

数据卷所挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)。该指令中路径支持相对路径。例如

volumes:  
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro

4.10 volumes_from

从另一个服务或容器挂载它的数据卷。

volumes_from:  
 - service_name
 - container_name

从零开始使用 Docker 打包 Django 开发环境 (2) Dockerfile

1. 基本概念

Dockerfile 是一些列构建 Docker 镜像的指令集合。Docker 通过读取 Dockerfile 指令自动构建镜像。Dockerfile 类似于 Makefile,都是一种文本文件,按照构建镜像顺序组织所有的指令。

Docker 镜像的构建命令:

$ docker build .

这条命令中,Docker CLI 的处理流程如下:

  • 把当前目录及子目录当做上下文传递给 Docker Daemon
  • 从当前目录(不包括子目录)中找到 Dockerfile 文件
  • 检查 Dockerfile 的语法
  • 依次执行 Dockerfile 中的指令,根据指令生成中间过渡镜像(存储在本地,为之后的指令或构建作缓存)

2. Docker 文件组成

Dockerfile 一般包含下面几个部分:

  • 基础镜像,以哪个镜像作为基础进行制作,用法是 FROM 基础镜像名称
  • 维护者信息,需要写下该 Dockerfile 编写人的姓名或邮箱,用法是MANITAINER 名字/邮箱
  • 镜像操作命令,对基础镜像要进行的改造命令,比如安装新的软件,进行哪些特殊配置等,常见的是 RUN 命令
  • 容器启动命令,当基于该镜像的容器启动时需要执行哪些命令,常见的是 CMD 命令或 ENTRYPOINT 命令

3. Dockerfile 命令

3.1 FROM

语法:FROM image[:tag]

解释:设置要制作的镜像基于哪个镜像,FROM 指令必须是整个 Dockerfile 的第一个指令,如果指定的镜像不存在默认会自动从 Docker Hub 上下载。如果不指定 tag,默认是 latast。

3.2 MAINTAINER

语法:MAINTAINER name

解释:MAINTAINER 指令允许你给将要制作的镜像设置作者信息

3.3 RUN

语法:

  • RUN command #将会调用/bin/sh -c command
  • RUN [“executable”, “param1”, “param2”] #将会调用exec执行,以避免有些时候shell方式执行时的传递参数问题,而且有些基础镜像可能不包含/bin/sh

解释:RUN指令会在一个新的容器中执行任何命令,然后把执行后的改变提交到当前镜像,提交后的镜像会被用于Dockerfile中定义的下一步操作,RUN中定义的命令会按顺序执行并提交,这正是Docker廉价的提交和可以基于镜像的任何一个历史点创建容器的好处,就像版本控制工具一样。

3.4 CMD

语法:

  • CMD [“executable”, “param1”, “param2”] #将会调用exec执行,首选方式
  • CMD [“param1”, “param2”] #当使用ENTRYPOINT指令时,为该指令传递默认参数
  • CMD command [ param1|param2 ] #将会调用/bin/sh -c执行

解释:CMD 指令中指定的命令会在镜像运行时执行,在 Dockerfile 中只能存在一个,如果使用了多个 CMD指令,则只有最后一个 CMD 指令有效。当出现 ENTRYPOINT 指令时,CMD 中定义的内容会作为 ENTRYPOINT 指令的默认参数,也就是说可以使用 CMD 指令给 ENTRYPOINT 传递参数。

注意:RUN 和 CMD 都是执行命令,他们的差异在于 RUN 中定义的命令会在执行 docker build 命令创建镜像时执行,而 CMD 中定义的命令会在执行docker run命令运行镜像时执行,另外使用第一种语法也就是调用 exec 执行时,命令必须为绝对路径。

3.5 EXPOSE

语法:EXPOSE port [ …]

解释:EXPOSE 指令用来告诉 Docker 这个容器在运行时会监听哪些端口,Docker 在连接不同的容器(使用–link参数)时使用这些信息。

3.6 ENV

语法:ENV key value

解释:ENV 指令用于设置环境变量,在 Dockerfile 中这些设置的环境变量也会影响到 RUN 指令,当运行生成的镜像时这些环境变量依然有效,如果需要在运行时更改这些环境变量可以在运行 docker run 时添加–env key=value参数来修改。

注意:最好不要定义那些可能和系统预定义的环境变量冲突的名字,否则可能会产生意想不到的结果。

3.7 ADD

语法:ADD src dest

解释:ADD 指令用于从指定路径拷贝一个文件或目录到容器的指定路径中,是一个文件或目录的路径,也可以是一个 url,路径是相对于该 Dockerfile 文件所在位置的相对路径, 是目标容器的一个绝对路径,例如 /home/yooke/Docker/Dockerfile 这个文件中定义的,那么 ADD /data.txt /db/指令将会尝试拷贝文件从 /home/yooke/Docker/data.txt 到将要生成的容器的 /db/data.txt,且文件或目录的属组和属主分别为 uid 和 gid 为0的用户和组,如果是通过 url 方式获取的文件,则权限是600。

注意:

  • 如果执行 docker build somefile 即通过标准输入来创建时,ADD 指令只支持 url 方式,另外如果 url 需要认证,则可以通过 RUN wget … 或 RUN curl … 来完成,ADD 指令不支持认证。
  • src 路径必须与 Dockerfile 在同级目录或子目录中,例如不能使用ADD ../somepath,因为在执行docker build时首先做的就是把 Dockerfile 所在目录包含子目录发送给 docker 的守护进程。
  • 如果 src 是一个 url 且 dest 不是以 ‘/’ 结尾,则会下载文件并重命名为 dest 。
  • 如果 src 是一个 url 且 dest 以 ‘/’ 结尾,则会下载文件到 dest filename,url 必须是一个正常的路径形式,’http://example.com’ 像这样的 url 是不能正常工作的。
  • 如果 src 是一个本地的压缩包且 dest 是以 ‘/’ 结尾的目录,则会调用 ‘tar -x’ 命令解压缩,如果 dest 有同名文件则覆盖,但 src 是一个 url 时不会执行解压缩。

3.8 COPY

语法:COPY src dest

解释:用法与 ADD 相同,不过 src 不支持使用url,所以在使用 docker build somefile 时该指令不能使用。

3.9 ENTRYPOINT

语法:

  • ENTRYPOINT [‘executable’, ‘param1’, ‘param2’] #将会调用exec执行,首选方式
  • ENTRYPOINT command param1 param2 #将会调用/bin/sh -c执行

解释:ENTRYPOINT 指令中指定的命令会在镜像运行时执行,在 Dockerfile 中只能存在一个,如果使用了多个 ENTRYPOINT 指令,则只有最后一个指令有效。ENTRYPOINT 指令中指定的命令(exec执行的方式)可以通过 docker run 来传递参数,例如 docker run images -l 启动的容器将会把 -l 参数传递给 ENTRYPOINT 指令定义的命令并会覆盖 CMD 指令中定义的默认参数(如果有的话),但不会覆盖该指令定义的参数,例如 ENTRYPOINT [‘ls’,’-a’],CMD [‘/etc’],当通过 docker run image 启动容器时该容器会运行 ls -a /etc 命令,当使用 docker run image -l 启动时该容器会运行 ls -a -l 命令,-l 参数会覆盖 CMD 指令中定义的/etc参数。

注意:

  • 当使用 ENTRYPOINT 指令时生成的镜像运行时只会执行该指令指定的命令。
  • 当出现 ENTRYPOINT 指令时 CMD 指令只可能(当 ENTRYPOINT 指令使用 exec 方式执行时)被当做 ENTRYPOINT 指令的参数使用,其他情况则会被忽略。

3.10 VOLUME

语法:VOLUME [‘samepath’]

解释:VOLUME 指令用来设置一个挂载点,可以用来让其他容器挂载以实现数据共享或对容器数据的备份、恢复或迁移。

3.11 USER

语法:USER [username|uid]

解释:USER指令用于设置用户或uid来运行生成的镜像和执行 RUN 指令。

3.12 WORKDIR

语法:WORKDIR /path/to/workdir

解释:WORKDIR 指令用于设置 Dockerfile 中的 RUN、CMD 和 ENTRYPOINT 指令执行命令的工作目录(默认为/目录),该指令在 Dockerfile 文件中可以出现多次,如果使用相对路径则为相对于 WORKDIR 上一次的值,例如 WORKDIR /data,WORKDIR logs,RUN pwd 最终输出的当前目录是 /data/logs。

4. 最佳实践

4.1 使用 .dockerignore 文件

在 docker 构建镜像的第一步,docker CLI 会先在上下文目录中寻找 .dockerignore 文件,根据 .dockerignore 文件排除上下文目录中的部分文件和目录,然后把剩下的文件和目录传递给 docker 服务。.dockerignore 语法同 .gitignore。

4.2 避免安装不必要的包

为了减小复杂度、依赖、文件大小和创建的时间,应该避免安装额外或者不必要的包。例如,我们不必在一个数据库镜像中包含一个文本编辑器。

4.3 对于多行参数要做字典序排序

只要有可能,通过对多行参数进行字母数字排序来缓解后续变更。这将帮助你避免重复的包并且更容易更新。在反斜线( )前添加一个空格是个好习惯。

RUN apt-get update && apt-get install -y   
  bzr 
  cvs 

4.4 尽量利用 build 镜像的缓存

未分类

在创建镜像过程中,Docker 将按照 Dockerfile 指定步骤执行每个指令。 一般情况下,对于每条命令,docker 都会生成一层镜像。如果在构建某个镜像层的时候,发现这个镜像层已经存在了,就直接使用,而不是重新构建。

大部分指令是通过与缓存进行对比该指令、执行指令的基础镜像,判断是否使用缓存。除了 ADD 和 COPY,这两个指令会复制文件内容到镜像内,docker 还会检查每个文件内容校验和(不包括最后修改时间和最后访问时间),如果校验和不一致,则不会使用缓存。

4.5 每个镜像只有一个功能

不要在容器里运行多个不同功能的进程,每个镜像中只安装一个应用的软件包和文件,需要交互的程序通过 pod(kubernetes 提供的特性) 或者容器之间的网络进行通信。这样可以保证模块化,不同的应用可以分开维护和升级,也能减小单个镜像的大小。

4.6 不要在构建中升级版本

更新将发生在基础镜像里,不要在你的容器内来apt-get upgrade更新。因为在隔离情况下,如果更新时试图修改 init 或改变容器内的设备,更新可能会经常失败。它还可能会产生不一致的镜像,因为你不再有你的应用程序该如何运行以及包含在镜像中依赖的哪种版本的正确源文件。

从零开始使用 Docker 打包 Django 开发环境 (1) 环境搭建

Vagrant 适合用来管理虚拟机,而 Docker 适合用来管理应用环境。为了更好地模拟真实运行环境,本系列文章借助 Docker 和 Docker Compose 搭建 Nginx + uWSGI+ Django + MySQL + Redis + Rabbit 的开发环境。

1. 基本概念

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包应用以及依赖包到一个轻量级、可移植的容器中,然后发布到机器上。

Docker Compose 是一个用来定义和运行复杂应用的 Docker 工具。

2. Docker 安装和使用

2.1 安装

在 Linux 上 安装 Docker。

# curl -sSL https://get.daocloud.io/docker | sh

在 Linux 上 安装 Docker Compose。

# curl -L https://get.daocloud.io/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose

2.2 查看安装信息

安装完毕后,可以通过如下命令检测是否安装成功。

查看 Docker 版本

# docker --version 
Docker version 1.12.6, build 88a4867/1.12.6  

查看 docker-compose 版本

# docker-compose --version
docker-compose version 1.16.1, build 6d1ac21  

拉起 Docker Deamon。Docker Client 需要将 Console 输入的命令,发送给 Daemon 执行。

# service docker start

通过,docker info 命令可以看到,本地使用的是 docker 原生的镜像源。

# docker info // 查看 docker 信息
Docker Root Dir: /var/lib/docker  
Debug Mode (client): false  
Debug Mode (server): false  
Registry: https://index.docker.io/v1/  
Insecure Registries:  
 127.0.0.0/8
Registries: docker.io (secure)  

2.3 拉取、启动镜像

拉取 hello-world 镜像。

# docker pull hello-world
Using default tag: latest  
Trying to pull repository docker.io/library/hello-world ...  
latest: Pulling from docker.io/library/hello-world

Digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f  

启动 hello-world 镜像。

# docker run hello-world

Hello from Docker!  
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:  
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:  
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:  
 https://cloud.docker.com/

For more examples and ideas, visit:  
 https://docs.docker.com/engine/userguide/

查看本地镜像列表。

# docker images 
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE  
docker.io/hello-world   latest              1815c82652c0        12 weeks ago        1.84 kB  

2.4 配置加速器(可选)

使用 Docker 的时候,经常需要从官方获取镜像,但是由于网络原因,拉取镜像的过程非常耗时,严重影响使用 Docker 的体验。

这里使用的 DaoDlcoud 提供的加速器,通过智能路由和缓存机制,提升了访问 Docker Hub 的速度。

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://6c5fbccc.m.daocloud.io

Nginx+uWSGI+Mysql+Django+Virtualenv环境部署

安装软件包

我的Linux是Ubuntu,需要安装Python3,如果你需要安装其他版本替换即可

sudo apt-get install mysql-server python3 python-dev python3-pip virtualenv

配置Virtualenv及Python环境

首先,这个Virtualenv并不是必须的,他的作用就是创建一个“隔离”的Python运行环境。

我想大家都碰到过在一台电脑上同时开发多个应用程序,如果应用A需要Python 2.7,而应用B需要Python 2.6怎么办?有时还会碰到不只是Python版本的不一致,比如Django等软件包版本。

这种情况下,每个应用可能需要各自拥有一套“独立”的Python运行环境。

1、新建独立运行环境,命名为pyblog_env

virtualenv pyblog_env --python=python3.5 --no-site-packages

–python指定Python版本 –no-site-packages不复制系统已安装Python包

2、进入pyblog_env环境

source pyblog_env/bin/activate

这时会发现命令提示符前面多了一个(pyblog_env),变成(pyblog_env)user@hostname:~$ 这种形式,这表示我们已经进入到刚刚创建的虚拟环境。 然后再通过pip安装包,都会安装到这个环境下,不会对系统环境造成影响。 退出虚拟环境命令:deactivate

3、安装项目依赖

pip3 install django PyMySQL mysqlclient Pillow
#如果有需求文件,比如requirements.txt,则执行
pip3 install -r requirements.txt

Django项目配置

1、上传Django项目,我的项目在GitHub。

git clone https://github.com/zytx/pyblog.git

2、配置项目的数据库信息

3、数据迁移

python manage.py makemigrations
python manage.py migrate

4、建立超级用户:

python manage.py createsuperuser

5、收集静态文件:

python manage.py collectstatic

6、测试项目 运行开发服务器看项目能否正常运行

python manage.py runserver 0.0.0.0:8000

访问ip:8000看是否出错

uWSGI 配置

退出刚才进入的虚拟环境,使用命令:deactivate

1、安装uWSGI

pip3 install uwsgi

2、运行测试:

uwsgi --http :8000 --home /home/zytx/pyblog_env/ --chdir /home/zytx/pyblog_env/pyblog -w pyblog.wsgi

–home Virtualenv的虚拟环境目录 –chdir Django项目目录

如果访问IP:8000可以看到项目,就说明Python环境和uWSGI是没有问题的

3、创建配置文件 接下来在项目里新建一个配置文件uwsgi.ini

[uwsgi]
# 项目根目录路径(full path)
chdir           = /home/zytx/pyblog_env/pyblog/
# Django的 wsgi 文件
module          = pyblog.wsgi:application
# virtualenv目录 (full path)
home            = /home/zytx/pyblog_env/

master          = true
# 最大工作进程数(CPU密集型建议设为CPU核心数,IO密集型建议设为CPU核心数的两倍)
processes       = 2
# unix套接字文
socket          = /home/zytx/pyblog_env/pyblog.sock
# socket文件权限
chmod-socket    = 777
# 退出时清空环境
vacuum          = true

4、后台启动uWSGI

uwsgi /home/zytx/pyblog_env/pyblog/uwsgi.ini&

Nginx 配置

1、创建配置文件

sudo vi /etc/nginx/sites-available/pyblog

加入如下内容:

server {
    listen 80;
    server_name www.immrz.com;
    root /home/zytx/pyblog_env/pyblog/;

        location /media/  {
            #如果你的media目录不在root里,可以配置 alias /path/to/your/mysite/media;
        }

        location  /static/ {
            #如果你的static目录不在root里,可以配置 alias /path/to/your/mysite/static;
        }

        location / {
            uwsgi_pass  unix:///home/zytx/pyblog_env/pyblog.sock;
            include uwsgi_params; # the uwsgi_params file you installed
        }
}

软连接到sites-enabled

sudo ln -s /etc/nginx/sites-available/pyblog /etc/nginx/sites
enabled/

2、重新加载Nginx配置

sudo service nginx reload

如果配置无误我们就可以让uWSGI开机运行

#编辑/etc/rc.local,在exit0之前加入
/usr/local/bin/uwsgi --ini /home/zytx/pyblog_env/pyblog/pyblog.uwsgi.ini&