无法将下一个 js 部署到 azure

unable to deploy next js to azure

我正在尝试将我的 NEXTJS 应用程序部署到 Azure。 我创建了一个包含安装了 Node 的 linux OS 的网络应用程序。 我的 package.json 看起来像这样。

{
  "name": "frontend",
  "version": "1.0.0",
  "description": "This package contains all necessary depenencies for frontned",
  "main": "index.js",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start -p $PORT",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "masnad",
  "license": "ISC",
  "dependencies": {
    "@zeit/next-css": "^1.0.1",
    "next": "^8.0.3",
    "react": "^16.8.3",
    "react-dom": "^16.8.3"
  }
}

我首先创建了一个空的 webapp,然后使用部署服务 kudu 将我的代码从本地推送到 azure。

推送到 Azure 时的 git 日志如下所示

remote: ..............................................................
remote: npm WARN rollback Rolling back fsevents@1.2.7 failed (this is probably harmless): ENOTEMPTY: directory not empty, rmdir '/home/site/wwwroot/node_modules/fsevents/node_modules/abbrev'
remote: npm WARN rollback Rolling back rc@1.2.8 failed (this is probably harmless): ENOTEMPTY: directory not empty, rmdir '/home/site/wwwroot/node_modules/fsevents/node_modules/rc/node_modules/minimist'
remote:
remote: > ax-frontend@1.0.0 postinstall /home/site/wwwroot
remote: > next build
remote:
remote: ...............
remote: Creating an optimized production build ...
remote:
remote: ...
remote: Compiled successfully.
remote:
remote:  ┌ /
remote:  ├ /_app
remote:  ├ /_document
remote:  └ /_error
remote:
remote: npm WARN unistore@3.2.1 requires a peer of preact@* but none is installed. You must install peer dependencies yourself.
remote: audited 6645 packages in 139.904s
remote: found 0 vulnerabilities
remote: npm WARN ax-frontend@1.0.0 No repository field.
remote:
remote: npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/fsevents):
remote: npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
remote:
remote:
remote: > ax-frontend@1.0.0 build /home/site/wwwroot
remote: > next build
remote:
remote: .........
remote: Creating an optimized production build ...
remote:
remote: ...
remote: Compiled successfully.
remote:
remote:  ┌ /
remote:  ├ /_app
remote:  ├ /_document
remote:  └ /_error
remote:
remote:
remote: Done.
remote: Running post deployment command(s)...
remote: Deployment successful.
remote: App container will begin restart within 10 seconds.
To https://node-ax-dev.scm.azurewebsites.net:443/node-ax-dev.git
   ec4d5ad..dcadc02  development -> master

所以我猜它部署得很好。 我去了 https://node-ax-dev-1212.azurewebsites.net 但什么也没发生。

所以我在实例中使用 SSH,然后 运行 npm run dev,它立即向我显示 localhost:3000 上的项目 运行。

所以我写了 https://node-ax-dev-1212.azurewebsites.net:3000 但它没有工作,因为它在终端中告诉端口已经在使用中并关闭了。

我不确定哪里出了问题,但感觉我大部分过程都是正确的。

我没有添加任何特定的环境变量,所以一切都是全新的。 我的目录如下所示。

P.S 我也尝试在应用程序设置中添加 runtime 启动文件命令 npm run dev 但我认为它不起作用。

Azure 需要一个 web.config 文件和一个服务器。js/index.js 作为起点,否则它将无法启动。

我建议更改您的文件夹结构。请参阅下面的示例 https://github.com/zeit/next.js/tree/master/examples/custom-server

创建 server.js 文件并复制上述 github 存储库中的信息。 在 package.json 文件中将 dev build and start 替换为

"dev": "node server.js",
"build": "next build",
"start": "node server.js"

现在您只需使用 node server.js 即可 运行 您的代码。

将其上传到 Azure 时,在您的根目录中创建一个文件调用 web.config 并添加以下代码。

<?xml version="1.0" encoding="utf-8"?>
<!--
     This configuration file is required if iisnode is used to run node processes behind
     IIS or IIS Express.  For more information, visit:
     https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->

<configuration>
  <system.webServer>
    <!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support -->
    <webSocket enabled="false" />
    <handlers>
      <!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
      <add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
    </handlers>
    <rewrite>
      <rules>
        <!-- Do not interfere with requests for node-inspector debugging -->
        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="^server.js\/debug[\/]?" />
        </rule>

        <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
        <rule name="StaticContent">
          <action type="Rewrite" url="public{REQUEST_URI}"/>
        </rule>

        <!-- All other URLs are mapped to the node.js site entry point -->
        <rule name="DynamicContent">
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
          </conditions>
          <action type="Rewrite" url="server.js"/>
        </rule>
      </rules>
    </rewrite>

    <!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
    <security>
      <requestFiltering>
        <hiddenSegments>
          <remove segment="bin"/>
        </hiddenSegments>
      </requestFiltering>
    </security>

    <!-- Make sure error responses are left untouched -->
    <httpErrors existingResponse="PassThrough" />

    <!--
      You can control how Node is hosted within IIS using the following options:
        * watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server
        * node_env: will be propagated to node as NODE_ENV environment variable
        * debuggingEnabled - controls whether the built-in debugger is enabled
      See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options
    -->
    <!--<iisnode watchedFiles="web.config;*.js"/>-->
  </system.webServer>
</configuration> 

根据需要通过调整 server.js 文件添加和更改路线后。

将其推送到 azure,您的应用程序将开始 运行ning,因为 azure 现在将 运行 节点 server.js 并且知道在哪里可以找到它。 而且 web.config 文件将重写 URL,因此您不必添加 yoururl.azure.net:3000,您只需输入 URL 即可。

通过对我的应用程序进行以下更改,我能够在 Azure Appservices 上获得 Next.js 到 运行。对您的 Express 应用和 package.json 文件进行以下更改。

// server.js

const express = require('express')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

// Your app will get the Azure port from the process.enc.PORT
const port = process.env.PORT || 3000;

app
  .prepare()
  .then(() => {
     const server = express()

     server.get('*', (req, res) => {
         return handle(req, res)
     })

     server.listen(port, err => {
        if (err) throw err
            console.log('> Ready on http://localhost:3000')
        })
     })
     .catch(ex => {
         console.error(ex.stack)
         process.exit(1)
     })

在您的 package.json 文件中,您需要确保您有 postinstallstart 的脚本。一开始你可以像下面这样添加一个端口变量。

"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "next start -p $PORT",
  "postinstall": "next build"
}

我在 Running Next.js on Azure App Services

有一个关于如何修复的博客 post

从今天(2021 年 10 月 30 日)开始,您不需要 Azure Linux webapp 中的 web.config 文件,IIS 上不需要 运行。您只需要一个命令即可从 Linux 具有 Node JS 环境的网络应用程序上的代码启动网络应用程序。

对于您的应用程序,我建议除非需要,否则不要自定义端口。在您的 package.json 中使用 next start 命令删除端口规范,这应该可以通过以下建议的方法解决问题。

{
  "name": "frontend",
  ...
  "scripts": {
    ...
    "start": "next start",
    ...
  },
  ...
}

Azure Linux Web 应用服务(容器)默认使用端口 8080 并将其映射到外部 http/https (80/443) 端口。

根据 Microsoft documentation 在 Azure Linux 网络应用程序上部署 Node JS / Next JS 应用程序,推荐的方法是使用 PM2 而不是 npm start (或) node server.js.

使用 PM2 比编写自己的 server.js 容易得多,因为 PM2 默认情况下已在 Azure Web 应用程序中使用 NodeJS 运行 次。 PM2 还提供了一个全方位服务的应用程序管理平台。

要使用它,只需使用以下代码将 ecosystem.config.js 文件添加到您的 Next JS 应用程序。

module.exports = {
  apps: [
    {
      name: "my-nextJs-site",
      script: "./node_modules/next/dist/bin/next",
      args: "start -p " + (process.env.PORT || 3000),
      watch: false,
      autorestart: true,
    },
  ],
};

根据上面提到的 Microsoft 文档,部署后的代码一旦找到 ecosystem.config.js 文件,就会自动以 PM2 开头。

The container automatically starts your app with PM2 when one of the common Node.js files is found in your project:
bin/www
server.js
app.js
index.js
hostingstart.js
(or) One of the following PM2 files: process.json or ecosystem.config.js

注意:如果应用程序在此之后仍未自动启动,您可以使用以下 PM2 命令作为 azure webapp 设置中的启动命令手动启动它。

pm2 --no-daemon start /home/site/wwwroot/ecosystem.config.js

请不要在 Azure 应用程序服务中使用 PM2,以防您遇到下一个 js 路由问题。在启动命令中我们可以使用“npx install serve -g && serve” 在我的例子中,我的下一个 js 文件在 out 文件夹中,所以使用: “npx install serve -g && serve ./out”

如果您仍然遇到任何问题,请告诉我。