Nginx + Uwsgi + Django部署详细流程
使用uWSGI 和nginx 设置Django 和您的Web 服务器
读完这篇文档,你可能已经能解决90%(甚至100%)的问题了。剩下的10% 的问题(我遇到的)将在我的部署过程中得到解决。
(第一次部署过程很粗糙,遇到的很多问题都没有好好记录,现在正在架设一个相对干净的服务器,重新部署,以便能够克服之前的坑,并对配置做一些优化。)
检查服务器端口配置,检查配置文件是否正确,检查防火墙(我配置时没有遇到这个问题)google.欢迎留言,一起解决问题~
环境
阿里云:Ubuntu 14.04 64位
本机:windows10
蟒蛇:3.6.6
工具
IDE:Pycharm(代码部署功能比较好用)
文件图形化客户端:WinSCP(查看服务器文件结构)
virtualbox虚拟机(这个其实无所谓,只是觉得开个虚拟机直接连接服务器比较舒服)
预配置
申请一个阿里云服务器
获取服务器实例
获取IP
配置安全组([配置放行端口](
))
连接到服务器的方法有多种。这里我就不详细说了。我更喜欢使用Ubuntu系统使用ssh直连
安装ssh
sudo apt-get install ssh
连接到目标服务器
ssh root@xx.xx.xxx.xxx
xxx部分为服务器的公网IP地址,root为用户名(后续部署操作不建议使用root账号)
连接服务器
sudo adduser 呼吸
详细过程你可以自己google一下:)
(创建用户后一定要添加sudo权限,避免后续权限问题)
配置用户
由于各个项目之间的python版本问题,服务器自带的python2(现在也自带了python3,但是版本可能达不到需求)远远不能满足需要,结果是你的多个python服务器中安装了版本,每个项目依赖不同的版本来运行。那么管理的必要性就不言而喻了。另外,每个项目都需要独立的运行环境(需要单独管理项目依赖关系,否则将成为噩梦)。这是通过创建虚拟环境来解决的。
使用pyenv管理python版本
首先更新系统环境,保证后续操作不会因为缺少某个工具而失败。
sudo apt-get 更新
安装curl、git
sudo apt-get 安装curl git-core
这段代码的主要目的是指明pyenv的位置,以便以后可以直接在命令行运行pyenv命令。它保存在~/.bashrc文件中,每次用户登录时自动生效。
所以如果您是第一次运行该命令并且没有注销,则此部分不会生效。我们还需要运行以下命令才能使其生效。
source ~/.bashrc1 然后直接在命令行输入pyenv 。
安装pyenv参考文章:点击这里
下载pyenv
pyenv 已安装。接下来,安装我们需要的python版本。首先查看当前可以安装哪些版本的python。
pyenv install --list1 将打印一个长列表。如果你在线刷的话,可以看到如下图所示。
我们来安装图中圈出的版本。
pyenv 安装3.6.6 -v
(注:这里安装时最好加上-v,否则控制台上不会打印安装过程信息,看起来安装进度卡住了,第一次安装可能会造成混乱)
安装失败==因为有些依赖还没有安装。
sudo apt-get install make build-essential libssl-dev zlib1g-devsudo apt-get install libbz2-dev libreadline-dev libsqlite3-dev wgetsudo apt-get install llvm libncurses5-dev libncursesw5-dev123 依赖安装完毕后,再次pyenv install 3.6 。 6伏
顺利完成~
注意:这一步有一个陷阱。许多人喜欢安装最新版本(python 3.7.0+)。当所有依赖都安装完毕后,仍然会出现以下提示。
问题是Open SSL 已经安装(这是libssl-dev)。我花了很长时间来解决这个问题。最后发现本地OpenSSL在不配置的情况下不支持python3.7.0+。
pyenv 将openssl 构建/安装到新安装前缀的子目录中,但Python 未配置为使用它。如果没有./configure --with-openssl=${somewhere} ,它将支持系统的OpenSSL。对于Darwin,这总是失败,因为不再支持OpenSSL 的版本(Python=3.7.0)。问题链接:Python 3.7.0 : Python ssl 扩展未编译。缺少OpenSSL 库?
我在做调查的时候完全没有想到这一点。结果很惨,浪费了很多时间==~
Python安装
安装完成,查看一下
pyenv versions1 发现系统中已经安装了python3.6.6~
切换系统默认python环境
pyenv global 3.6.61 目前系统默认的python版本已经变成3.6.6。可以输入python命令来查看。
卸载某个python版本
pyenv uninstall x.x.x1 另外,pyenv还有其他各种命令行操作,大家可以google一下了解一下~
重新打开远程SSH窗口时,可能会遇到找不到pyenv命令的问题。请重新获取.bashrc 文件。
或者
查看解决方案:点击这里
pyenv基本操作
配置虚拟环境
在开始配置之前,不妨阅读一下pyenv-virtualenv ReadMe
准备
通过pyenv安装完成后,virtualenv也安装完成。我们可以通过pyenv命令完成虚拟环境的配置。
在pyenv-virtualenv中,由于需要从根本上解决一些已知问题(关于$PATH和shell提示),以后的版本中将删除activate/deactivate提示(仍然可以使用,但会弹出警告,我感觉不高兴~)
问题链接:关于提示更改的问题
跑步
$ echo 'eval '$(pyenv virtualenv-init -)'' ~/.bash_profile
重新启动外壳
$ exec '$SHELL'1 运行
pyenv virtualenv 3.6.6 电子商店
其中3.6.6是需要指定的python版本,eshop是虚拟环境的名称(随便取~)
至此,虚拟环境已经创建并自动激活,可以通过pyenv版本查看,如下图。
通过pyenv shell xxx(xxx为python版本号或者虚拟环境名称)切换环境,效果如下
(可选 + 推荐)自动激活虚拟环境
运行
pyenv virtualenv 3.6.6 电子商店
激活/停用虚拟环境
pyenv 激活eshop
pyenv 停用
原有的激活方式
卸载虚拟环境
pyenv卸载
至此,虚拟环境搭建完成~
最后
sudo apt-get install nginx1 运行
sudo /etc/init.d/nginx start #启动nginx1 如果出现sudo:无法解析主机问题,请参考这里
如果出现端口被占用的情况,请将配置文件更改为其他端口(如8000)
如果端口未被占用但无法访问,请返回配置安全组检查端口策略是否配置完整。
打开浏览器,访问xx.xx.xxx.xxx:80,其中xxxx是你的公网IP,80是Nginx默认监听端口号。
出现
这意味着Nginx已经成功安装并运行。
Nginx基本配置
(可选)服务端配置数据库
参考文章:Ubuntu安装配置postgresql
安装postgresql
sudo apt-get 安装postgresql
安装完成后,服务器系统会自动创建一个名为postgres(数据库超级用户)的帐户,密码为空。
切换到postgres
sudo su postgres1 登录postgresql
psql postgres1 在postgresql界面继续输入以下命令(注意最后的分号)
更改用户postgres,密码为“postgres”; 1 修改成功后,输入'\q'退出postgresql
退出postgres账户可以直接输入exit并回车或者ctrl + d
如果上述过程正确的话,如下图所示。
基本配置
编辑pgsql配置文件并运行
vim /etc/postgresql/9.1/main/postgresql.conf
或者使用WinSCP界面编辑(本文所有配置文件编辑均使用WinSCP+sublime,个人喜好)
修改配置文件如下:
监控任何地址访问并修改连接权限
#listen_addresses=‘localhost’ 改为listen_addresses=‘*’ 123 启用密码验证
#password_encryption=on 更改为password_encryption=on123 编辑/etc/postgresql/9.1/main/pg_hba.conf并将其添加到文件末尾
# 允许你的客户端访问postgresql serverhost all all 0.0.0.0 0.0.0.0 md512保存以上更改
最后重启数据库
sudo 服务postgresql 重新启动
至此,数据库配置完成
您可以通过登录来测试。您可以直接登录,也可以使用PgAdmin。这里我就不详细说了。
远程登陆
Django项目代码上传
经过这么多配置,Django项目还没有上传到服务器。确保本地有可运行的Django项目(废话:P)
上传方式有很多种
通过WinSCP直接上传(从左拖到右,完成~) 通过pycharm部署代码(推荐) 其他新用户可能会遇到上传权限问题。如需解决方案,请单击/var/www/html 上的权限以通过SFTP 上传网站文件
查看用户xxx所属组及组内成员
组xxx
更改文件上传目录的用户和用户组
sudo chown breavo:breavo /文件/上传/路径
给用户组添加写权限
sudo chmod -R 775 /文件/上传/路径
上传
设置django settings.py
ALLOWED_HOSTS=['*']1 安装项目依赖(依赖写在requirements.txt中,请添加每个依赖的版本号)
cd 到存储requirement.txt的目录并运行
pip install -r 要求.txt
等待依赖安装完成,cd到项目目录并运行
python管理.py运行服务器0.0.0.0:8000
打开浏览器输入服务器地址即可查看
xx.xx.xxx.xxx:8000(xxx为服务器的公网IP地址)
项目运行正常~(如果settings.py文件中的DEBUG设置为False,会观察到静态资源无法加载)
项目试运行
Nginx代理
在项目目录下添加config文件夹,后续所有配置文件都会放在该文件夹中(配置文件存放路径不一致会导致进入提示时操作不成功)
在config文件下新建mysite_nginx.conf文件,内容如下(路径替换为自己的项目路径或对应文件):
# mysite_nginx.conf# 上游组件nginx 需要连接到上游django { # unix:///home/breavo/PyWorkSpace/mysite_code_shuffle/config/eshop.sock # server unix:///path/to/your/mysite/mysite.sock ; # 对于文件套接字服务器127.0.0.1:8001; # 用于网络端口套接字(我们将首先使用它)}# 服务器配置server { # 您的站点将在listen 8000 上提供服务的端口; # 它将为server_name xx.xx.xxx.xxx 服务的域名; # 替换您机器的IP 地址或FQDN 字符集utf-8; # 最大上传大小client_max_body_size 75M; # 根据口味进行调整# Django 媒体位置/media { # /home/breavo/PyWorkSpace/mysite_code_shuffle/meida;别名/path/to/your/mysite/media; # 你的Django 项目的媒体文件- 根据需要修改} location /static { # /home/breavo/PyWorkSpace/mysite_code_shuffle/static alias /path/to/your/mysite/static; # 你的Django 项目的静态文件- 根据需要修改} # 最后,将所有非媒体请求发送到Django 服务器。位置/{ uwsgi_pass django;包括/home/breavo/PyWorkSpace/mysite_code_shuffle/config/uwsgi_params; # 你安装的uwsgi_params 文件}}12345678910111213141516171819202122232425262728293031323334353637在/etc/nginx/sites-enabled 中创建一个链接,以便Nginx 可以发现并启用我们的配置,运行
sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/1
在项目中配置Nginx
在运行Nginx之前,需要将django项目中的所有静态文件放入static文件夹中。添加到mysite/settings.py
STATIC_ROOT=os.path.join(BASE_DIR, 'static/')1 然后运行
python manage.pycollectstatic1 启动(重新启动)Nginx
sudo /etc/init.d/nginx start1
部署静态文件
将图像放入服务器项目的media 文件夹中(此处以test.png 为例)
使用权
xx.xx.xxx.xxx:8000/media/test.png1
图片显示正确~
至此,静态文件部署完成。
简单测试
接下来我们需要在项目中使用Uwsgi处理动态请求
Uwsgi安装及配置
在虚拟环境中运行
pip 安装uwsgi
在之前创建的config文件夹下新建hello.py用于测试,写入以下内容
# test.pydef application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b'Hello World'] # python3 #return ['Hello World '] # python212345 接下来运行
uwsgi --http :8001 --wsgi-文件test.py
打开浏览器查看
出现上图,说明Uwsgi已经初步运行成功。
基本配置
如果上述步骤没有问题,我们就可以使用Uwsgi启动项目并在项目根目录下运行
uwsgi --http :8001 --模块mysite.wsgi
其中mysite.wsgi(将mysite替换为自己的项目名)会自动搜索项目中的wsgi.py文件。
如果运行正常~恭喜
如果浏览器中出现内部服务器错误
检查命令提示符输入是否正确。检查项目根目录下是否有其他条件正在运行。检查命令行输出或日志。至此Uwsgi的基本配置就完成了~~
运行项目
Nginx + Uwsgi + django
现在我们使用socket通信通过Nginx访问hello.py,(确保Nginx已经启动)在config文件夹下运行
uwsgi --socket :8001 --wsgi-文件hello.py
好的,现在就访问浏览器
xx.xx.xxx.xxx:8000
参观成功~
其中8000是Nginx监听的端口(在mysite_nginx.conf文件中配置),--socket :8001是socket通信使用的端口(两个端口都可以替换~)
Nginx访问hello.py
编辑mysite_nginx.conf文件,将原来的内容更改为以下内容
服务器unix:///path/to/your/mysite/mysite.sock; # 对于文件套接字# server 127.0.0.1:8001; # 对于一个Web端口套接字(我们将首先使用它)12保存后,转到config文件夹运行
uwsgi --socket mysite.sock --wsgi-file hello.py
还是打开浏览器,访问xx.xx.xxx.xxx:8000。屏幕上出现Hello world,说明一切正常。
如果出现502 Bad Getway
检查Nginx 错误日志(/var/log/nginx/error.log)
如果出现
connect() to unix:///path/to/your/mysite/mysite.sock failed (13: Permissiondenied)12 意味着这是一个权限问题。跑步
uwsgi --socket mysite.sock --wsgi-file hello.py --chmod-socket=666
或者
uwsgi --socket mysite.sock --wsgi-file hello.py --chmod-socket=664 (推荐,但我使用它没有成功)
如果日志打印其他问题,请仔细检查配置~
使用Unix sockets替换端口
uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=6641 注意,这里有一个小坑。我在mysite_nginx.conf中配置的mysite.sock是在config文件夹下的,而这个命令需要在项目根目录下运行,这里可以:
修改mysite_nginx.conf下的sock文件路径为根目录并使用配置文件启动(推荐)
使用Nginx + Uwsgi运行项目
在config文件夹下新建mysite_uwsgi.ini,输入以下内容
# mysite_uwsgi.ini file[uwsgi]# Django相关设置# 基本目录(完整路径)chdir=/path/to/your/project# Django的wsgi filemodule=project.wsgi# virtualenv(完整路径)home=/path /to/virtualenv# 进程相关设置# mastermaster=true# 最大工作进程数processes=10# 套接字(使用完整路径为safesocket=/path/to/your/project/mysite.sock# . with适当的权限- 可能需要chmod-socket=666#clearenvironment on exitvacuum=truestats=%(chdir)/config/uwsgi.status pidfile=%(chdir)/config/uwsgi.pid1234567891011121314151617181920212223242526将相应的配置替换为自己的路径~
保存后运行(确保在mysite_uwsgi.ini目录下)
uwsgi --ini mysite_uwsgi.ini
打开浏览器访问xx.xx.xxx.xxx:8000
现在项目应该可以完美运行了~~
完成啦~:)
用户评论
尝试过在本地运行它们的过程了吗?真是令人头疼啊!但最终看到系统稳定和兼容时,那种成就感简直无与伦述。
有20位网友表示赞同!
学习如何使用这些工具进行部署真的很值得,特别是对于喜欢挑战的人来说。
有10位网友表示赞同!
Nginx的缓存功能配合Uwsgi后,网站访问速度提升了不少,太棒了!
有9位网友表示赞同!
Django项目的初期配置总是让人纠结,但一旦成功配合Nginx和Uwsgi运行起来,感觉超流畅的!
有15位网友表示赞同!
搭建过程中遇到的小摩擦让我意识到自己的技术还有待提高。不过结果很好,这过程也让我成长了不少。
有18位网友表示赞同!
我一直用传统的部署方式,这次尝试Nginx+Uwsgi+Django之后发现效率大增了,真是太出乎意料了!
有8位网友表示赞同!
在服务器环境兼容性测试时花费了一些时间,最终达到完美运行效果是很有成就感的。
有13位网友表示赞同!
Nginx作为一个负载平衡器表现出色,特别是在高并发场景下,Uwsgi和Django项目的响应依然快速稳定。
有5位网友表示赞同!
虽然部署初期遇到一些调试问题,但随着项目经验的积累感觉越来越得心应手了。
有14位网友表示赞同!
Django+Uwsgi+Nginx的组合对于新手来说确实有一定的学习曲线,但结果非常值得!
有10位网友表示赞同!
Nginx对Django的应用提供了良好的环境支持,尤其是在处理静态文件方面效率极高。
有5位网友表示赞同!
用Uwsgi做预热服务器,然后通过Nginx反向代理部署Django应用,性能提升效果明显。
有7位网友表示赞同!
Django和Uwsgi的集成是开发过程中的一大亮点,让代码执行速度提高了好几个档次!
有14位网友表示赞同!
面对Nginx配置的挑战确实耗费了一些时间,但在了解整个流程后感觉有了更强的技术底气。
有10位网友表示赞同!
在使用Nginx + Uwsgi部署Django项目时,优化了日志管理,进一步提升了用户体验。
有8位网友表示赞同!
这三者结合使用让开发过程中的一些痛点得到了解决,特别是服务器的响应速度和稳定性的提升。
有8位网友表示赞同!
从代码到实际运行,每一步都充满了挑战和惊喜,在Nginx + Uwsgi + Django的组合下体验了一次技术成长之旅。
有19位网友表示赞同!
尝试了新的部署框架后发现,系统的整体性能明显改善,特别是在处理并发请求时。
有12位网友表示赞同!
在Nginx的反向代理下,Django应用流畅运行,尤其是对用户体验方面有显著提升。
有10位网友表示赞同!
对于想要深入理解Web服务环境搭建的人来说,Nginx与Uwsgi、Django结合是一种很好的实践方式。
有11位网友表示赞同!