经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
浅谈Django+Gunicorn+Nginx部署之路
来源:jb51  时间:2019/9/12 8:54:56  对本文有异议

前言

最近,我已经成功将我的个人网站从 Flask 迁移到 Django 了,最早接触 Django 的时候大概是在 4 年前,我记得那个时候 Django 中的路由配置使用 正则 来进行的,但是我有特别烦这个东西,所以就果断弃坑了。然后今年年初的时候,我用 Flask 写了一个我的个人网站,刚开始的时候功能还是比较简单,看着路由配置和部署规则都很方便,就果断采用了。但是后来我想添加的功能越来越多的时候,我发现我已经越来越难掌控它了,正好最近我稍微看了一下 Django 这几年的变化,最新的 2.2 版本还是很不错的,路由规则和 Flask 已经一致了,所以我就重新入坑了。

目前我的个人网站基本功能已经迁移完毕。但是在部署的时候,我遇到了一些问题,在网上看了一些解决方法,要么太乱,要么太旧,个人觉得都已经不太适用了。所以在这里记录一下我的部署过程。

部署

网上有很多都是用 UWSGI 的方式来部署,但是我个人比较喜欢 Gunicorn,所以以下内容我只是记录了 Django + Gunicorn + Nginx 在 Ubuntu 上的部署方式相关内容。

步骤一

上传网站源码至目标服务器

由于我的源码是用 Github 来托管的,所以我直接执行下述命令来克隆我的网站源码到服务器即可。

  1. git clone https://github.com/your-name/repo-name.git
  2.  
  3. # 进入项目目录
  4. cd repo-name
  5.  
  6. # 创建并激活虚拟环境
  7. python3 -m virtualenv venv
  8. source venv/bin/activate
  9.  
  10. # 安装项目依赖
  11. pip install -r requirements.txt

目前我的网站采用的相关依赖包如下:

  1. autopep8
  2. Django
  3. django-bootstrap4
  4. django-ckeditor
  5. gunicorn
  6. Markdown
  7. Pillow
  8. python-slugify
  9. requests

这里有个坑需要注意,如果你使用了 awesome-slugify,请尝试使用 python-slugify,因为有的服务器可能无法正常安装 awesome-slugify,具体 BUG 可参考:Clashes with python-slugify package

步骤二

修改项目相关配置,并进行静态资源收集

由于我需要将我的网站部署到生产环境,所以我需要关闭 Django 的调试模式,并修改静态资源相关配置,示例配置如下所示:

settings.py

  1. SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
  2.  
  3. DEBUG = os.environ.get('DJANGO_DEBUG', False)
  4.  
  5. TEMPLATE_DEBUG = os.environ.get('DJANGO_TEMPLATE_DEBUG', False)
  6.  
  7. ALLOWED_HOSTS = ["*"]
  8.  
  9. TEMPLATES = [
  10. {
  11. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  12. 'DIRS': [os.path.join(BASE_DIR, 'templates')],
  13. 'APP_DIRS': True,
  14. 'OPTIONS': {
  15. 'context_processors': [
  16. 'django.template.context_processors.debug',
  17. 'django.template.context_processors.request',
  18. 'django.contrib.auth.context_processors.auth',
  19. 'django.contrib.messages.context_processors.messages',
  20. ],
  21. },
  22. },
  23. ]
  24.  
  25. STATIC_URL = '/static/'
  26. STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
  27. STATICFILES_DIRS = [
  28. os.path.join(BASE_DIR, 'static'),
  29. ]
  30.  
  31. MEDIA_URL = '/media/'
  32. MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
  33.  

然后执行如下命令进行静态资源收集:

  1. python manage.py collectstatic

之后,我还需要创建一个 Gunicorn 进程的相关配置,示例配置如下所示:

gunicorn.conf.py

  1. # 安装
  2. # sudo pip3 install gunicorn
  3.  
  4. import sys
  5. import os
  6. import logging
  7. import logging.handlers
  8. from logging.handlers import WatchedFileHandler
  9. import multiprocessing
  10.  
  11. BASE_DIR = '/home/hippie/hippiezhou.fun/src'
  12. sys.path.append(BASE_DIR)
  13.  
  14. LOG_DIR = os.path.join(BASE_DIR, 'log')
  15. if not os.path.exists(LOG_DIR):
  16. os.makedirs(LOG_DIR)
  17.  
  18. # 绑定的ip与端口
  19. bind = "0.0.0.0:8000"
  20.  
  21. # 以守护进程的形式后台运行
  22. daemon = True
  23.  
  24. # 最大挂起的连接数,64-2048
  25. backlog = 512
  26.  
  27. # 超时
  28. timeout = 30
  29.  
  30. # 调试状态
  31. debug = False
  32.  
  33. # gunicorn要切换到的目的工作目录
  34. chdir = BASE_DIR
  35.  
  36. # 工作进程类型(默认的是 sync 模式,还包括 eventlet, gevent, or tornado, gthread, gaiohttp)
  37. worker_class = 'sync'
  38.  
  39. # 工作进程数
  40. workers = multiprocessing.cpu_count()
  41.  
  42. # 指定每个工作进程开启的线程数
  43. threads = multiprocessing.cpu_count() * 2
  44.  
  45. # 日志级别,这个日志级别指的是错误日志的级别(debug、info、warning、error、critical),而访问日志的级别无法设置
  46. loglevel = 'info'
  47.  
  48. # 日志格式
  49. access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
  50. # 其每个选项的含义如下:
  51. '''
  52. h remote address
  53. l '-'
  54. u currently '-', may be user name in future releases
  55. t date of the request
  56. r status line (e.g. ``GET / HTTP/1.1``)
  57. s status
  58. b response length or '-'
  59. f referer
  60. a user agent
  61. T request time in seconds
  62. D request time in microseconds
  63. L request time in decimal seconds
  64. p process ID
  65. '''
  66.  
  67. # 访问日志文件
  68. accesslog = os.path.join(LOG_DIR, 'gunicorn_access.log')
  69. # 错误日志文件
  70. errorlog = os.path.join(LOG_DIR, 'gunicorn_error.log')
  71. # pid 文件
  72. pidfile = os.path.join(LOG_DIR, 'gunicorn_error.pid')
  73.  
  74. # 访问日志文件,"-" 表示标准输出
  75. accesslog = "-"
  76. # 错误日志文件,"-" 表示标准输出
  77. errorlog = "-"
  78.  
  79. # 进程名
  80. proc_name = 'hippiezhou_fun.pid'
  81.  
  82. # 更多配置请执行:gunicorn -h 进行查看

之后可用通过如下方式启动我们的网站:

  1. # 启动方式(首先需要切换到项目根目录,即和 manage.py 在同级目录下):
  2.  
  3. gunicorn -c gunicorn.conf.py website.wsgi:application
  4.  
  5. # 或
  6. gunicorn website.wsgi:application -b 0.0.0.0:8000 -w 4 -k gthread
  7.  
  8. # 或
  9. gunicorn website.wsgi:application -b 0.0.0.0:8000 -w 4 -k gthread --thread 40 --max-requests 4096 --max-requests-jitter 512
  10.  
  11. # 查看进程
  12. ps aux | grep gunicorn
  13.  

步骤三

配置 Nginx

通过前两步,我们可以成功将我们的网站跑起来,但是目前还只能在内部访问,所以我们需要通过 Nginx 来做反向代理,供外网访问。

执行下述命令进行安装和配置

  1. sudo apt-get install nginx
  2.  
  3. sudo service nginx start
  4.  
  5. # 备份默认配置
  6. sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
  7.  
  8. # 启动 Vim 修改我们的网站配置
  9. sudo vim /etc/nginx/sites-available/default
  10.  

示例配置如下所示:

  1. server{
  2. ...
  3. server_name hippiezhou.fun *.hippiezhou.fun;
  4. access_log /var/log/nginx/access.log;
  5. error_log /var/log/nginx/error.log;
  6. ...
  7.  
  8. location / {
  9. # First attempt to serve request as file, then
  10. # as directory, then fall back to displaying a 404.
  11. # try_files $uri $uri/ =404;
  12. proxy_pass http://127.0.0.1:8000; #此处要和你 gunicore 的 ip 和端口保持一致
  13. proxy_redirect off;
  14.  
  15. proxy_set_header Host $host;
  16. proxy_set_header X-Real-IP $remote_addr;
  17. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  18. proxy_set_header X-Forwarded-Proto $scheme;
  19. }
  20.  
  21. location /static {
  22. alias /root/hippiezhou.fun/src/staticfiles; # 此次需要配置为你的网站对应的静态资源的绝对路径
  23. }
  24.  
  25. location /media {
  26. alias /root/hipiezhou.fun/src/media; # 如果你的网站有上传功能,需要配置该结点并指向目标路径
  27. }
  28.  
  29. ...
  30. }

配置完成后执行下述操作即可将我们的网站运行起来

  1. # 若网站未启动执行该命令
  2. gunicorn -c gunicorn.conf.py website.wsgi:application
  3.  
  4. sudo nginx -t
  5. sudo service nginx restart
  6.  

如果不出意外,网站应该是可以正常访问,如果静态资源依然不能访问,打开网站的 开发者工具看一下是什么错误。

  • 如果是 404 的问题,请确保你的 settings 相关配置和我上面列出来的是一致的;
  • 如果是 403 的问题,应该是 Nginx 无权访问你指定的静态资源,你需要修改 Nginx 的用户类型,亲执行下述命令
  1. sudo vim /etc/nginx/nginx.conf

将 user 后面的值修改为 root,然后重启 Nginx 即可。

最后,关于如何配置 HTTPS,这里就不过多介绍了,直接列出相关示例脚本:

  1. sudo apt-get update
  2. sudo apt-get install software-properties-common
  3. sudo add-apt-repository universe
  4. sudo add-apt-repository ppa:certbot/certbot
  5. sudo apt-get update
  6. sudo apt-get install certbot python-certbot-nginx
  7.  
  8. sudo certbot --nginx
  9.  
  10. # sudo certbot renew --dry-run
  11.  
  12. sudo ufw allow https
  13.  
  14. sudo systemctl restart nginx
  15.  

总结

在部署的过程中,其实遇到最多的问题就是关于静态资源无法问题的问题,但是看到网上很多文章,都不一样,并且有的写的还是错误的。所以这里就总结一些。还好,一切顺利。算是填了 4 年前的一个坑吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号