Django 每一個App配置獨立域名

環境:Python 3.8.1 + Django 2.2.12python

爲整合流程規範,部署了綜合型的項目,包含了 task (需求系統),doc (文檔系統),sso (單點登陸系統),nginx

大體的目錄結構:shell

CellMiddle  -- 項目根目錄
├─task --- 需求系統
│  ├─migrations
│  ├─static
│  └─templates
├─logs --- 日誌目錄
├─doc --- 文檔系統
│  ├─data
│  ├─migrations
│  ├─static
│  └─templates
├─sso --- 單點登陸,權限控制系統
│  ├─migrations
│  ├─static
│  └─templates
├─upload ---文件資源上傳目錄
├─static --- 靜態資源
├─templates --- 公共模板
└─CellMiddle --- 項目主目錄
│    ├─config --- 公共配置
│    ├─helper --- 公共輔助類,ex:時間,日期,字符串,響應等
│    └─loader --- 第三方庫的實例化加載,ex:Redis,Memcached等
│    │  settings.py
│    │  urls.py
│    │  wsgi.py
│    │  __init__.py
├─manage.py
└─envConf  -- 部署配置文件:requirement.txt, host.conf, supervisor, gunicorn 等

使用 nginx + gunicorn + supervisor 部署,使用域名 cell.hao456.com 解析指向服務器, nginx 監聽 gunicorn 綁定的端口,能夠正常訪問:django

http://cell.hao456.com/task
http://cell.hao456.com/doc
http://cell.hao456.com/sso

雖然同一個域名路由控制來訪問,也是能夠的。但仍是想像PHP同樣只要獨立入口文件,每一個app獨立使用不一樣子域名,如:服務器

http://task.hao456.com 指向task
http://doc.hao456.com  指向doc
http://sso.hao456.com  指向sso

嘗試了幾種辦法:app

  1. nginx 層轉發;
    • 修改proxy指向,location 要加app,static 等。
  2. 每一個app獨立一個 wsgi.py 文件,使用gunicorn單獨起服務;
    • 增長 task_wsgi.py, doc_wsgi.py, sso_wsgi.py,使用 supervisor起三個gunicorn服務。
  3. 使用django-hosts;
    • 添加MIDDLEWARE中間件,實現host與urls的namespace關聯。nginx的conf配置不用改動,只須要將 全部子域名的監聽,一塊兒代理指向gunicorn端口,
$ cat hosts.conf
server {
    listen 80;
    server_name task.hao456.com doc.hao456.com sso.hao456.com;
    location / {
        proxy_pass http://127.0.0.1:10888;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 120s;
    }
    ... ...
}

django-hosts實現:

  1. pip 安裝 django-hosts, 這裏用到的是 4.0版本:
$ pip install django-hosts==4.0  # root權限
  1. 修改settings.py:
    • 將django-hosts添加到app:
INSTALLED_APPS = [
        ...
        'django_hosts',
        'sso',
        'doc',
        'task',
    ]
- 添加Django的hosts配置:
ROOT_HOSTCONF = 'CellMiddle.hosts'  # host配置
    DEFAULT_HOST = 'sso'  # 默認的域名
- 將django_hosts添加到中間件MIDDLEWARE:
MIDDLEWARE = [
    'django_hosts.middleware.HostsRequestMiddleware',  # 首要加
    ...
    'django_hosts.middleware.HostsRequestMiddleware',  # 尾要加
]
  1. 在項目主目錄下settings.py同級,添加 hosts.py(注意和 settings 裏面配置的ROOT_HOSTCONF一致):
...
└─CellMiddle
    │  hosts.py  --- 新增文件
    │  settings.py
    │  urls.py
    │  wsgi.py
    │  __init__.py

內容爲:ui

# coding=utf8
    """
    django-hosts
    """
    from django.conf import settings
    from django_hosts import patterns, host

    host_patterns = patterns(
        '',
        host('sso', settings.ROOT_URLCONF, name='sso'),
        host('doc', 'doc.urls', name='doc'),
        host('task', 'task.urls', name='task'),
    )
  1. 路由配置urls.py,添加路由對應的appname(app名稱), namespace(域名):
urlpatterns = [
        path('admin/', admin.site.urls),
        path('', include(('sso.urls', 'sso'), namespace='sso')),  # 默認sso
        path('doc', include(('doc.urls', 'doc'), namespace='doc')),  # 文檔
        path('task', include(('task.urls', 'task'), namespace='task')),  # 需求
    ]
  1. reload 重載服務:
  • DNS 確認子域名的解析;
  • 檢查nginx的配置有效性,重載nginx;
  • 動態更新Web服務 或 在 supervisorctl重啓Web服務;
$ kill -HUP PID  # root權限
$ supervisorctl restart program_name服務名  # root權限
  1. 檢查子域名的訪問,app對應的路由,靜態資源訪問等是否正常;
相關文章
相關標籤/搜索