首页 > 解决方案 > 如何通过Passenger/Nginx在Digital Ocean上部署Django/React/Webpack应用

问题描述

我正在尝试在 Digital Ocean 液滴上部署一个使用 Django/Redux/React/Webpack 构建的 Web 应用程序。我在部署服务器上使用 Phusion Passenger 和 Nginx。

我使用 create-react-app 构建了一个 Django 应用程序,它有一个使用 React/Redux 的前端和一个使用 django-rest-framework 的后端 api。我使用npm run build.

Django 应用程序配置为在 frontend/build 文件夹中查找其文件,并且一切都按预期工作,包括身份验证。它基于本教程:http: //v1k45.com/blog/modern-django-part-1-setting-up-django-and-react/

在 settings.py 中:

ALLOWED_HOSTS = ['*']

TEMPLATES = [
... 
       'DIRS': [
            os.path.join(BASE_DIR, 'frontend/build'),
        ],
...
]

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'frontend/build/static'),
]

在我的开发机器上,我激活了一个 Python 3.6 虚拟环境并运行./manage.py runserver,应用程序显示在 localhost:3000。

在部署服务器上,我将文件克隆到 var/www/ 的文件夹中并构建了前端。

我已经根据文档使用文件 Passenger_wsgi.py 设置了乘客:

import myapp.wsgi
application = myapp.wsgi.application

wsgi.py 文件位于下面的 djangoapp 文件夹中:

import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
application = get_wsgi_application()

乘客文档仅涵盖单部分应用程序:

https://www.phusionpassenger.com/library/walkthroughs/start/python.html https://www.phusionpassenger.com/library/walkthroughs/deploy/python/digital_ocean/nginx/oss/xenial/deploy_app.html https: //www.phusionpassenger.com/library/deploy/wsgi_spec.html

我尝试将教程第 1 部分的代码直接克隆到我的服务器上并按照说明运行它。我通过添加"proxy": "http://localhost:8000"到 frontend/package.json 让这个在服务器上工作。如果我运行 Django 服务器,./manage.py runserver --settings=ponynote.production_settings xxx.x.x.x:8000 那么应​​用程序将在 myserver:8000 上正确提供。但是,Passenger 仍然没有提供正确的文件。

我已经改变了 wsgi.py 来这样说:

import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.production_settings")
application = get_wsgi_application()

现在,Passenger 在 URL 根处提供的页面似乎具有指向 js 文件的正确链接,例如“text/javascript” src="/static/bundles/js/main.a416835a.js,但这些链接不起作用:预期的 js 不存在。Passenger 无法从 static/bundles/js 提供 js 文件,即使 Django 服务器可以找到它们。

非常感谢任何帮助或想法。

标签: pythondjangoreactjswebpackpassenger

解决方案


Create-react-app 对本地和生产环境有相当固执的设置。

在本地,运行npm start将运行webpack-dev-server,您通常会在端口 3000 上访问它。它运行本地 nodejs Web 服务器来提供文件。您可以通过代理设置将请求路由到本地 Django 服务器。

值得注意的是,此时您的 React 应用程序和 Django 之间几乎没有联系。如果您使用代理设置,连接这两个应用程序的唯一方法是将您的 React 应用程序未处理的任何请求通过端口路由到您的 Django 应用程序。

默认情况下,在 create-react-app 中(正如您提到的教程中所述)在生产中,您将运行npm run build它会将您的 create-react-app 文件处理为静态 JS 和 CSS 文件,然后在 Django 中访问这些文件静态文件任何其他 Django 应用程序

Django 为了访问静态文件而缺少的一件事是一种知道运行时生成什么文件的方法npm run build。运行构建通常会导致文件输出如下:

- css
   |- main.e0c3cfcb.css
   |- main.e0c3cfcb.css.map
- js
   |- 0.eb5a2873.chunk.js
   |- 0.eb5a2873.chunk.js.map
   |- 1.951bae33.chunk.js
   |- 1.951bae33.chunk.js.map

随机散列添加到文件名以确保缓存清除。这就是webpack-bundle-trackerdjango-webpack-loader发挥作用的地方。生成构建文件时,还会创建一个名为 的随附文件manifest.json,列出为构建创建的文件。这是在 Webpack 中生成并由 django-webpack-loader 提取的,这样 Django 就可以知道要导入哪些文件。

可以在生产中运行 nodejs 服务器,或者使用服务器端渲染,但是如果您按照您提到的教程并使用 create-react-app 默认设置,那么运行npm run build和部署静态文件是最简单的,最安全的选择。

您提到的任何乘客部署链接中的任何内容都没有涵盖部署 Python/Django 应用程序之外的任何内容 - 您需要管理两个应用程序和部署,以使 Django 和 React 在生产中作为服务器运行。

请注意,您提到的教程涵盖了如何在生产环境中将构建文件导入 Django,但您需要确保已将webpack-bundle-trackerdjango-webpack-loader和 Django 静态文件配置全部配置为可以协同工作。


推荐阅读