I have an application built using Angular 17 with SSR enabled
When I build the application I got 2 folders inside the dist\AppName folder (browser and server folders)
I need help to know the steps to deploy the application on IIS with SSR enabled
I created a folder on the machine, added the content of the "Server" folder to it and added the following web config file and created a site on IIS, but the application site didn't work
The "Server" folder content is
Appreciate your help on this matter as I didn't find any content to help with this
Based on your description, I created a simple demo and referred to this answer, finally implement your requirement.
I'm not sure where you are in your current deployment process. Please make sure you have installed IISnode and URL Rewrite module.
Create application pool with No Manage Code
, in my test its name ssrPool.
Modify server.ts
:
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import express from 'express';
import { fileURLToPath } from 'node:url';
import { dirname, join, resolve } from 'node:path';
import bootstrap from './src/main.server';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
...
...
//function run(): void {
// const port = process.env['PORT'] || 4000;
// Start up the Node server
// const server = app();
// server.listen(port, () => {
// console.log(`Node Express server listening on http://localhost:${port}`);
// });
//}
//run();
export * from './src/main.server';
main.js
:async function run() {
try {
// Import the app from the ES module
const server = await import("./server/server.mjs");
const app = await server.app();
const port = process.env["PORT"] || 4000; //modify the port here if you need.
// Start up the Node server
app.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
} catch (error) {
console.error("Failed to import app:", error);
}
}
run();
web.config
:<configuration>
<system.web>
<httpRuntime enableVersionHeader="true" />
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
<add name="X-Content-Type-Options" value="nosniff" />
<add name="X-Frame-Options" value="DENY" />
<add name="X-XSS-Protection" value="1; mode=block" />
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<webSocket enabled="false" />
<handlers>
<!-- Indicates that the main.js file is a node.js site to be handled by the iisnode module -->
<add name="iisnode" path="main.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="^main.js\/debug[\/]?" />
</rule>
<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
<match url="^(?!.*login).*$"></match>
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
</conditions>
<action type="Rewrite" url="main.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" />
<!-- Restart the server if any of these files change -->
<iisnode watchedFiles="web.config;*.js;browser/*.*" nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" />
</system.webServer>
</configuration>