I normally run my app with the following command on a test server:
ts-node --type-check -r tsconfig-paths/register src/server.ts
Now I want to use pm2 to go into production, but when I run:
pm2 start src/server.ts
It errors out because it can't find the paths properly, because the tsconfig-paths is not loaded.
How can I configure pm2 to run ts-node with those parameters?
+1
How about trying pm2 start ts-node -- --type-check -r tsconfig-paths/register src/server.ts?
Pm2 is able to launch a normal bin (or says, a command) with arguments (--type-check -r tsconfig-paths/register src/server.ts) after the first -- feeding to your bin (i.e. in this case, ts-node).
I am using pm2 start ts-node -- -P tsconfig.server.json ./server/index.ts
incidentally for those using ecosystem:
{
"script": "ts-node", // or locally "./node_modules/.bin/_ts-node"
"args": "src/main.ts"
}
Hello all
I am having the same issue where pm2 cannot find the modules from tsconfig.json paths and trying to figure out how to run it with pm2 inside docker container.
My docker file(only the relevant part)
RUN "pm2 install pm2-logrotate && pm2 set pm2-logrotate:compress true && pm2 set pm2-logrotate:retain 2 && pm2 install typescript"
cmd "pm2-docker","start","pm2.json"
pm2.json
{
"apps": [
{
"name": "app-name",
"script": "start.ts",
"watch": true,
"ignore_watch":["uploads","downloads"],
"instances": "2",
"exec_mode": "cluster",
"env": {
"production": true
}
}
]
}
I even tried the below commands but both of them failed to find the modules and do not know how to the add the ts-node args to the pm2.json file
pm2 start ts-node -- -r ../node_modules/tsconfig-paths/register ./start.ts
pm2-docker start ts-node -- -r ../node_modules/tsconfig-paths/register ./start.ts
Please advise
Let me answer my own question,
I was able to run the app by modifying the pm2.json as below. Now my only concern is the path to ts-node as I want to use the same version pm2 uses instead of installing it globally.
{
"apps": [
{
"name": "app-name",
"script": "/usr/local/lib/node_modules/pm2/node_modules/.bin/ts-node",
"args":"-r ../node_modules/tsconfig-paths/register ./start.ts",
"watch": true,
"ignore_watch":["uploads","downloads"],
"instances": "4",
"exec_mode": "cluster",
"env": {
"production": true
}
}
]
}
@saachinsiva Did that pm2.json work for you?
I also use pm2 with docker and the ecosystem.js file, but I cannot get it to work... My dockerfile looks as follows:
FROM keymetrics/pm2:latest-alpine
COPY . .
RUN npm install --silent
RUN pm2 install typescript --silent
EXPOSE 8080
CMD ["pm2-runtime", "start", "ecosystem.config.js"]
and my ecosystem looks like yours:
module.exports = {
apps: [
{
wait_ready: true,
script: '/usr/local/lib/node_modules/pm2/node_modules/.bin/ts-node',
args: '-r node_modules/tsconfig-paths/register ./src/app.ts',
watch: true,
name: 'dev-API',
NODE_ENV: 'development',
PORT: 8080,
},
],
};
But when run it, I get the following error:
TypeError: Option requires argument (but was followed by another short argument): -r
If I just use ts-node, without the long pm2 path /usr/local/lib/node_modules/pm2/node_modules/.bin/ts-node , then I get this error
PM2 error: 0 application started (no apps to run on ecosystem.config.js)
I have been trying all kinds of combinations, but I just can't get it to work, so all help is greatly appreciated!
Okay, so I think I solved it... My ecosystem.js has some conditionals depending on production or development, so my args object was inside an env_development object. When this is the case, it seems the arguments are passed wrongly or too late... Moving the args object out and toggling it like
{
script: production ? './dist/app.js' : '/usr/local/lib/node_modules/pm2/node_modules/.bin/ts-node',
args: production ? '' : '-r tsconfig-paths/register ./src/app.ts',
}
fixed it for me
My pm2.json is
{
"apps": [
{
"name": "poker-static-service",
"script": "./node_modules/.bin/ts-node",
"args":"-r ./node_modules/tsconfig-paths/register ./src/main.ts",
"ignore_watch":["uploads","downloads","www"],
"instances": "1",
"max_memory_restart" : "1024M",
"exec_mode": "cluster",
"error_file": "/var/log/unblockcn-server-err.log",
"out_file": "/var/log/unblockcn-server-out.log",
"merge_logs": true,
"env": {
"production": true
}
}
]
}
but wo got the error:
7|poker-st | C:UsersAdministratorDesktopCompony Projectstatistic_servicenode_modules.bints-node:2
7|poker-st | basedir=$(dirname "$(echo "$0" | sed -e 's,\,/,g')")
7|poker-st | ^^^^^^^
7|poker-st |
7|poker-st | SyntaxError: missing ) after argument list
7|poker-st | at new Script (vm.js:80:7)
7|poker-st | at createScript (vm.js:274:10)
7|poker-st | at Object.runInThisContext (vm.js:326:10)
7|poker-st | at Module._compile (internal/modules/cjs/loader.js:664:28)
7|poker-st | at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
7|poker-st | at Module.load (internal/modules/cjs/loader.js:600:32)
7|poker-st | at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
7|poker-st | at Function.Module._load (internal/modules/cjs/loader.js:531:3)
7|poker-st | at C:UsersAdministratorAppDataRoamingnpmnode_modulespm2libProcessContainer.js:295:23
7|poker-st | at C:UsersAdministratorAppDataRoamingnpmnode_modulespm2node_modulesasyncinternalonce.js:12:16
who can help me ,thanks!
In my case, the following config works with cluster mode:
module.exports = {
apps: [
{
script: 'node_modules/.bin/ts-node',
args: '-T -r tsconfig-paths/register ./api/index.ts',
instances: 3,
exec_mode: 'cluster',
// ...
The key is to use node_modules/.bin/ts-node instead of node_modules/.bin/ts-node -T -r .... Thank you @mantissa7 !
You can use the interpreter option, here is an example in yaml format
apps:
- name: 'app'
script: './src/index.ts'
watch: ['src']
ignore_watch: ['node_modules', 'src/sequelize']
interpreter: 'node_modules/.bin/ts-node'
node_args: ['--require=tsconfig-paths/register']
env:
NODE_ENV: development
seems like interpreter and interpreter_args properties in ecosystem file doesnt work for ts-node...
this worked instead:
module.exports = {
apps: [
// Nuxt
{
name: 'nuxt',
script: './node_modules/.bin/ts-node',
args: '-P ./tsconfig.node.json ./nuxt/run.ts'
cwd: __dirname,
...
However --no-daemon parameter doesnt work with above;
cross-env NODE_ENV=production pm2 --no-daemon start ./pm2.config.js
I need to run pm2 in foreground as everything in production is containerized and want to log in stdout..
Anyone got better workarounds...?
Nothing of the previously mentioned worked for me, but I found another workaround, it seems to be the best in terms of clean code.
You create a ts-hook.js containing
require("ts-node").register({
project: "tsconfig.api.json",
// You can add any ts-node arguments, even from environment variables if you require dotenv/register before
});
then in your ecosystem.config.js
module.exports = {
apps: [
{
name: "API",
script: "api/index.ts",
interpreter: "node",
interpreter_args: [
"-r",
"dotenv/config",
"-r",
"./ts-hook.js",
"-r",
"tsconfig-paths/register",
],
...
}
]
...
}
The YAML version something like this
apps:
- name: API
script: api/index.ts
interpreter: node
interpreter_args:
- -r
- ./ts-hook.js
- -r
- tsconfig-paths/register
- -r
- dotenv/config
...
PS: I was having serious trouble with keeping this working on cluster mode, the only way to get it working is locking ts-node to @7.0.1
https://github.com/Unitech/pm2/issues/4142
PS2: nevermind, settings ts-node to 7.0.1 doesn't work, it seems to be a deeper problem with ts-node in cluster mode, when a file is already transpiled it tries to transpile it again, and then it just dies https://github.com/TypeStrong/ts-node/issues/883. My final solution is to compile the typescript and run it just as Javascript
It's very simple guys.
Just use tsc and pm2 watch combination with single & to run both commands.
"scripts": {
"serve": "tsc src/app.ts -w & pm2 start dist/app.js --watch"
},
for user using custom register + inspect debugger in vscode
NODE_ENV=development pm2-dev start node -- -r ./tsRegister.js --inspect-brk=9221 ./src/index.ts
I tried @momocow solution, and it works for me. Here's the command I used.
pm2 start ts-node -- -r tsconfig-paths/register --files bin/www.ts
Basically ecosystem "script" field should be inserted executable file path. So ts-node should be located to 'interpreter', and args should be in interpreter_args or node_args too.
here is my eco system config:
{
"apps": [
{
"name": "ts-node-app",
"script" : "src/server.ts",
"exec_mode": "fork",
"env": {
"NODE_ENV": "local"
},
"interpreter" : "./node_modules/.bin/ts-node",
"interpreter_args": "-P ./tsconfig.json -r ts-node/register/transpile-only -r tsconfig-paths/register"
}
]
}
module.exports = {
apps: [
{
name: 'backend',
script: 'src/index.ts',
exec_mode: 'fork',
cwd: './backend',
interpreter: 'node',
interpreter_args: '--require ts-node/register --require tsconfig-paths/register'
}
]
}
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
module.exports = { apps: [ { name: 'backend', script: 'src/index.ts', exec_mode: 'fork', cwd: './backend', interpreter: 'node', interpreter_args: '--require ts-node/register --require tsconfig-paths/register' } ] }
this one really works for me on system windows 10
module.exports = { apps: [ { name: 'backend', script: 'src/index.ts', exec_mode: 'fork', cwd: './backend', interpreter: 'node', interpreter_args: '--require ts-node/register --require tsconfig-paths/register' } ] }
this one really works for me on system windows 10
it really works for me on win 10 platform
Most helpful comment
I am using
pm2 start ts-node -- -P tsconfig.server.json ./server/index.ts