现有的脚本、工具想找个统一的地方能让开发和其他人员使用,就想弄个网站。调研了下,发现Django不错,虽然都说性能不好,但上手快、敏捷开发,符合我们内部使用需求,就用他了。下面记录我搭建Django服务的过程
一、申请服务器(阿里云、腾讯云等等,略)
注:下面的命令是在linux下的,如果是CentOS的,把相应命令改成yum的命令即可
二、安装和开d发环境一致的python版本
1、安装python3.6
apt-get install software-properties-common
add-apt-repository ppa:jonathonf/python-3.6
apt-get update
apt-get install python3.6
2、创建软连接
cd /usr/bin
# 如果还需要保留python2的,则下面删除python的软连接不用操作
rm python
ln -s python3.6 python
rm python3
ln -s python3.6 python3
3、安装pip
apt-get install python3-pip
pip3 install --upgrade pip
如果是CentOS系统,可以参考这篇文章
4、安装虚拟环境(可选)
pip3 install virtualenv
5、创建虚拟环境(可选)
virtualenv mysite_env #创建虚拟环境
source mysite_env/bin/activate # 进入虚拟环境
deactivate #退出虚拟环境
若出现找不到virtualenv命令提示,可参考这篇文章
三、安装Git(或其他的代码管理工具)
# 安装Git
apt-get install git
# clone项目代码
git clone XXX项目地址
CentOS系统下编译安装(yum安装的版本过低)可参考这篇文章
四、安装项目依赖包
1、生成、安装依赖包
# 在开发环境生成requirements.txt文件
pip freeze >requirements.txt
# 由于默认的pip freeze命令生成的依赖包是你环境下所有的包,不是跟你项目相关的包也会生成,可能会有很多,所以这里我使用第三方包 pipreqs
pipreqs ./
# pipreqs 会去遍历你项目目录,尽可能的识别你的依赖包,但可能会遗漏,需要你检查下
# 在服务器上安装依赖文件
pip install -r requirements.txt
2、安装依赖包时报错的解决
-
问题1:安装mysqlclient出现“OSError: mysql_config not found”错误
解决方法:
apt-get install libmysqlclient-dev python3-dev
# CenOS系统下的命令
yum install mysql-devel gcc gcc-devel python-devel
-
问题2:matplotlib安装报错
解决方法见这篇文章
-
问题3: 提示xadmin-2.0.1找不到,这是因为xadmin针对Django2版本的包是手动安装的(增强的后台管理插件,不需要的可不装)
解决方法:
# 手动安装
pip install git+git://github.com/sshwsfc/xadmin.git@django2
五、安装配置mysql数据库
1、安装mysql
wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb
dpkg -i mysql-apt-config_0.8.10-1_all.deb
apt-get update
apt-get install mysql-server
# 然后设置密码
CentOS系统下安装mysql可参考这篇文件(mysql5.6)
2、配置数据库(配置文件一般在/etc/my.cnf 文件里)
[mysqld]
# 设置默认使用的端口
port=3306
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。这是为了防止有人试图攻击数据库
max_connect_errors=10
# 服务端使用的字符集
character-set-server=utf8mb4
# 数据库字符集对应一些排序等规则使用的字符集
collation-server=utf8mb4_general_ci
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件作为认证加密方式
# MySQL8.0默认认证加密方式为caching_sha2_password
default_authentication_plugin=mysql_native_password
3、创建用户、创建库
#进入数据库
mysql -u root -p
# 创建库
CREATE DATABASE mysite_db DEFAULT CHARSET=utf8 DEFAULT COLLATE utf8_unicode_ci
# 创建用户
CREATE USER 'test’@‘localhost’ IDENTIFIED BY ’Test123456@‘;
# 用户授权该表全部权限
GRANT ALL PRIVILEGES ON mysite_db.* TO ’Test123456@‘;
# 刷新入库生效
FLUSH PRIVILEGES;
4、数据库导出导入
# 从开发库里导出
mysqldump -u root -p mysite_db > data.sql
# 把data.sql文件拷到服务器上(可以用工具,也可以用scp命令)
scp data.sql root@xx.xx.xx.xx:/home/data.sql
# 进入服务器数据库
mysql -u root -p mysite_db
# 导入数据文件
source data.sql;
5、如果不是通过数据库导入方式建表的,那重新创建表即可
python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py createcachetable # 缓存表的名称需在setting文件里已设置
六、测试启动
启动测试下,服务是否正常
python3 manage.py runserver 0.0.0.0:80
七、用Nginx+uWSGI部署
1、安装uwsgi(可参考官方文档)
# 安装uwsig
pip3 install uwsgi
2、基础测试
创建一个名为 test.py的文件,vim编辑文件:
def application ( env,start_response ):
start_response ('200 OK',[('Content-Type','text / html' )])
return [ b “Hello World” ] #python3
3、测试运行
uwsgi --http:8000 --wsgi-file test.py
# 说明 --http :8000 使用http协议 端口8000 --wsgi-file test.py 加载指定文件
# 如果出现HelloWorld说明可用
# 如果出现--- no python application found, check your startup logs for errors —错误,说明python版本有多个,而你的uwsgi不是装在默认的那个python里,所以可以在虚拟机里创建一个只有一个python的环境启动,或者在/etc/profile里把python路径改成安装uwsgi的python路径
# 访问不了,还有可能是服务器没有开放8000端口,比如阿里云是默认关闭8000端口的,去开启即可
4、使用uwsgi测试你的项目
# 进入的项目文件夹(与manage.py同一级)
# 确保项目可以正常工作
python3 manage.py runserver 0.0.0.0:8000
# 如果发现django模块不能导入,则是因为没有添加环境变量,具体命令如下:vim ~/.bash_profile,添加django的路径export PATH=$HOME 在此部分添加,用冒号隔开,具体格式请搜索 $PATH。
# 如果地址不能访问,检查django项目的settings.py设置,把 ALLOWED_HOSTS = [] 改为 ALLOWED_HOSTS = ['*’]
# 如果还是不能访问,查看8000端口是否开放
# 用uwsgi运行项目
uwsgi --http :8000 --chdir /home/mysite --home /home/mysite_env --module mysite.wsgi:application
# 上面具体参数设置可见[官方文档](https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/uwsgi/#configuring-and-starting-the-uwsgi-server-for-django)
5、安装nginx(CentOS)
# 安装nginx(已装过的可略)
# 下载
wget [http://nginx.org/download/nginx-1.14.1.tar.gz](http://nginx.org/download/nginx-1.14.1.tar.gz)
# 解压
tar -xzvf nginx-1.14.1.tar.gz
# 进入目录
cd nginx-1.14.1/
# 安装依赖
yum install -y pcre pcre-devel
yum install -y openssl openssl-devel
# 创建Nginx的用户组及用户
groupadd nginx
useradd -s /sbin/nologin -M -g nginx nginx
# 编译及安装
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make && make install
# 检查并启动(以下三个命令都要运行)
/usr/local/nginx/sbin/nginx -t # 测试nginx.conf的配置是否正确
/usr/local/nginx/sbin/nginx # 直接启动
/usr/local/nginx/sbin/nginx -s reload # 重启
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf # 根据nginx.conf里的配置,启动nginx服务
# 具体可参考[Linux(CentOS 6.5) 下Nginx 安装,重启和停止](https://blog.csdn.net/greensomnuss/article/details/80986238)
6、配置nginx(CentOS)
# 将/usr/local/nginx/conf目录下的uwsgi_params文件复制到你的项目目录
cp /usr/local/nginx/conf/uwsgi_params /home/mysite/
# 创建myconfs文件夹
mkdir /home/myconfs
# 创建一个名为mysite_nginx.conf的文件(可以在任意路径,只要你能找到,这里我把它放在/home/myconfs/)
vim /home/myconfs/mysite_nginx.conf
# 按自己路径写入配置信息(如下)
具体配置(可见nginx文档)
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 {
# 你的网站监听的端口,此处先用8000端口测试,正式部署可以改为80或其他
listen 8000;
# 你的网站的域名
server_name *.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 /home/mysite/media; # 你的media的文件目录
}
location /static {
alias /home/mysite/collected_static; # 你的项目收集的静态文件目录(后边会将收集静态文件)
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/mysite/uwsgi_params; # uwsgi_params 文件所在目录
}
}
# 这个配置文件告诉nginx提供来自文件系统的媒体和静态文件,以及处理那些需要Django干预的请求。对于一个大型部署,让一台服务器处理静态/媒体文件,让另一台处理Django应用,被认为是一种很好的做法,但是现在,这样就好了。
让nginx的根文件载入你的mysite_nginx.conf配置的信息:
vim /usr/local/nginx/conf/nginx.conf

7、部署静态文件
# 在运行nginx之前,你必须收集所有的Django静态文件到静态文件夹里
# 编辑项目的settings
vim /home/mysite/mysite/settings.py
#添加
STATIC_ROOT = os.path.join(BASE_DIR, "collected_static/")
# 然后运行(如果之前用虚拟环境的,记得进入虚拟环境再操作)
python3 manage.py collectstatic
8、基本的nginx测试
# 启动nginx
/usr/local/nginx/sbin/./nginx
# 如果已经启动,则重启
/usr/local/nginx/sbin/./nginx -s reload
# 要检查是否正确的提供了媒体文件服务,上传一张图片(这里我上传的文件为 1.jpg)到 /home/sysite/media文件夹中
# 然后访问[http://example.com:8000/media/1.jpg](http://example.com:8000/media/1.jpg) - 如果这能正常工作,那么至少你知道nginx正在正确的提供文件服务。
# 最好将你的nginx先停止, 再开启,而不是重载
9、配置uwsgi,创建ini文件方便处理。ini参考如下
创建一个名为mysite_uwsgi.ini的文件
[uwsgi]
chdir = /home/mysite # 你的项目目录
home = /home/mysite_env # 如果有虚拟环境,则需要指定虚拟环境目录; 没有则注释掉
module = mysite.wsgi:application # 指向自己Django项目目录下mysite目录下的wsgi文件
master = True
processes = 4 # 使用进程数
harakiri = 60 # 最大超时时间
max-requests = 5000 # 最大请求数,到了后就会自动重启
socket = 127.0.0.1:8001 # socket连接地址和端口,和之前nginx配置一致
pidfile = /home/mysite_uwsgi/master.pid # 在失去权限前,将pid写到指定的pidfile文件中
daemonize = /home/mysite_uwsgi/mysite.log # 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器
# chmod-socket = 664 # 如果没有权限访问uWSGI的socket,这里可以设置权限
vacuum = True # 服务退出或重启,自动删除pid和socket文件
10、运行uWSGI
uwsgi -d --ini mysite_uwsgi.ini
# 参数 -d 为后台运行。此时你的django项目已经部署成功。
# 注意,必须nginx也要启动才能正常访问
11 、官方参考地址
nginx测试命令:nginx -t
查看uwsgi进程:ps -aux | grep uwsgi
正常关闭uwsgi进程:uwsgi --stop /home/mysite_uwsgi/master.pid
强制关闭全部uwsgi进程:ps -aux | grep uwsgi |awk '{print $2}'|xargs kill -9
重新加载uwsgi:uwsgi --reload /home/mysite_uwsgi/master.pid
参考文档:
(Django官网)https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/uwsgi/
(uwsgi中文)https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/tutorials/Django_and_nginx.html
(uwsgi英文)https://uwsgi.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
(自强学堂)https://code.ziqiangxuetang.com/django/django-nginx-deploy.html
八、使用Nginx+Gunicorn部署(其他方案)
可参考:Centos上Python应用部署详情(Nginx 和 Gunicorn 部署 Django项目)
九、配置清单(发布环境配置修改)
1、开发环境和生产环境配置分开
把原先的settings.py改名为settings_base.py,创建settings_development.py和settings_production.py文件。把基础共用的配置保留在base文件里,在development文件里只保留Degbu、DATABASES等其他需单独配置的设置,在production文件里同样,development和production继承base文件。注意配置不要重复




2、修改生产环境的配置:秘钥不明文显示
- 修改Debug为False
-
重新生成SECRET_KEY秘钥,并设置从环境变量里读取的方式获取(不在配置文件里明文显示)
- 数据库密码也一样,从环境变量里读取的方式获取(不在配置文件里明文显示)
- 邮箱的授权码也一样设置
# 重新生成秘钥方法
from django.core.management import utils
utils.get_random_secret_key() # 该方法可以生成秘钥
# linux里设置环境变量
vim /etc/profile
# 在文件最后面加上配置(如下图)
# 然后生效
source /etc/profile

3、修改生产环境的配置:增加日志文件配置(官方文档说明)
在settings_production.py文件最后增加日志配置
# 日志配置,若需要其他设置,可参考官方文档
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': ‘/home/mysite_debug.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
在服务器上创建并修改mysite_debug.log文件的权限
chmod 666 mysite_debug.log
4、修改生产环境的配置:更改邮件设置的端口和认证方式
有些云服务器对25端口有严格的限制,所以我们把端口和认证方式改成SSL的:
# 端口改成465,记得在服务器上把465端口开放
EMAIL_PORT = 465
# EMAIL_USE_TLS 改成 EMAIL_USE_SSL
EMAIL_USE_SSL = True
5、增加404、500错误页面
把404.html和500.html等文件放到templates根目录下即可
6、增加favicon.ico图标(浏览器图标)
- 第一种方法(这种方法可行):
把favicon.ico图标放到项目misite目录下(目录可以自定),然后同步到GITHUB,服务器pull同步数据
编辑nginx配置文件(vim /home/myconfs/mysite_nginx.conf):
location /favicon.ico {
# 你的favicon.ico文件path
alias /home/mysite/mysite/favicon.ico;
}
- 第二种方法(这个方法我在开发环境可以,部署到生产环境还是不行):
把favicon.ico文件放到根目录的static目录下,然后修改urls.py,如下
from django.contrib.staticfiles.views import serve
urlpatterns = [
...
path('favicon.ico', serve, {'path': 'favicon.ico'}),
]
- 第三种方法(这种方法可以用,但admin管理界面里默认是没有这个文件的)
# 修改base.html文件,在head里增加读取favicon.ico
<link href="{%static "favicon.ico" %}" rel="shortcut icon"/>
7、设置上传文件目录的权限
# 修改media目录的权限
chmod 777 media/
8、重新汇聚静态文件
python3 manage.py collectstatic
9、重启nginx和uwsgi测试
十、正常运行后发现的问题记录和处理
1、django-ckeditor插件里上传图片是报server 500错误
解决方法:网上有说把media文件夹权限改成777,但我不行,我把/usr/local/nginx/conf/nginx.conf配置文件里第一行原值#user nobody; 修改为 user root;并保存。使用 /usr/local/nginx/sbin/nginx -s reload 命令重新加载配置文件即可。

但我不想用root,但试了改成nginx用户等都不行,暂时没有找到其他办法。
2、我们在页面编辑的时候,总是要写代码的,但现在的django-ckeditor插件还没有设置插入代码的功能
解决方法:在settings设置里,修改CKEDITOR_CONFIGS的设置:
CKEDITOR_CONFIGS = {
'default': {
'width': 'auto',
'toolbar': (
['div', 'Source', '-', 'Preview'],
['Copy', 'Cut', 'Paste', 'PasteText', 'PasteFromWord',],
['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'],
['Bold', 'Italic', 'Underline', 'Strike', '-', 'Subscript', 'Superscript'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak'],
['Styles', 'Format', 'Font', 'FontSize'],
['TextColor', 'BGColor'],
['Maximize', 'ShowBlocks', '-', 'About'],
['CodeSnippet', '-', 'Print'],
),
# 插件
'extraPlugins': ','.join(['codesnippet', 'prism', 'widget', 'lineutils', ]),
},
}
# 其中插件codesnippet既是代码编辑功能,记得在toolbar里加上'CodeSnippet’按钮
# prism为代码高亮插件
3、加了codesnippet后,可以编辑代码了,但当非编辑状态下看的时候,发现代码没有高亮显示,不美观
解决方法:增加prism插件(详细步骤可见这篇文章).
-
从ckeditor官网下载 插件prism(点这里直接下载),然后将其解压到ckeditor/static/ckeditor/ckeditor/plugins路径下,同样的我们需要在CKEDITOR_CONFIGS里将extraPlugins对应的value里加入插件 'prism' 和另外两个插件"lineutils"、"widget" ,这两个插件无须下载,在django-ckeditor中已经有了.
-
去prismjs官网下载css文件http://prismjs.com/download.html,选择你喜欢的主题,勾选支持的语言,以及别忘选择line-numbers功能,下载后把他解压到自己项目的static/下
-
然后在模板中引用静态文件即可
网友评论