Python环境Django+uwsgi+nginx的部署
Django+uwsgi+nginx的部署
欢迎使用Django+uwsgi+nginx
最近被要求使用python写接口,这让写了三年java接口的我又要从一个小白开始写起。搞了两天,翻阅了无数的博客,终于搞了一个大概。这次从初始化创建Django开始,到正式访问结束。大家凑乎看看吧。。。
Django
Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。
使用 Django,只要很少的代码,Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容,并进一步开发出全功能的 Web 服务 Django 本身基于 MVC 模型,即 Model(模型)+ View(视图)+ Controller(控制器)设计模式,MVC 模式使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。
----摘自菜鸟教程
本次开发使用的开发工具为Pycharm,一款出自于JetBrains的优秀的python开发工具。主要是IDEA开发JAVA的时间长了,对这个布局已经很熟悉了,懒得换而已。
windows安装python
我使用的是windows电脑,具体安装方法为:
- 进入python的官方网站:点我啊,标题栏有个downloads,选择你的系统,找到对应的位数,点击之后就可以下载了(选择那个executable那个的)。
- 下载完毕后,有一个.exe的文件,打开它,红框内的东西记住选了,完了一路下一步就可以了。
- 安装好之后,使用键盘的WIN+R调出运行,输入cmd,键入
python -V
。如果出现以下图片,证明你的python已经安装好了。
创建DJango项目
- 打开Pycharm,左上角选择file,new project,左边选择Django,右边输入你喜欢的名字,create!
- 这就是Django的一个初始化的格式,我们需要新建一个module
- 在下面的Terminal中键入
django-admin.py startapp appTest
,就会新增一个app模块 - views.py相当于MVC项目中的Controller的作用,用来接收请求,而
@RequestMaping
相关的映射配置在urls.py中
5.右上角启动之后,点击控制台的连接,在地址后面输入hello就可以看到页面啦
连接数据库
- 数据库相关的配置是配置在setting.py中的,django默认使用的数据库为sqlite3,你可以根据自己的需求配置不同的数据库
oracle:
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'ip:port/databaseName',
'USER': 'userName',
'PASSWORD': 'password',
},
mysql:
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "databaseName",
'USER':'userName',
'PASSWORD': 'password',
'HOST': 'ip',
'PORT': 'port'
},
注:在连接oracle的时候,需要下载cx_oracle,并且这玩意还必须根据你的数据库版本及位数,python版本和位数来下载,稍微有一点不一样就会报错
oracle报错:
django.core.exceptions.ImproperlyConfigured: Error loading cx_Oracle module: No module named 'cx_Oracle'
这个错误的原因是你使用了连接oracle但是却没有拿到oracle的驱动之类的,因此需要下载cx_oracle,进去之后找到符合你python位数和数据库版本的cx_oracle
安装一下就好了(我是直接执行pip install cx-Oracle
)
进入oracle网站,选择符合你系统位数的连接,点进去后寻找你数据库的版本,下载完成后,解压,将文件中的oci.dll
、oraocci11.dll
、oraociei11.dll
这三个文件拷贝到项目中,路径是项目名\venv\Lib\site-packages\
- mysql:
Traceback (most recent call last)
File CUsersLenovoAppDataLocalProgramsPythonPython38libthreading.py, line 932, in _bootstrap_inner
self.run()
File CUsersLenovoAppDataLocalProgramsPythonPython38libthreading.py, line 870, in run
self._target(self._args, self._kwargs)
File EDjangoTestvenvlibsite-packagesdjangoutilsautoreload.py, line 53, in wrapper
fn(args, kwargs)
File EDjangoTestvenvlibsite-packagesdjangocoremanagementcommandsrunserver.py, line 109, in inner_run
autoreload.raise_last_exception()
File EDjangoTestvenvlibsite-packagesdjangoutilsautoreload.py, line 76, in raise_last_exception
raise _exception[1]
File EDjangoTestvenvlibsite-packagesdjangocoremanagement__init__.py, line 357, in execute
autoreload.check_errors(django.setup)()
File EDjangoTestvenvlibsite-packagesdjangoutilsautoreload.py, line 53, in wrapper
fn(args, kwargs)
File EDjangoTestvenvlibsite-packagesdjango__init__.py, line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File EDjangoTestvenvlibsite-packagesdjangoappsregistry.py, line 114, in populate
app_config.import_models()
File EDjangoTestvenvlibsite-packagesdjangoappsconfig.py, line 211, in import_models
self.models_module = import_module(models_module_name)
File CUsersLenovoAppDataLocalProgramsPythonPython38libimportlib__init__.py, line 127, in import_module
return _bootstrap._gcd_import(name[level], package, level)
File frozen importlib._bootstrap, line 1014, in _gcd_import
File frozen importlib._bootstrap, line 991, in _find_and_load
File frozen importlib._bootstrap, line 975, in _find_and_load_unlocked
File frozen importlib._bootstrap, line 671, in _load_unlocked
File frozen importlib._bootstrap_external, line 783, in exec_module
File frozen importlib._bootstrap, line 219, in _call_with_frames_removed
File EDjangoTestvenvlibsite-packagesdjangocontribauthmodels.py, line 2, in module
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
File EDjangoTestvenvlibsite-packagesdjangocontribauthbase_user.py, line 47, in module
class AbstractBaseUser(models.Model)
File EDjangoTestvenvlibsite-packagesdjangodbmodelsbase.py, line 121, in __new__
new_class.add_to_class('_meta', Options(meta, app_label))
File EDjangoTestvenvlibsite-packagesdjangodbmodelsbase.py, line 325, in add_to_class
value.contribute_to_class(cls, name)
File EDjangoTestvenvlibsite-packagesdjangodbmodelsoptions.py, line 208, in contribute_to_class
self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
File EDjangoTestvenvlibsite-packagesdjangodb__init__.py, line 28, in __getattr__
return getattr(connections[DEFAULT_DB_ALIAS], item)
File EDjangoTestvenvlibsite-packagesdjangodbutils.py, line 207, in __getitem__
backend = load_backend(db['ENGINE'])
File EDjangoTestvenvlibsite-packagesdjangodbutils.py, line 111, in load_backend
return import_module('%s.base' % backend_name)
File CUsersLenovoAppDataLocalProgramsPythonPython38libimportlib__init__.py, line 127, in import_module
return _bootstrap._gcd_import(name[level], package, level)
File EDjangoTestvenvlibsite-packagesdjangodbbackendsmysqlbase.py, line 18, in module
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured Error loading MySQLdb module.
Did you install mysqlclient
解决办法:简单明了,看到最后一句了没?Did you install mysqlclient?
来自灵魂深处的提问,所以解决办法就是:pip install mysqlclient
uWSGI
uWSGI 是一个快速的、纯C语言开发的、自维护的、对开发者友好的 WSGI 服务器,旨在提供专业的 Python web应用发布和开发。可使用 C/C++/Objective-C 来为 uWSGI 编写插件。
– 摘自开源中国
在Linux上安装python3
参见linux安装python3的方法
附链接一只:wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz
安装uWSGI
- 按照第一步装好python了之后,我们可以使用
pip3
命令去下载关于python的模块了,我们使用pip3 install uwsgi
安装完成后,会有一行提示
WARNING: You are using pip version 19.2.3, however version 20.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
看着应该是要执行的,就执行一下吧pip3 install --upgrade pip
为uwsgi建立软连接 ln -s /usr/local/python3/bin/uwsgi /usr/bin/uwsgi
- 安装好了之后,为了测试我们的uWSGI有没有安装成功,我们可以建立一个测试类来测试一下。
进入一个你喜欢的目录(我是建了一个新的用户进行测试),写一个python脚本:firstpy.py
def application ( env,start_response ):
start_response ('200 OK',[('Content-Type','text / html' )])
return [ b"Hello World"]
保存之后,执行命令uwsgi --http :8080 --wsgi-file firstpy.py
访问你的服务器地址+端口号,例如我的是192.168.1.101:8080
。看到以下页面即视为安装成功
创建python的虚拟环境
- 安装virtualenvwrapper,登录服务器(root或者你自己的都行)使用pip3安装virtualenvwrapper
pip3 install virtualenvwrapper
- 把下面两行代码添加到
~/.bashrc
文件中
打开文件vim ~/.bashrc
写入以下两行代码
export WORKON_HOME=~/fakeEnv #设置virtualenv的统一管理目录
export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages' #添加virtualenvwrapper的参数,生成干净隔绝的环境
export VIRTUALENVWRAPPER_PYTHON=/opt/python347/bin/python3 #指定python解释器
source /opt/python34/bin/virtualenvwrapper.sh #执行virtualenvwrapper安装脚本
读取文件,使得生效,此时已经可以使用virtalenvwrappersource ~/.bashrc
- 创建一个虚拟环境:
mkvirtualenv django
这会在 ~/fakeEnv 中创建 django文件夹。此时,你的虚拟环境的目录就是django
在虚拟环境上工作:激活虚拟环境django
workon django
手动停止虚拟环境
deactivate
删除虚拟环境,需要先退出虚拟环境
rmvirtualenv django
进入虚拟环境
source ~/fakeEnv/django/bin/activate
这时你能在你的用户名前看到(django),这就说明你已经进入虚拟环境了
- 在Pycharm上开发完成后,你可以使用命令
pip freeze > requirements.txt
将你在开发时导入的依赖库导出,并且在虚拟环境中执行pip install -r requirements.txt
安装项目依赖。 - 关于代码,可以选择直接从git下拉,也可以本地直接打包,然后放在指定目录解压出来就行了
注意:部署时有关数据库的坑:
在部署成功之后,我进入了我的项目,想使用命令python3 manage.py runserver
来启动项目,结果却遇到了一个奇怪的错误
(django) [python@localhost pythonDjango]$ python3 manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
Exception in thread django-main-thread:
Traceback (most recent call last):
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/base/base.py", line 220, in ensure_connection
self.connect()
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/base/base.py", line 197, in connect
self.connection = self.get_new_connection(conn_params)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/oracle/base.py", line 228, in get_new_connection
return Database.connect(
cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". See https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html for help
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/python3/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/local/python3/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/utils/autoreload.py", line 53, in wrapper
fn(*args, **kwargs)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/core/management/commands/runserver.py", line 120, in inner_run
self.check_migrations()
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/core/management/base.py", line 458, in check_migrations
executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
self.loader = MigrationLoader(self.connection)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/migrations/loader.py", line 49, in __init__
self.build_graph()
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/migrations/loader.py", line 212, in build_graph
self.applied_migrations = recorder.applied_migrations()
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 76, in applied_migrations
if self.has_table():
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 56, in has_table
return self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor())
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/base/base.py", line 260, in cursor
return self._cursor()
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/base/base.py", line 236, in _cursor
self.ensure_connection()
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/base/base.py", line 220, in ensure_connection
self.connect()
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/base/base.py", line 220, in ensure_connection
self.connect()
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/base/base.py", line 197, in connect
self.connection = self.get_new_connection(conn_params)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/home/python/fakeEnv/django/lib/python3.8/site-packages/django/db/backends/oracle/base.py", line 228, in get_new_connection
return Database.connect(
django.db.utils.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". See https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html for help
一开始百度,他们都说是因为python的位数或者oracle的位数与cx_oracle的位数不一致导致的,但是我反复确认,的确都是64位的。正当我快把头发都拔光的时候,突然想起来我在开发的时候从oracle官网下载了一个包,把oci.dll等文件拷贝进了我的开发环境的虚拟环境中,这时我在luinx中重新创建虚拟环境,那我的那些包是不是需要重新拷贝进去呢?
通过那些.py文件我确定了我的虚拟环境的地址,接下来我打开了oracle的帮助网站,找到了Install Oracle Client这一段话
Install Oracle Client
Using cx_Oracle requires Oracle Client libraries to be installed. These provide the necessary network connectivity allowing cx_Oracle to access an Oracle Database instance.
If your database is on a remote computer, then download the free Oracle Instant Client “Basic” or “Basic Light” package for your operating system architecture. Use the RPM or ZIP packages, based on your preferences.
Download an Oracle 19, 18, 12, or 11.2 “Basic” or “Basic Light” zip file: 64-bit or 32-bit, matching your Python architecture.
The latest version is recommended. Oracle Instant Client 19 will connect to Oracle Database 11.2 or later.
Unzip the package into a single directory that is accessible to your application. For example:
mkdir -p /opt/oracle
cd /opt/oracle
unzip instantclient-basic-linux.x64-19.6.0.0.0dbru.zip
Install the libaio package with sudo or as the root user. For example:
sudo yum install libaio
On some Linux distributions this package is called libaio1 instead.
On recent Linux versions, such as Oracle Linux 8, you may also need to install the libnsl package.
这个步骤就相当于在windows下把oci.dll等文件放到venv下的操作,然后再次进入虚拟环境,执行python3 manage.py runserver
,看到了熟悉的成功页面,顿时出了一身冷汗
使用uWSGI启动Django
- 首先需要在与项目同名的目录下创建uwsgi.ini的文件,具体内容如下:
[uwsgi]
chdir = /home/python/server/pythonDjango
#你的项目目录
home = /home/python/fakeEnv/django
# 如果有虚拟环境,则需要指定虚拟环境目录; 没有则注释掉
module = pythonDjango.wsgi
# 指向自己Django项目目录下mysite目录下的wsgi文件
master = True
processes = 4
# 使用进程数
harakiri = 60
# 最大超时时间
max-requests = 5000
# 最大请求数,到了后就会自动重启
socket = 127.0.0.1:8080
# socket连接地址和端口,和之前nginx配置一致
pidfile = /home/python/server/pythonDjango/pythonDjango/pythonDjango.pid #在失去权限前,将pid写到指定的pidfile文件中
daemonize = /home/python/logs/pythonDjango/pythonDjango.log
# 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器
# chmod-socket = 664 # 如果没有权限访问uWSGI的socket,这里可以设置权限
vacuum = True
# 服务退出或重启,自动删除pid和socket文件
- 保存后使用命令
uwsgi --ini uwsgi.ini
即可启动项目 - 重启:
uwsgi --reload pythonDjango.pid
,停止:uwsgi --stop pythonDjango.pid
nginx
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,*使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
–摘自百度百科
- 这一部分没啥好说的,直接贴nginx.conf:
http{
upstream django {
# 注意这里的server要和uwsgi.ini配置文件中的socket保持一致
server 127.0.0.1:8080; # for a web port socket
}
server {
listen 8881;
server_name localhost; # 这里填自己的域名或者服务器的ip(决定你今后访问网站的方式)
charset utf-8;
root /usr/share/nginx/html;
location / {
root /home/python/server/pythonDjango/appTest; # 这是Django App的路径
uwsgi_pass django;
include uwsgi_params; # the uwsgi_params file you installed
}
}
}
- 完成之后,重启nginx:
./nginx -s reload
本文地址:https://blog.csdn.net/Incosolable/article/details/107049891
推荐阅读
-
用docker部署RabbitMQ环境的详细介绍
-
Python环境下安装使用异步任务队列包Celery的基础教程
-
Python环境Django+uwsgi+nginx的部署
-
anaconda虚拟环境 使用的还是base环境的python/pip
-
Python数据可视化高级库pyecharts的用法,相关环境的安装部署和第一个简单的可视化柱状统计图
-
深度学习python环境搭建的版本问题及错误
-
三分钟完成 ubuntu16.04初始化,Java,maven,docker环境的部署问题
-
python 2.7 环境,读取一个 json字符串的文件,并解析(文件解析)
-
Python环境下搭建属于自己的pip源的教程
-
Linux系统上Nginx+Python的web.py与Django框架环境