I am trying to deploy my Next.js (SSR) on Azure.
I have a build pipeline that publishes the entire root folder (not just .next folder as for static apps)
trigger:
- main
pool:
vmImage: "ubuntu-latest"
# Set variables
variables:
directory: .
steps:
- task: NodeTool@0
inputs:
versionSpec: "16.x"
displayName: "Install Node.js"
- script: yarn
displayName: "Install dependencies"
workingDirectory: $(directory)
- task: Cache@2
displayName: 'Cache .next/cache'
inputs:
key: next | $(Agent.OS) | yarn.lock
path: '$(System.DefaultWorkingDirectory)/.next/cache'
- script: yarn build
displayName: "Build for production"
workingDirectory: $(directory)
- task: CopyFiles@2
displayName: "Copy files"
inputs:
sourceFolder: "$(directory)"
Contents: "**/*"
TargetFolder: "$(Build.ArtifactStagingDirectory)"
cleanTargetFolder: true
- task: ArchiveFiles@2
displayName: "Archive files"
inputs:
rootFolderOrFile: "$(Build.ArtifactStagingDirectory)"
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- task: PublishBuildArtifacts@1
displayName: "Publish build artifacts"
inputs:
pathtoPublish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
I also have a file ecosystem.config.js
in project root folder with contents (as described in this answer)
module.exports = {
apps: [
{
name: "app-name",
script: "./node_modules/.bin/next",
args: "start -p " + (process.env.PORT || 3000),
watch: false,
autorestart: true,
},
],
};
As mentioned the build pipeline publishes the entire root folder as a .zip
artifact for the release pipeline.
I have a release pipeline that deploys the artifact to the App Service and runs the startup command (from the same answer as before and Microsoft docs)
pm2 start /home/site/wwwroot/ecosystem.config.js --no-daemon
package.json
scripts section
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
I can see that both build and release pipelines complete successfully and I can see the files from the root project folder are located in /home/site/wwwroot
, but when I go to the site all I get is
The link leading to diagnostic resources doesn't grant much insight, but if I check the logs for the docker container in the App Service I see
2022-05-16T11:03:07.083870878Z 2022-05-16T11:03:07: PM2 log: App [app-name:0] exited with code [1] via signal [SIGINT]
2022-05-16T11:03:07.085484100Z 11:03:07 PM2 | App [app-name:0] exited with code [1] via signal [SIGINT]
2022-05-16T11:03:07.086237210Z 2022-05-16T11:03:07: PM2 log: App [app-name:0] starting in -fork mode-
2022-05-16T11:03:07.087102722Z 11:03:07 PM2 | App [app-name:0] starting in -fork mode-
2022-05-16T11:03:07.103212737Z 2022-05-16T11:03:07: PM2 log: App [app-name:0] online
2022-05-16T11:03:07.105379766Z 11:03:07 PM2 | App [app-name:0] online
2022-05-16T11:03:07.370010000Z 11:03:07 0|app-name | Error: Cannot find module '../build/output/log'
2022-05-16T11:03:07.372651936Z 11:03:07 0|app-name | Require stack:
2022-05-16T11:03:07.372950840Z 11:03:07 0|app-name | - /home/site/wwwroot/node_modules/.bin/next
2022-05-16T11:03:07.373244644Z 11:03:07 0|app-name | at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
2022-05-16T11:03:07.373521147Z 11:03:07 0|app-name | at Module.Hook._require.Module.require (/usr/local/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:61:29)
2022-05-16T11:03:07.373779851Z 11:03:07 0|app-name | at require (node:internal/modules/cjs/helpers:94:18)
2022-05-16T11:03:07.374053954Z 11:03:07 0|app-name | at Object.<anonymous> (/home/site/wwwroot/node_modules/.bin/next:7:35)
2022-05-16T11:03:07.375460973Z 11:03:07 0|app-name | at Module._compile (node:internal/modules/cjs/loader:1101:14)
2022-05-16T11:03:07.375473673Z 11:03:07 0|app-name | at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
2022-05-16T11:03:07.375477573Z 11:03:07 0|app-name | at Module.load (node:internal/modules/cjs/loader:981:32)
2022-05-16T11:03:07.375480873Z 11:03:07 0|app-name | at Function.Module._load (node:internal/modules/cjs/loader:822:12)
2022-05-16T11:03:07.375485473Z 11:03:07 0|app-name | at Object.<anonymous> (/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js:33:23)
2022-05-16T11:03:07.375693476Z 11:03:07 0|app-name | at Module._compile (node:internal/modules/cjs/loader:1101:14) {
2022-05-16T11:03:07.376825291Z 11:03:07 0|app-name | code: 'MODULE_NOT_FOUND',
2022-05-16T11:03:07.377099895Z 11:03:07 0|app-name | requireStack: [ '/home/site/wwwroot/node_modules/.bin/next' ]
2022-05-16T11:03:07.377376699Z 11:03:07 0|app-name | }
2022-05-16T11:03:07.378681516Z 2022-05-16T11:03:07: PM2 log: App [app-name:0] exited with code [1] via signal [SIGINT]
2022-05-16T11:03:07.379377325Z 2022-05-16T11:03:07: PM2 log: Script /home/site/wwwroot/node_modules/.bin/next had too many unstable restarts (16). Stopped. "errored"
2022-05-16T11:03:07.384267191Z 11:03:07 PM2 | App [app-name:0] exited with code [1] via signal [SIGINT]
2022-05-16T11:03:07.384723497Z 11:03:07 PM2 | Script /home/site/wwwroot/node_modules/.bin/next had too many unstable restarts (16). Stopped. "errored"
Would anyone how to proceed from here?
Thanks in advance!
What is the advantage of using "pm2"? The same result could be achieved by adding another script:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"startAzure": "./node_modules/next/dist/bin/next start"
"lint": "next lint"
}
and then for the web app configure a start up script in configurations: image of where to add the script -> "npm run startAzure"
Then the web app will take care of calling that script. (I guess you could only have the script as start up script, instead of redirecting it)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With