pm2 restart loop in AWS Elastic Beansalk (Node environment) - node.js

I have a NodeJs environment built in AWS Elastic Beanstalk. I'm using pm2 to monitor 2 different NodeJS apps uploaded to environment. The kicker is I need to make sure the local app is started before the gateway app starts. I'm using npm-run-all synchronously to start apps in a specific order.
Here's my package.json:
"start": "npm-run-all -s start:local start:gateway",
"start:local": "pm2 start ./ecosystem.config.js --only local-service --env production",
"start:gateway": "pm2 start ./ecosystem.config.js --only gateway-service --env production",
Here's my ecosystem.config file:
module.exports =
{
apps:
[
{
name: 'local-service',
script: './dist/services/local.js',
watch: false,
interpreter: 'node',
interpreter_args: '--require ts-node/register --require tsconfig-paths/register',
autorestart: false
},
{
name: 'gateway-service',
script: './dist/server.js',
watch: false,
interpreter: 'node',
interpreter_args: '--require ts-node/register --require tsconfig-paths/register',
wait_ready: true,
listen_timeout: 5000,
autorestart: false
}
]
};
The elastic beanstalk log is indicating start in package.json is continuously being called. I've configured each app to not restart, but there seems to be something else causing the continuous restart to happen. I'm getting 502 Bad Gateway error when trying to access the gateway-service itself.

Please try to use just pm2 ecosystem without npm-run-all, i.e. just pm2 start ecosystem.config.js and allow any (re)start sequences, because in real life your gateway & local apps can be restarted in different orders.
So instead of using start scheduling logic - please consider to move that logic to your local app - to monitor & re-connect on connection failure with gateway app.
In case you still want to use start scheduling logic, please take a look at pm2 process actions and add to gateway app code to trigger starting your local app.

Related

Hangs on build using nestjs, pm2

I want to provide uninterrupted service using nestjs, pm2.
I download the changes via git pull origin master command.
After that, save the new changes through the yarn build command.
At this time, the service stops with an error saying dist/main.js cannot be found.
I tried to move the dist folder that was build outside the operating folder using mv, but it stopped and the service started again after entering the reload command.
Below is my code. How can I operate uninterrupted service?
//ecosystem.config.js
name: 'my_api',
script: 'dist/main.js',
watch: '.',
instances: 2,
exec_mode: 'cluster',
wait_ready: true,
listen_timeout: 20000,
kill_timeout: 5000
//package.json
"prebuild": "rimraf dist",
"start": "yarn build && pm2 start ecosystem.config.js",
You need to remove the dist folder before creating the build of the application. Stop the pm2 service and create a fresh build. After creating a fresh build. Restart the pm2 service. It will be fine.
I removed the watch:'.', the service did not stop during build,
and I was able to run it normally through the command pm2 reload myApp.

Why Does My ReactJS App Run Locally But Not In Azure?

I have a ReactJS app that connects to json-server as a fake API.
I have deployed it to Azure using VSCode and the F1 Free Linux tier.
When I run it locally with npm start everything works.
"scripts": {
"start": "npm-run-all --parallel mock web",
"web": "cross-env PORT=8080 react-scripts start",
"mock": "node index.js"
},
The index.js contains the json-server config etc as it is a bit more than json-server --watch db.json
I am using the package npm-run-all to run json-server and the react app at the same time.
This works fine locally but when I try to deploy it to Azure the container fails to start:
INFO - Starting container for site
INFO - docker run -d -p 7307:8080 --name demo_0_8cd -e WEBSITE_SITE_NAME=demo -e WEBSITE_AUTH_ENABLED=False -e WEBSITE_ROLE_INSTANCE_ID=0 -e WEBSITE_HOSTNAME=demo.azurewebsites.net -e WEBSITE_INSTANCE_ID=8fe4512f9f -e HTTP_LOGGING_ENABLED=1 appsvc/node:12-lts_20200918.1
INFO - Initiating warmup request to container demo_0_8cd for site demo
ERROR - Container demo_0_8cd for site demo has exited, failing site start
ERROR - Container demo_0_8cd didn't respond to HTTP pings on port: 8080, failing site start. See container logs for debugging.
INFO - Stopping site demo because it failed during startup.
I can't see much in the container logs to debug this.
I also can't tell what command Azure is using to start since all it says in the logs is docker run.
Is it calling npm start? (see EDIT - tldr: yes)
Why is it working locally but not in Azure?
Why is it not responding to the ping?
Is it something to do with this being a React app instead of "just" a node app?
EDIT:
The docker container that this tutorial generates has scripts in /opt/startup.
The templated one is /opt/startup/init_container.sh and this contains:
STARTUP_COMMAND_PATH="/opt/startup/startup.sh"
STARTUPCOMMAND=$(cat $STARTUP_COMMAND_PATH)
echo "Running $STARTUPCOMMAND"
$STARTUP_COMMAND_PATH
The /opt/startup/startup.sh contains
# Enter the source directory to make sure the script runs where the user expects
cd "/home/site/wwwroot"
npm start
The start script in the package.json for the demo app has "start": "node ./bin/www"
Which then has:
var http = require('http');
var server = http.createServer(app);
server.listen(port);
So the key thing here is that it does npm start to run which then creates a nodejs server to serve the application on port 8080.
The npm start in my application ends up calling react-scripts start, which uses the WebpackDevServer
Whilst you shouldn't use the dev server for production, does that also mean you can't use it on a server for some reason?
This is just a test/demo to familiarise myself with Azure and not production.
The end result is that npm run is running the WebpackDevServer.
This isn't designed for production so we need to have another way of running on Azure.
Changing the Azure webapp Startup command to npx serve -l 8080 build will run the ReactJS application in Azure.
NB: This answer explains how to run it, but not why.
See this other question for why.

Service Worker not registered in Heroku - Angular PWA

I am trying to deploy an Angular PWA on Heroku, but I can't seem to figure it out.
The deployed app works great, however no service worker is registered according to LightHouse, therefore it is not a PWA.
Here is the process I am using to deploy :
Run ng build --prod in the angular project
Copy the dist/myapp folder next to my server.js file
Commit and push to heroku.
Before pushing, running npm run start or http-server dist/myapp works just fine locally, a service worker is registered and the app is installable.
Here is my start command in package.json and my post-deploy command in ecosystem.config.js:
"start": "pm2-runtime start ecosystem.config.js --env production"
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
Note: It uses node.js and express to load an Angular project using this method : app.use(express.static(path.join(__dirname, 'dist/myapp')));
Does anyone have an idea as to why it does not register a service worker on Heroku ?

How to start pm2 process with DEBUG option

I have an express app that I start in terminal with following command to enable debug logs in it:
DEBUG=custom:* npm start (on Ubuntu)
SET DEBUG=custom:* & npm start (on Windows)
On production server, I start app with PM2 using following command:
pm2 start bin/www -i 0
But this does not enable the debug logs in my code, so the debug statements are not added to the logs, only console.error() are added to the log files. How can I pass the DEBUG=custom:* option while starting my app with PM2?
Try DEBUG='custom:*' pm2 start bin/www -i 0
If you are restarting an existing process add the --update-env flag:
DEBUG='custom:*' pm2 restart bin/www -i 0 --update-env
Mikko was correct but if you add that to package.json scripts, it won't work!
"scripts": {
"start": "DEBUG='custom:*' pm2 start bin/www -i 0",
...
},
Because DEBUG='custom:*' is given to pm2 process NOT your process. So in this case you have to use an ecosystem file and add DEBUG setting in ecosystem file, e.g.
"scripts": {
"start": "pm2 start ecosystem.config.js",
...
},
//in ecosystem.config.js add this
env: {
NODE_ENV: 'development',
DEBUG: 'custom:*'
},

Can't find entry file when deploying node app to heroku

I'm trying to deploy my first node app to heroku. I have set up a Procfile with the following code
web: node ./app/server.js
but when I deploy to heroku and check the logs I see the error Error: Cannot find module '/app/server.js'.
On local it works fine. I have the following in my package.json nested under scripts
"start": "nodemon ./app/server.js
Nodemon is a utility that will monitor for any changes in your source and automatically restart your server. Perfect for development.
While using nodemon its better to maintain script commands for dev and production as follows:
"scripts": {
"start": "node ./app/server.js",
"dev": "nodemon ./app/server.js"
}
To determine how to start your app, The deployment server( Heroku) first looks for a Procfile. If no Procfile exists for a Node.js app, It will attempt to start a default web process via the start script in your package.json.
If you use nodemon in script, It'll internally try to run node server.js but in your case start file present in app/server.js. To avoid these issues it's better to use two separate script commands for dev and production. So that while running locally you can use npm dev command.

Resources