icflorescu / openshift-cartridge-nodejs

Custom cartridge for OpenShift providing the lastest version of Node.js.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

use npm to start application

GochoMugo opened this issue · comments

As noted in the Readme:

The cartridge emulates the execution of npm start to start your application, so make sure your application
entrypoint is defined in your start script of your package.json file. See package.json in the provided
template or read the npm docs for more information.

Some advantages of using npm directly would include:

  • automatically add node_modules/.bin to $PATH:

In addition to the shell's pre-existing PATH, npm run adds node_modules/.bin to the PATH provided to
scripts. Any binaries provided by locally-installed dependencies can be used without the
node_modules/.bin prefix.

https://docs.npmjs.com/cli/run-script

With the assumption that this emulation was meant to be similar to the actual npm start, the start command (in bin/control#L6),

START_COMMAND=$(node -e "var p = require('$OPENSHIFT_REPO_DIR/package.json'); console.log(p.scripts.start);")

could be enhanced to run npm:

START_COMMAND="npm start"

Since this command will be executed in the repository's working directory, we can be sure it will find a package.json to look for the scripts in.

Side note:

  • I noticed this when I tried to run forever app.js, but the application crashed as the forever command could not be found ($PATH did not include node_modules/.bin)

Thanks for taking the time to look into this!

Actually we've had a brief "adventure" trying to use npm start a few months ago, see #7, #10 and #11.

As far as I remember, there were 2 main problems:

  • We also need to be able to properly stop/restart the app, and I remember @AlexChesters bumped into and issue (see #10);
  • The additional process is taking up memory during the entire application life-cycle. While ~30MB is definitely not an issue on a development machine, the amount of memory we can use in the application cartridge is limited. But the benefits may outweigh the costs, I guess we'll just have to test and see how it behaves.

I think we might be able to make it work in the end, so I'll spin up a test app and run some tests when I find the time, hopefully over the next couple of days.

Meanwhile, any feedback/help is, of course, appreciated! :-)

On the issue of properly start/stop/restart control of the application, I would suggest saving the process ID (PID) of the process in a (PID) file that we can use to query its status. Since it might be safe to assume that the actual process started by the control script in the cartridge is that of a process manager such as supervisord, forever, nohup, etc., the PID would not change even when the managed application process crashes and is restarted. All we would have is the PID of the process manager (which obviously (?), is the parent of any application processes it manages). I do not clearly know how this would affect scaling with gears, we would require more research into that.

The other issue of npm hogging memory is daunting. First, npm does eat up valuable memory (on my machine, when my node_modules/ gets larger in size, npm gets so slow and heavy, I end up using nice). But I see most PaaS using npm start for starting their applications. While this is no validation that it is the correct way to do it, it would be our best interest to understand how they handle the memory issue.

I guess PaaS are generally defaulting to npm start for convenience, not efficiency. For instance,Heroku does it only if a Procfile is not present in the root of your application.

"It would be our best interest to understand how they handle the memory issue" - I suspect they don't, but you can always buy more gears ;-)

I never considered the fact that the amount of memory taken by npm start is directly related to the size of node_modules, but now that you mentioned, it makes total sense.

That being said, maybe we consider adding node_modules/.bin to $PATHon cartridge install instead of using npm start to start the application.

What do you think?

I have actually started reading through the npm source code, noting the setup functions it goes through when running scripts. Mostly cause I'm not very sure how the size affects the process so much!

I have always thought Heroku have their shit together, better than these other PaaS. But I guess building great s/w is quite hard, you know!

While modifying $PATH would certainly solve my primary issue (in this thread), this same issue would crop up later should we realize that npm start does more! We will end up re-implementing the functionality all over again (and am a lazy coder!!!).

But we could modify $PATH and clearly state in the README that we are not using npm start. A link to this discussion would help pull more people into it and hear different perspectives.

Just added node_modules/.bin to $PATH in this commit and a link to this discussion in the README as suggested. You should now be able to things like forever app.js in your package.json scripts without having to prefix them with node_modules/.bin. Unfortunately you'll have to redeploy your application, since custom cartridges can't autoupdate.

I'm going to close the issue for now, but we can always reopen it if necessary.

Thanks again for your feedback and support.

Nice job! Hoping to improve this catridge in the future. 👍

Can we also include these predefined scripts?

https://docs.npmjs.com/misc/scripts#description

pretest, test, posttest: Run by the npm test command.
prestop, stop, poststop: Run by the npm stop command.
prestart, start, poststart: Run by the npm start command.
prerestart, restart, postrestart: Run by the npm restart command.

@Qusic - won't have time to look at this and do proper implementation and tests until the next week.
Feel free to try your hand if you have time - you'll probably want to look at bin/control.
I can imagine when you'd like to call pre/post stop, start & restart, but I have no idea where - in terms of OpneShift-specific commands - to call pre/post test.

So @Qusic kinda saw the future for me. I needed to make it support stop (see #57). The **pre** and **post** scripts will have to be invoked immediately before and after the corresponding scripts.

@Qusic Did you get to work on this?

This has been really daunting for me, as i have a prestart script setup to build my databases and tables automatically. But to my wildest suprise npm start. Never get called according to you guys, whats the roadmap from here? ... Are you implementing it at a later time or what are the other best practices?

Until we are able to implement the pre and post scripts, you may want to use an action hook, in particular .openshift/action_hooks/pre_start.