Deploy NextJS to Azure Web Service/ IIS

There are two steps required to deploy NextJS to IIS server or Azure Web Service:
First: Prepare the NextJs Application.
Second: Prepare the IIS Server or Azure Web Service depeneding on where you want to deploy tour application.

Preparing NextJs Application:
1- Create custom server file in the root of the application, create server.js file that contains code from the following page : https://nextjs.org/docs/advanced-features/custom-server

// server.js
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')

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

app.prepare().then(() => {
  createServer((req, res) => {
    // Be sure to pass `true` as the second argument to `url.parse`.
    // This tells it to parse the query portion of the URL.
    const parsedUrl = parse(req.url, true)
    const { pathname, query } = parsedUrl

    if (pathname === '/a') {
      app.render(req, res, '/a', query)
    } else if (pathname === '/b') {
      app.render(req, res, '/b', query)
    } else {
      handle(req, res, parsedUrl)
    }
  }).listen(3000, (err) => {
    if (err) throw err
    console.log('> Ready on http://localhost:3000')
  })
})

2- convert the port number in the server.js file to variable as the following:
const port = process.env.PORT || 3000

3- change the listen function and replace the port number with port variable:

 }).listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })

4- Edit package.json, change the start value to “node server.js” script like this:

"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "node server.js",
    "lint": "next lint"
  },

5- Finally, to check every thing work correctly, build the application with following command
npm run build

try to run the application with the command npm start, it should work correctly

6- Now we have to add web.config file to the root of the project , from this repo: https://github.com/MRCollective/nextjs-server-azuresiteextension
copy the content of the web.config file here: https://github.com/MRCollective/nextjs-server-azuresiteextension/blob/master/Next.js/files/web.config
we only need the code between the <configuration> tag.

<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>


7- Make sure that the path to server.js file in the web.config is correct.

8- Edit security section in the web.config file to add node_moudules segment like this

 <security>
      <requestFiltering>
        <hiddenSegments>
          <add segment="node_modules"/>
        </hiddenSegments>
      </requestFiltering>
    </security>

9- Add node environment like this : (optional) refer to the NextJS custom server documentation for more info

 <httpErrors existingResponse="PassThrough" />
 <iisnode node_env="production" />
        

10 – Edit package.json to start for the production node:

 "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "NODE_ENV=production node server.js",
    "lint": "next lint"
  },

At this point the application is ready to be deployed to Azure Web Service, just make sure to select the NodeJS stack when creating the service

Preparing the IIS server

1- Install url rewrite from this url : https://www.iis.net/downloads/microsoft/url-rewrite

2- Install iisnode from the following url : https://github.com/tjanczuk/iisnode/releases/tag/v0.2.21

3- Windows Control Panel => From the turn windows features on-off, change the Internet Information Service, select following options :

4- Go to windows services and restart the service World Wide Web Publishing

5- Create new web application in the IIS server and point the application to NextJS folder, build the application with npm run build and run the application from IIS server, it should work.
sometimes we will need to add IIS_IUSRS permission to the folder of the project.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s