how start actionhero by pm2 - node.js

I'm starting actionhero by this command
pm2 start .\node_modules\actionhero\bin\actionhero
But actionhero doesn't start successfully and this is in my pm2 log:
error: No config directory found in this project, specified with
--config, or found in process.env.ACTIONHERO_CONFIG

I have no experience with actionhero but it clearly says no config directory found.
Either
1. --config parameter has to be passed as next argument for pm2 start or
2. Set an env variable ACTIONHERO_CONFIG to appropriate value.
Boot Options to find the Config Directory
When launching ActionHero you can specify which config directory to use with --config '/path/to/dir' or the environment variable ACTIONHERO_CONFIG, otherwise ./config/ will be used from your working directory.
The priority of arguments is:
Use the project's ./config folder, if it exists.
actionhero --config=PATH1 --config=PATH2 --config=PATH3,PATH4
ACTIONHERO_CONFIG=PATH1,PATH2 npm start
Note that if --config or ACTIONHERO_CONFIG are used, they overwrite the use of the default /config folder. If you wish to use both, you need to re-specify "config", e.g. --config=config,local-config. Also, note that specifying multiple --config options on the command line does exactly the same thing as using one parameter with comma separators, however the environment variable method only supports the comma-delimited syntax.

Related

npm adds whitespace when setting env variable in package.json

I have a pre-written package.json file for an app which I need to modify. More specifically, I want to change the NODE_PORT environment variable through the package.json file and I'm working on a Windows machine.
In the package.json I have several scripts that I run through npm when I like to spin up an instance of the app.
For example:
set NODE_PORT=80&& set NODE_ENV=test&& pm2 install pm2-logrotate&& pm2 start app.js -i max -o ./logs/access.log -e ./logs/err.log --time --name Test
This script for example works fine.
However, when I'm trying to set the NODE_PORT variable to 8080 (that's the port I need) like so:
set NODE_PORT=8080&& set NODE_ENV=parallel_test&& pm2 install pm2-logrotate&& pm2 start app.js -i max -o ./logs/parallel_access.log -e ./logs/parallel_err.log --time --name Parallel_Test
a whitespace at the end of the variable gets added.
I verified this by printing out the number of chars of $process.env.NODE_PORT in the log file which prints 5. Moreover the login for the app via Google crashes as the redirect link of the app doesn't match with the one in the Google Cloud Platform. That is:
app: http://localhost:8080 /auth/check-google vs. Google Cloud Platform: http://localhost:8080/auth/check-google
Any idea why this is happening?
i have faced similar issue recently. Handled it with .trimEnd() while adding variables with dotenv. But I think using cross-env can solve your problems.
Most Windows command prompts will choke when you set environment
variables with NODE_ENV=production like that. (The exception is Bash
on Windows, which uses native Bash.) Similarly, there's a difference
in how windows and POSIX commands utilize environment variables. With
POSIX, you use: $ENV_VAR and on windows you use %ENV_VAR%.
Adding this inside your script: "cross-env NODE_PORT=8080 ..."

How do I set home folder in Heroku system variable?

I'm deploying a node.js app on Heroku dyno and using config module that requires me to define a system variable NODE_CONFIG_DIR with the location of the config folder.
The config folder is located on my project's root.
I tried to define the system variable NODE_CONFIG_DIR using the following values, all failed:
./config
~/config
app/config
~/app/config
./app/config
$HOME/config
$HOME/app/config
I keep getting this error:
WARNING: No configurations found in configuration directory:app/config
(replace app/config with any of the values above)
I manage to set a system variable, but its value is not pointing the right place.
What is the correct way to refer to the root of my tree when using a system variable in Heroku?
Based on documentation - if config folder is in the root of your application you should not need to specify $NODE_CONFIG_DIR env variable.
From node-config documentation:
Node-config reads configuration files in the './config' directory for the running process, typically the application root. This can be overridden by setting the $NODE_CONFIG_DIR environment variable to the directory containing your configuration files. It can also be set from node, before loading Node-config:
process.env["NODE_CONFIG_DIR"] = __dirname + "/configDir/";
const config = require("config");
$NODE_CONFIG_DIR can be a full path from your root directory, or a relative path from the process if the value begins with ./ or ../.
You could use above code to set it from your node code.
You were close: /app is the correct path. You can verify it by running heroku run bash.
It was my bad...
Both answers are correct but didn't solve my issue.
The problem was that I used lowercase for my configuration file name while the NODE_ENV value was uppercase.

Docker & PM2: String based CMD with environment variables

I'm currently using the shell-form of CMD in Docker for launching my node app:
CMD /usr/src/app/node_modules/.bin/trifid --config $TRIFID_CONFIG
The env-var TRIFID_CONFIGis set to a default in the Dockerfile:
ENV TRIFID_CONFIG config.customer.json
This makes it easy to pass another config file for dev-environments for example.
Now I try to switch this to PM2 for production. However it looks like all PM2 samples are using the "exec" form which from what I understood does not evaluate ENV-vars. I tried the shell-form with PM2:
CMD pm2-docker /usr/src/app/node_modules/trifid/server.js --config $TRIFID_CONFIG
But it looks like the variable is not evaluated like this, it fails back to default on execution.
What would be the proper way to handle this with PM2 inside a Docker image?
I had a discussion on Github and meanwhile figured it out:
CMD pm2-docker /usr/src/app/node_modules/.bin/trifid -- --config $TRIFID_CONFIG
So the trick is to use -- after the command and the rest will be passed as argument. If I use the shell form env-vars do seem to get evaluated properly.

How to reload/restart pm2 with flighplan and be aware of a symlink directory?

I am using flighplan to deploy my web service that built by Node.js
My deployment script uploads the new release to a new directory which has a timestamp or some random characters in its name. I am keeping all my releases in my server so I can rollback easily by just changing the link to any specific release and have zero-downtime deployment.
The main directory, named by the service name and it is just a symbolic link that get changed to the new release's directory after uploading it.
ln -snf ~/tmpDir ~/appName
My problem is when pm2 restars my server it uses the original path of the previous release, it doesn't bind with the symbolic link and follow the link to the new directory that the link is pointing to.
Is there any way to restart or reload pm2 and let it be aware of that symbolic link ?
Short answer - You should not run pm2 inside a symlink which changes.
pm2 would always pick the old path the symlink is pointing to unless you use pm2 kill command.
Solution - create a new directory and make it parent directory of smylink and your code directories (mohmal-144 etc.). For the sake of understanding lets call this deploy.
Now you should have below structure
/home/deploy
/home/deploy/mohmal -> home/deploy/mohmal-144.
If you are using pm2, yous should use ecosystem.json (pm2 config for starting apps) file. Though you can name this file to anything you want. For the sake of understanding, lets call this file ecosystem.json file.
Inside this ecossystem.json file, in the apps section, add the cwd directory and cwd should point to the path of the symlink(not the path to which symlink it pointing to). See below example.
{
"apps": [
{
"name": "mohmal",
"script": "src/bin/server.js",
"exec_mode": "cluster",
"instances" : "0",
"cwd": "/home/deploy/mohmal",
"error_file": "/var/log/mohmal/error.log",
"out_file" : "/var/log/mohmal/out.log",
"merge_logs": true
}
]
}
Place this file in the parent directory which is named deploy in this example.
Now run/use pm2 start, pm2 restart commands from this directory only.
If you are already running pm2 in the system, just once run pm2 kill to clear the old processes.
And then use the suggested changes, you would never have to pm2 kill the processes.
Also the changes to symlink would reflect.

Read command line arguments passed to node.js using pm2

I'm aware about how to pass variables to node.js using pm2. But how do I read them? process.argv doesn't contain it.
This is what I'm referring to.
Passing environment variables to node.js using pm2
UPDATE
pm2 start file_name.js -- -my_port 8080 is the right way to do it. process.argv will contain the arguments.
But running pm2 describe file_name still shows args -3000 which is a cached value.
Restarting the system gives me the argument that was passed last before restart, which was 3000 in my case.
I think you're confusing :
node_args
node_args list ["--harmony", "--max-stack-size=1024"] arguments given to node when it is launched
Those are node executable options, like --harmony or --debug=7001. For more informations see node --help
args
args list ["--enable-logs", "-n", "15"] arguments given to your app when it is launched
Those are your script arguments. In a json declaration it's the arg property but within command line the syntax is:
pm2 start app.js -- arg1 arg2
Those should be available in process.argv.
Reference
From the Node.js doc about process.argv:
An array containing the command line arguments.
It does not contain environment variables. You can access the ENV_VARIABLE environment variable using
process.env.ENV_VARIABLE
See this answer.

Resources