2012-07-02 29 views
14

Tôi muốn chạy một dự án thử nghiệm đơn giản trong một bí danh thư mục con trên máy chủ phát triển của chúng tôi. Các thiết lập cơ bản là một nginx với một vị trí mà vượt qua tất cả mọi thứ trong một thư mục con để ứng dụng wsgi.Chạy ứng dụng django qua nginx + uwsgi trong đường phụ

Django rõ ràng không hiểu rằng nó chạy trong một bí danh thư mục con, điều này hoàn toàn hủy hoại việc tạo và phân tích cú pháp URL.
Tôi không thể tìm thấy bất kỳ cài đặt tiền tố giống như trong tài liệu và google fu của tôi cũng không giúp đỡ nhiều ... vì vậy tôi yêu cầu ở đây để thay thế.

Điều duy nhất tôi tìm thấy là cài đặt FORCE_SCRIPT_NAME ít nhất là sửa lỗi tạo URL. (xem: http://docs.webfaction.com/software/django/config.html#mounting-a-django-application-on-a-subpath)
Đáng buồn là điều này không khắc phục phân tích cú pháp urlconf, mặc dù trang web được đề xuất gợi ý điều đó.

Có thể chạy ứng dụng django trong bí danh thư mục con không và nếu có, làm cách nào?

nginx config:

server { 
     location /fancyprojectname/static { 
       alias /srv/fancyprojectname/static; 
     } 

     location /fancyprojectname/ { 
       uwsgi_pass unix://var/run/uwsgi/app/fancyprojectname/socket; 
       include uwsgi_params; 
     } 
} 

Sửa

Vì vậy, thiết lập "uwsgi_param SCRIPT_NAME/fancyprojectname;" ở vị trí nginx khiến FORCE_SCRIPT_NAME trở nên không cần thiết - thật đáng buồn là việc khớp URL vẫn không hoạt động.

from django.conf.urls import patterns, include, url 

# Uncomment the next two lines to enable the admin: 
from django.contrib import admin 
admin.autodiscover() 

urlpatterns = patterns('', 
    # Uncomment the admin/doc line below to enable admin documentation: 
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 

    # Uncomment the next line to enable the admin: 
    url(r'^admin/', include(admin.site.urls)), 
) 

Những gì tôi nghĩ rằng những gì đang xảy ra: Khi regex quản trị bắt đầu với "^ admin" và URL thực tế là "fancyprojectname/admin /", Django có thể không phù hợp với URL chính xác, mặc dù SCRIPT_NAME là bộ.

Giải pháp

Vì vậy, nó thực sự là một vấn đề với SCRIPT_NAME.

Các WSGI specification nói như sau:

SCRIPT_NAME Phần đầu của "con đường" URL yêu cầu của tương ứng với đối tượng ứng dụng, do đó việc áp dụng biết nó ảo "location". Đây có thể là một chuỗi rỗng, nếu ứng dụng tương ứng với "gốc" của máy chủ.

PATH_INFO Phần còn lại của "đường dẫn" của URL yêu cầu, chỉ định "vị trí" ảo của mục tiêu của yêu cầu trong ứng dụng. Đây có thể là một chuỗi trống, nếu URL yêu cầu nhắm mục tiêu gốc ứng dụng và không có dấu gạch chéo.

Nginx không đặt SCRIPT_NAME tự động, vì vậy, điều này cần phải được đặt trong mọi trường hợp. Sau đó PATH_INFO là sai, bởi vì trong thiết lập mặc định Nginx đặt nó thành $ document_uri, đó sẽ là URL đầy đủ.

"uwsgi_modifier1 30;" yêu cầu Nginx đặt UWSGI_MODIFIER_MANAGE_PATH_INFO, từ đó yêu cầu UWSGI loại bỏ SCRIPT_NAME của PATH_INFO.

Sự kết hợp của các cài đặt này dường như hoạt động, vì Django hiện có thể tạo VÀ khớp các URL chính xác.

+0

Hãy có một cái nhìn tại https://stackoverflow.com/a/40496307/1588163 Ở đó bạn sẽ tìm ra cách cập nhật để thực hiện điều này – clapas

+0

[Xem thêm : Làm thế nào để Mount Django App với uwsgi] (https://stackoverflow.com/questions/19475651/how-to-mount-django-app-with-uwsgi) –

Trả lời

7

Đây là sai:

Django rõ ràng không hiểu rằng nó chạy trong một bí danh thư mục con, mà hoàn toàn phá hủy thế hệ URL và phân tích cú pháp.

Django không hiểu điều đó và giải quyết rõ ràng. Máy chủ nên tự thiết lập SCRIPT_NAME: thực tế bạn thấy mình đang sử dụng FORCE_SCRIPT_NAME cho thấy rằng sự cố nằm trong cấu hình Nginx của bạn, thay vì ở Django.

Tôi nghi ngờ vấn đề là việc sử dụng location, thay vì chỉ thị phù hợp hơn. Thật không may, tôi không có chuyên gia về Nginx/uwsgi. Trong Apache/mod_wsgi, bạn sẽ làm điều này:

WSGIScriptAlias /mysite /usr/local/django/mysite/apache/django.wsgi 

nói với mod_wsgi trang web đó bắt đầu từ mysite, chứ không phải là root. Có gần như chắc chắn là một lệnh tương tự với nginx/uwsgi.

+3

Được rồi, tôi đã thử điều này với "uwsgi_param SCRIPT_NAME/fancyprojectname;" trong nginx và điều này dường như "hoạt động", vì giờ đây tôi có thể nhận xét ra FORCE_SCRIPT_NAME trong cài đặt và URL được tạo chính xác - điều này vẫn không khắc phục được kết hợp URL. Tôi sẽ nối thêm cấu hình url hiện tại trong câu hỏi. – Strayer

+5

Có vẻ như nó đang hoạt động ngay bây giờ - SCRIPT_NAME không hoạt động, thiết lập "uwsgi_modifier1 30;" hiện nó mặc dù. Tôi không biết cài đặt này là gì, nhưng khi tôi tìm ra tôi sẽ cập nhật lại câu hỏi và chấp nhận câu trả lời này là câu trả lời hợp lệ. Cảm ơn con trỏ! – Strayer

+0

Cảm ơn bạn @Strayer. Nó làm việc cho tôi :) –

5

Nếu vị trí Nginx khối này hoạt động khi lưu trữ các trang web Django tại http://www.example.com/ (miền cơ sở của bạn):

location/{ 
    uwsgi_pass unix:/tmp/fancyprojectname.socket; 
    include /etc/nginx/uwsgi_params; 
} 

Sau đó, điều này sẽ làm việc tại http://www.example.com/subpath/ (một subpath trên tên miền cơ sở của bạn):

location /subpath { 
    uwsgi_pass unix:/tmp/fancyprojectname.socket; 
    uwsgi_param SCRIPT_NAME /subpath; # explicitly set SCRIPT_NAME to match subpath 
    uwsgi_modifier1 30; # strips SCRIPT_NAME from PATH_INFO (the url passed to Django) 
    include /etc/nginx/uwsgi_params; 
} 

... và không cần đặt FORCE_SCRIPT_NAME trong cài đặt Django của bạn.

Tài liệu tham khảo:

+0

Cảm ơn bạn, bây giờ tôi có [Hatta wiki] (http://hatta-wiki.org/) đang chạy trên một đường phụ dưới nginx. –

+0

Đừng quên thêm "env = DJANGO_SETTINGS_MODULE = your_app.settings" vào tệp uwsgi.ini của bạn. –

Các vấn đề liên quan