Can I tell foreman to reload the web app every time a request is made so I can develop decently? - node.js

A web app I am writing in JavaScript using node.js. I use Foreman, but I don't want to manually restart the server every time I change my code. Can I tell Foreman to reload the entire web app before handling an HTTP request (i.e. restart the node process)?

Here's an adjusted version of Pendlepants solution. Foreman looks for an .env file to read environment variables. Rather than adding a wrapper, you can just have Foreman switch what command it uses to start things up:
In .env:
WEB=node app.js
In dev.env:
WEB=supervisor app.js
In your Procfile:
web: $WEB
By default, Foreman will read from .env (in Production), but in DEV just run this:
foreman start -e dev.env

You can use rerun for this purpose
You might implement just 2 commands for this:
gem install rerun
rerun foreman start
Then rerun will automatically restart process after any change in your files.

If you use nodemon
, you can do
nodemon --exec "foreman start"

The problem isn't with Foreman so much as it's with how node doesn't reload code on new requests. The solution is to use an npm package like supervisor along with an environment wrapper for Foreman.
First, install supervisor:
npm install -g supervisor
Then, write a wrapper shell script that Foreman can call:
if [ "$NODE_ENV" == "production" ]; then
node /path/to/app.js
else
supervisor /path/to/app.js
fi
Set the wrapper script's permissions to executable by running chmod a+x /path/to/wrapper_script.sh
Lastly, update foreman to use the wrapper script. So in your Procfile:
web: /path/to/wrapper_script.sh
Now when you run Foreman and your node app isn't running in production, it should reload on every request.

I feel like Peter Ehrlich's comment on the original question deserves to be an answer on its own. I think a different Procfile for local/dev is definitely the best solution: https://stackoverflow.com/a/10790514/133720

You don't even need to install anything new if you use node-dev.
Your .env file loaded from Procfile:
NODECMD=node-dev
Your Procfile:
web: $NODECMD app/server.js
Your foreman command
foreman start -e dev.env -p 9786
And in your production env (heroku) set an environment variable:
NODECMD=node

Related

Run nextjs application in the background

I have an application built with nextJs and this application should work on a local server (Windows).
my customer told me that he needed this application to work in the background after searching I found that I needed to use a package called pm2 and when I used it gives me an error and I found that I needed to make some configurations for it and I can't found any helping resources, please help 💔
I found that to run nextJs application in the background you will need a custom configuration
you need to download the pm2 globally in your system
create a file with the name ecosystem.config.js in the root folder next to the package.json file
you need to put your config data in this file which would be something like this
module.exports = {
apps: [
{
name: "inventory_test",
script: "node_modules/next/dist/bin/next",
args: "start -p 3333", //running on port 3000
watch: false,
},
],
};
you should set the name as the name you want to see when you check
the list of pm2
the problem will be solved when you set the script as I did in the code above to be more precise the default run of pm2 is to go to the node js folder in the system and try to make start for the application using npm directly but this is the problem we need to make it use the node runner from the nextjs itself or something like this so we change the script as above
after that, we set the arguments that we should run after the npm and in my example is the arg start and choose the port for our application too
and now we make our config
NOTES
you should make build before you start the application
to run the project you will open the folder of the project in the terminal || cmd || cmder and run the command pm2 start ecosystem.config.js

Cannot connect to my databse addon on heroku

I attempted to use the command Heroku pg:psql to connect to my database addon in heroku but got a response below
--> Connecting to postgresql-regular-61345
unrecognized win32 error code: 123could not find a "psql" to execute
unrecognized win32 error code: 123could not find a "psql" to execute
psql: fatal: could not find own program executable
! psql exited with code 1
After using the heroku logs --tail command i got the following errors
sh: 1: nodemon: not found
Process exited with status 127
State changed from starting to crashed
I can also see all processes stopping with SIGTERM and the process exiting with status 143
Resolution steps I have taken
Verified that the environment variables have the path for installed postgress14 on my PC
Added a procfile to the root file in my backend code and spcified "web: node matthewfaceappback/server.js in the file"
Changed my set port to a variable port using process.env.PORT || 3000
Set all environment variable including my database url(set by default) on config variable in heroku
Verified there is a start up script
Updated all my packages using "npm update". after doing this i started expereincing the issue of processes stopping with SIGTERM and the process exiting with status 143
I moved nodemon from devDependencies to dependencies. nodemon version is 2.0.15
In package.json i inputed an engines parameter using the version of node in my case
{"engines": {
"node": "14.17.4"
}}
I restarted heroku using "heroku restart"
Below are links to the screenshots of the error
https://www.dropbox.com/s/5bdbyi9e99lbxhu/pic1.PNG?dl=0
https://www.dropbox.com/s/41euniaes5q68c9/pic2.PNG?dl=0
https://www.dropbox.com/s/50oqzbwmwrqogax/pic3.PNG?dl=0
Put nodemon back in the devDependencies and add it as a second node script in package.json:
"scripts": {
"start": "node matthewfaceappback/server.js",
"dev": "nodemon matthewfaceappback/server.js"
},
These two errors are completely unrelated.
The database connection error
The first issue, which I believe is the one you actually care about at the moment based on the title of the question, indicates that the Heroku CLI can't find a PostgreSQL client on your local machine.
The documentation makes the following recommendation
Set up Postgres on Windows
Install Postgres on Windows by using the Windows installer.
Remember to update your PATH environment variable to add the bin directory of your Postgres installation. The directory is similar to: C:\Program Files\PostgreSQL\<VERSION>\bin. Commands like heroku pg:psql depend on the PATH and do not work if the PATH is incorrect.
If you haven't already installed Postgres locally, do so. (This is a good idea anyway as you should be developing locally and you'll probably need a database.)
Then make sure to add its bin/ directory to your PATH environment variable.
The Nodemon error
The second issue is because you are trying to use nodemon in production. Heroku strips development dependencies out of Node.js applications after building them, which normally makes sense. Nodemon is a development tool, not something that should be used for production hosting.
Depending on the contents of your package.json, this might be as simple as changing your start script from nodemon some-script.js to node some-script.js. Alternatively, you can add a Procfile with the command you actually want to run on Heroku:
web: node some-script.js
See also Need help deploying a RESTful API created with MongoDB Atlas and Express

How can I check if my pm2 app NODE_ENV is getting set?

So I just deployed a site with node and pm2 for the first time and I'm going back and doing some optimization and reading best practices, etc.
I read that you can get a lot of benefit by setting NODE_ENV=production.
I found this in the pm2 docs:
[process.json]
"env_production" : {
"NODE_ENV": "production"
}
...
$ pm2 start process.json --env production
So, I did it but I have no idea if it is working. While trying to figure out how to check it I learned to try:
$ node
> process.env.NODE_ENV
> undefined
So, that's not a good sign.. but, with my limited understanding of how the low level stuff works, I can guess that maybe pm2 launches each app as a separate node process? So maybe I'm not in the right process when I try to check it.
Also, I don't know if I have to make a new ~/.pm2/dump.pm2 file because maybe whenever that is maybe overriding the options I set? (because I used pm2 startup).
How do I check if my pm2 app's NODE_ENV is set?
To answer the actual question in the title:
Within your script, for me my Express app's app.js file, you can use process.env.NODE_ENV to get the current value of NODE_ENV and log that out if you want.
An even better way is to use PM2's Process Metrics module, aka pmx.
yarn add pmx
or
npm install pmx --save
then
const Probe = require('pmx').probe()
Probe.metric({
name : 'NODE_ENV',
value : function() {
return process.env.NODE_ENV
}
})
Now it will show up in calls to pm2 monit (bottom left).
To change your environment:
It is necessary that you kill and restart the process to change your environment.
$ pm2 kill && pm2 start pm2.json --env production
The following isn't good enough:
pm2 restart pm2.json --env production
You can also check your NODE_ENV via running pm2 show <yourServerName>. This will output info about your running server including node env.
In addition, you can check your environment variables via running pm2 env 0. This will show all the environment variables for the running node process.
Start it with npm by adding this to your package.json:
"scripts": {
"myScript": "NODE_ENV=production pm2 start server.js"
}
Then
npm start myScript
You can do it directly too, but this is easy to manage, automate wth crontab and is in your source control...
Your process.json file is incomplete. Try using something like this:
[process.json]
{
"name" : "MyApp",
"script" : "myapp.js",
"env_production" : {
"NODE_ENV": "production"
}
}
Then add logging into your code, preferably somwhere on startup:
console.log("NODE_ENV : ", process.env.NODE_ENV);
Now start the application:
pm2 start process.json --env production
Lastly watch app logs:
pm2 logs MyApp
This should do it.
May be at the start of your server script you can print the value of the environment variable and then check the PM2 logs. Use the following code to print your environment variable value:
console.log('process.env.NODE_ENV:', process.env.NODE_ENV);
And then use the following code to see the PM2 logs
pm2 logs app_name
Here app_name is your process name as indicated by the entry in the process.json file.
You can set Environment variable for pm2 specifically.
go to /etc/systemd/system/ location.
you can see a file named pm2-username.service
file. (eg: pm2-root.service ) you can directly add an Enviorment variable for pm2.
for me, it was LD_LIBRARY_PATH . so I added the line as below after the PATH variable.
Environment=PATH=/usr/local/lib......
Environment=LD_LIBRARY_PATH=/opt/oracle/instantclient_21_1
after that, you can restart or start the node application with update-env flag,
pm2 start yourapp --update-env
try pm2 env <app_name/id> also you can find NODE_ENV in pm2 show <app_name/id>
In your terminal just type:
echo NODE_ENV
it will print current selected environment variable

Does travis-ci.org support pm2?

I set up a nodejs auto test with travis-ci.org。I need to set up a server to support static files.I want to know if trvis-ci support pm2:)
Or,is there any way to record a server`s pid。
like pm2 do:
pm2 start app.js
pm2 stop app.js
You can install pm2 on travis. To do that, you need to change your .travis.yml:
before_script:

Forever with npm start and environment variable

I used to start my application using:
DEBUG=chakka ENVIRONMENT=production npm start
How can i start it using forever so i wouldn't have to do it everytime i want to test the application? Thanks!
First you need to know what the application's main script file is. Open up your package.json file and find out what the start script is. If you're using Express it might be app.js. So we'll assume app.js for this example, replace with whatever your file is.
To start the application:
DEBUG=chakka ENVIRONMENT=production forever start app.js
to restart the application after you've made changes:
forever restart app.js

Resources