【问题标题】:How to deploy Angular Universal app to Node.js production server?如何将 Angular Universal 应用程序部署到 Node.js 生产服务器?
【发布时间】:2019-10-29 03:10:00
【问题描述】:

我有一个带有 Universal 的 Angular 8 应用程序,我想将它部署到共享的 Web 主机生产服务器。我事先与网络主机核对过,他们告诉我可以在他们的共享网络主机上托管一个 Angular 通用网络应用程序。但是,无论我做什么,我都无法让网站正常工作。当我访问该网站时,我不断看到消息:“无法访问此网站”

到目前为止我做过的事情:

  1. 使用 npm run build:ssr 构建项目,它创建了一个 dist 文件夹,其中包含一个浏览器和服务器文件夹以及一个 server.js 文件
  2. 将 dist 文件夹移动到服务器的 public_html 文件夹内。 然后通过 SSH 访问服务器并执行以下操作:
  3. 安装 Node.js 和 npm
  4. npm 安装
  5. npm install pm2 -g
  6. pm2 启动 dist/server.js

pm2 启动没有问题。

这些是一些项目文件。如果有任何遗漏,请询问,我会将它们添加到问题中。

包含脚本的 package.json 的一部分:

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "compile:server": "webpack --config webpack.server.config.js --progress --colors",
    "serve:ssr": "node dist/server",
    "build:ssr": "npm run build:client-and-server-bundles && npm run compile:server",
    "build:client-and-server-bundles": "ng build --prod && ng run ProjectName:server:production --bundleDependencies all"
  },

构建中的 server.js(只有 express 部分,因为它有 25000 多行):

const app = express__WEBPACK_IMPORTED_MODULE_1__();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = Object(path__WEBPACK_IMPORTED_MODULE_2__["join"])(process.cwd(), 'dist/browser');
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap } = __webpack_require__(144);
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [
        provideModuleMap(LAZY_MODULE_MAP)
    ]
}));
app.set('view engine', 'html');
app.set('views', DIST_FOLDER);
// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express__WEBPACK_IMPORTED_MODULE_1__["static"](DIST_FOLDER, {
    maxAge: '1y'
}));
// All regular routes use the Universal engine
app.get('*', (req, res) => {
    res.render('index', { req });
});
// Start up the Node server
app.listen(PORT, () => {
    console.log(`Node Express server listening on http://localhost:${PORT}`);
});

根据 SO 或其他地方的几个答案,您“简单地”将 dist 文件夹复制粘贴到服务器,运行 pm2 并且您的网站应该可以正常工作。不过,我觉得要让它发挥作用还缺少很多东西。

有人知道如何将 Angular Universal 网站正确部署到生产服务器吗?

【问题讨论】:

  • 您的共享主机是否有您可以配置的网络服务器,例如Apache 还是 nginx?
  • 直接访问 http://ip-adres 可以看到 Apache 正在运行
  • 你能在 apache 中创建一个虚拟主机吗?从技术上讲,您需要将流量从 Apache 配置重定向到您的 nodejs 服务器
  • 不知道该怎么做。我会试着弄清楚。我需要在某个配置文件中这样做吗?
  • 这取决于您的托管公司。有时您必须使用.htaccess 文件来完成此操作

标签: node.js angular pm2 angular-universal


【解决方案1】:

我最终在我的 DirectAdmin 控制台中使用了一个名为“NodeJS Selector”的工具,因为 PM2 一直给我带来问题。这是一个安装应用程序的工具,执行 npm install 并启动应用程序。所以基本上你会用 SSH 做什么,但在一个花哨的 UI 中。设置如下所示:

我的文件夹结构如下所示:

domains
    - appname.com
        - public_html
            - browser (=> this set as the document root in Apache, because index is located here)
                - index.html
                - .htaccess
                - other files...
            - server
            - server.js
            - package.json

我让我的网络主机做两件事,因为我不是服务器上的 root 用户。他们将 documentroot 设置为 Apache 的 httpd.conf 文件中的浏览器文件夹。在同一个文件中,他们还将 proxy 设置添加到端口 4000,因为这是我的应用程序运行的地方。所以在httpd.conf文件中会是这样的:

 DocumentRoot "/domains/appname.com/public_html/browser"

 <Proxy *>
  Order allow,deny
  Allow from all
 </Proxy>
 ProxyPreserveHost On
 ProxyRequests Off
 ProxyPass / https://localhost:4000/
 ProxyPassReverse / https://localhost:4000/

接下来在 NodeJS 选择器中将根设置为启动文件所在的位置(在我的例子中是 server.js)。 package.json 也需要位于 de public_html 文件夹中,以便您可以在 Selector 中执行 npm install

要启动应用程序,请单击 'Run JS script' 并选择 serve:ssr 选项,它会运行节点服务器命令。

Angular 文档描述了如何在服务器上重写一些规则。 Apache 安装在我的 Web 服务器上,因此我添加了一个 .htaccess 文件,其中包含文档中的重写规则。但是,此应用程序由 Node 提供服务,并且 Node 可以提供实际路径。因此,就我而言,我不必添加带有重写规则的 .htaccess 文件。相反,当我添加 .htaccess 文件时,它会导致我的应用程序的通用端无法完全呈现。请参阅this question 了解更多信息。

【讨论】:

    【解决方案2】:

    server.ts文件更改

    const DIST_FOLDER = join(process.cwd(), 'dist/browser');
    

    const DIST_FOLDER = join(process.cwd(), 'browser');
    

    现在通过npm run build:ssr 构建应用程序并将dist 文件夹内的所有内容复制到您的公共文件夹(在主机上)。请记住,您应该运行 pm2 start server.js,而不是 pm2 start dist/server.js

    【讨论】:

    • 试过这个,不幸的是没有运气。这种变化究竟在做什么?如果我查看 pm2 的 -out.log 文件,它会显示:“Node Express 服务器正在侦听 localhost:4000”我是否还需要在某处配置主机和端口以重定向到我的域或 ip?
    • “无法访问此站点”错误意味着您在错误的目的地提供该网站。因此,其中一种可能性是删除 dist 文件夹(这为我个人解决了这个问题)。建议你问问web主机端口是否开放,以及如何将此端口代理到80(http)和443(https)。
    猜你喜欢
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    • 2018-05-31
    相关资源
    最近更新 更多