firebase-tools
firebase-tools copied to clipboard
Angular SSR 17 in Firebase : listen EADDRINUSE: address already in use :::8080
[REQUIRED] Environment info
firebase-tools: 13.0.2
Platform: Windows, Linux
[REQUIRED] Test case
I deploy a fully workable version from the emulator in Firebase Functions of the Angular SSR application.
[REQUIRED] Steps to reproduce
- Enabled experiment webframeworks.
- Create an application angular ssr from cli with standalone componenet
- run it locally
- deploy it in the firebase. During Local build I have next warning
▲ [WARNING] Module 'undici' used by 'node_modules/@firebase/auth/dist/node-esm/index.js' is not ESM
▲ [WARNING] Module '@grpc/grpc-js' used by 'node_modules/@firebase/firestore/dist/index.node.mjs' is not ESM
▲ [WARNING] Module '@grpc/proto-loader' used by 'node_modules/@firebase/firestore/dist/index.node.mjs' is not ESM
▲ [WARNING] Module 'undici' used by 'node_modules/@firebase/functions/dist/esm-node/index.node.esm.js' is not ESM
▲ [WARNING] Module 'undici' used by 'node_modules/@firebase/storage/dist/node-esm/index.node.esm.js' is not ESM
CommonJS or AMD dependencies can cause optimization bailouts.
For more information see: https://angular.io/guide/build#configuring-commonjs-dependencies
[REQUIRED] Expected behavior
Should work exactly as in the emulator.
[REQUIRED] Actual behavior
SSR Page returns: Service Unavailable
Logs
Default STARTUP TCP probe succeeded after 1 attempt for container "ssr-project-name-1" on port 8080.
Uncaught exception
Error: listen EADDRINUSE: address already in use :::8080
at Server.setupListenHandle [as _listen2] (node:net:1872:16)
at listenInCluster (node:net:1920:12)
at Server.listen (node:net:2008:7)
at te.listen (file:///workspace/dist/ssr-project-name/server/server.mjs:81:3210)
at $k (file:///workspace/dist/ssr-project-name/server/server.mjs:99:5579)
at file:///workspace/dist/ssr-project-name/server/server.mjs:99:5665
at ModuleJob.run (node:internal/modules/esm/module_job:217:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
at async importModuleDynamicallyWrapper (node:internal/vm/module:431:15)
Error: Process exited with code 16
at process.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:92:22)
at process.emit (node:events:514:28)
at process.emit (node:domain:488:12)
at process.exit (node:internal/process/per_thread:193:15)
at sendCrashResponse (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/logger.js:44:9)
at process.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:84:44)
at process.emit (node:events:526:35)
at process.emit (node:domain:488:12)
at process._fatalException (node:internal/process/execution:159:25)
I have the same problem, I have published a repo with the minimum to recreate the SSR problem with angular 17: https://github.com/hittten/angularSSR17
Clone & Setup:
git clone https://github.com/hittten/angularSSR17
npm install
npx firebase init hosting
Logs:
=== Account Setup
Which account do you want to use for this project? Choose an account or add a new one now
? Please select an option: [email protected]
✔ Using account: [email protected]
=== Project Setup
First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.
? Please select an option: Use an existing project
? Select a default Firebase project for this directory: xxxxxxx(xxxxxxx)
i Using project xxxxxxx (xxxxxxx)
=== Hosting Setup
? Detected an existing Angular codebase in the current directory, should we use this? Yes
? In which region would you like to host server-side content, if applicable? europe-west1 (Belgium)
? Set up automatic builds and deploys with GitHub? No
i Writing configuration info to firebase.json...
i Writing project information to .firebaserc...
✔ Firebase initialization complete!
Deploy to firebase hosting with SSR function
npx firebase deploy
Server logs:
Error: listen EADDRINUSE: address already in use :::8080
at Server.setupListenHandle [as _listen2] (node:net:1872:16)
at listenInCluster (node:net:1920:12)
at Server.listen (node:net:2008:7)
at te.listen (file:///workspace/dist/angular-ssr17/server/server.mjs:81:3210)
Error: Process exited with code 16
at process.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:92:22)
at process.emit (node:events:514:28)
at process.emit (node:domain:488:12)
at process.exit (node:internal/process/per_thread:193:15)
at sendCrashResponse (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/logger.js:44:9)
at process.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:84:44)
at process.emit (node:events:526:35)
at process.emit (node:domain:488:12)
at process._fatalException (node:internal/process/execution:159:25)
{
"textPayload": "The request failed because either the HTTP response was malformed or connection to the instance had an error. Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#malformed-response-or-connection-error",
"insertId": "659475b700062cb90f40d1e3",
"httpRequest": {
"requestMethod": "GET",
"requestUrl": "https://fh-8d3e45905df6630b---ssrfirebase-project-ou4f5ridea-ew.a.run.app/home",
"requestSize": "1456",
"status": 503,
"responseSize": "896",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"remoteIp": "xx.xx.xx.xx",
"serverIp": "xx.xx.xx.xx",
"latency": "0.003751506s",
"protocol": "HTTP/1.1"
},
"resource": {
"type": "cloud_run_revision",
"labels": {
"revision_name": "ssrfirebase-project-00049-suv",
"service_name": "ssrfirebase-project",
"location": "europe-west1",
"configuration_name": "ssrfirebase-project",
"project_id": "firebase-project"
}
},
"timestamp": "2024-01-02T20:44:39.398780Z",
"severity": "ERROR",
"labels": {
"instanceId": "0087599d42b9441d6d09db1939ddd4cf4272e2926a4f28f80a4a7435e09c496814eec2631eed5c4f41d11da415f43dbdd4584eebf9300d2775bc6e376358218de7",
"goog-managed-by": "cloudfunctions"
},
"logName": "projects/firebase-project/logs/run.googleapis.com%2Frequests",
"trace": "projects/firebase-project/traces/2cbddcb349eb67f0b870211ea2050942",
"receiveTimestamp": "2024-01-02T20:44:39.688582619Z",
"spanId": "15678518055140550732"
}
Info
basically I have created a project like this:
npx @angular/[email protected] new angularSSR17 --ssr --routing --scss --skip-tests
cd angularSSR17
npm i -D [email protected]
ng g c pages/homePage
ng g c pages/aboutPage
ng g c pages/notFoundPage
I also disable pre-render in angular.json:
{
"scripts": [],
"server": "src/main.server.ts",
"prerender": false,
"ssr": {
"entry": "server.ts"
}
}
and I have done the settings of the routes for lazy load. I have not installed @angular/fire because it is not necessary to recreate the SSR error.
ng version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 17.0.8
Node: 20.10.0
Package Manager: npm 10.2.5
OS: darwin arm64
Angular: 17.0.8
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, platform-server
... router, ssr
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1700.8
@angular-devkit/build-angular 17.0.8
@angular-devkit/core 17.0.8
@angular-devkit/schematics 17.0.8
@schematics/angular 17.0.8
rxjs 7.8.1
typescript 5.2.2
zone.js 0.14.2
firebase-tools version:
13.0.2
Hi @hittten,
I discovered a workaround that can be applied to the code of an Angular application.
For example in the server.ts, https://github.com/hittten/angularSSR17/blob/2ed948581d32b20b45c66e8c4f4f72046d9a5cf4/server.ts#L46-L54 adjust a way of setting port variable. It looks like the PORT environment variable is already used. The solution could be:
const port = process.env['NG_SSR_PORT'] || 4000;// change the environment variable nameconst port = 4000;// hardcode the port value without using environment variable
I don't know what exactly is the root cause, but as I mentioned it looks like PORT environment variable is already used.
Getting the same error:
Error: listen EADDRINUSE: address already in use :::8080
at Server.setupListenHandle [as _listen2] (node:net:1817:16)
at listenInCluster (node:net:1865:12)
at Server.listen (node:net:1953:7)
at te.listen (file:///workspace/dist/lucas-app/server/server.mjs:81:3210)
at Mk (file:///workspace/dist/lucas-app/server/server.mjs:99:5579)
at file:///workspace/dist/lucas-app/server/server.mjs:99:5665
at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:336:24)
at async importModuleDynamicallyWrapper (node:internal/vm/module:429:15)
const port = process.env['NG_SSR_PORT'] || 4000;// change the environment variable nameconst port = 4000;// hardcode the port value without using environment variableI don't know what exactly is the root cause, but as I mentioned it looks like
PORTenvironment variable is already used.
@9kubczas4 Thanks for information. This works well!
Add info:
If you deploy index.html, Functions will not work and must be IGNORED.
{
"source": ".",
"frameworksBackend": {
"region": "asia-east1"
},
"ignore": [
+ "index.html",
@rdlabo thanks. Removing this process.env['NG_SSR_PORT'] worked
But will this be fixed in future releases in angular
Thank you for your comment, but in which file can I find it?
{ "source": ".", "frameworksBackend": { "region": "asia-east1" }, "ignore": [
- "index.html",
const port = process.env['NG_SSR_PORT'] || 4000;// change the environment variable nameconst port = 4000;// hardcode the port value without using environment variableI don't know what exactly is the root cause, but as I mentioned it looks like
PORTenvironment variable is already used.@9kubczas4 Thanks for information. This works well!
Add info:
If you deploy index.html, Functions will not work and must be IGNORED.
{ "source": ".", "frameworksBackend": { "region": "asia-east1" }, "ignore": [ + "index.html",
Thank you for your comment, but in which file can I find it? to make an addition
Reserved environment variables are listed here: https://firebase.google.com/docs/functions/config-env?gen=2nd#reserved-names
// In cloud functions bootstrap.js
const app = import(`./dist/project/server/server.mjs`).then(server => server.app());
exports.handle = (req, res) => app.then(it => it(req, res));
It appears that the run() function generated by Angular CLI is unnecessary. I use an firebase instance in my backend, it seems to execute firebase initializeApp() twice, leading to an error.
@9kubczas4 your workaround works perfectly.
Any update about this? this issue doesn't happen in angular 16.
Same problem here. Any news ?
Please for now try to apply this workaround for Angular 17: https://github.com/firebase/firebase-tools/issues/6651#issuecomment-1881647322.
I created a fix in angular-cli - https://github.com/angular/angular-cli/pull/27333, once it's merged then it'll be available in one of the future Angular releases.