14

As the title suggested, I've been playing around deploying apps with Amazons new OpsWorks management system, however I haven't been able to figure out how to get the node server to start running on the instance. From the ports the application layers have access too I assume I need be listening on port 80, however I feel that the problem is that the correct file isn't being started.

Similar to a Procfile on Heroku, is there a special start-script type file that needs to be included for OpsWorks to start it properly?

Note that I don't have experience with Chef yet, so I'm hoping to get it working with the default options, ie not writting a custom Chef recipe to do it.

Nick Mitchinson
  • 5,452
  • 1
  • 25
  • 31

5 Answers5

28

The amount of time I spent on this is embarrassing, but I will share anyway in hopes of saving other people the hours of their lives that would otherwise be stolen by Amazon.

  • To answer your question, yes, I did get my node/express application running.
  • In case you were using any kind of process.env method of choosing your port number, change your listening port to 80 (or 443 if appropriate).
  • Most importantly, Amazon doesn't care what your main file is. Rename it server.js and have it in the root directory of your application. That is the file that monit tries to run.

Hopefully that helps. If it doesn't, or if all of that is obvious, I apologize for my silliness and blame lack of sleep. :)

ZachRabbit
  • 5,144
  • 1
  • 23
  • 16
  • Haha ya I spent way to long on it as well. And yes the name of the file was the thing that I thought it was. Mine was app.js (what the basic express command generates) however I couldn't figure out what it had to be. – Nick Mitchinson Feb 21 '13 at 05:49
  • 3
    Furthermore: If you run your node app behind a HAProxy Layer, be sure that the health check (by default its a HTTP OPTIONS request) can be handled by express. I had to switch to a HEAD request method to make it work... – fbrandel Mar 10 '13 at 18:11
4

Great answer from ZachRabbit. I'd just like to add that OpsWorks now supports setting of environment variables (i.e. process.env.PORT) for the deployed application process.

When you Add App (or edit) you can go ahead and set up an environment variable with a key of PORT and a value of 80 if you're using something like the following in your server.js:

!/usr/bin/env node
var debug = require('debug')('my-app');
var app = require('app');

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
  debug('Express server listening on port ' + server.address().port);
});

More information on the setting of the environment variables can be found here:

http://docs.aws.amazon.com/opsworks/latest/userguide/apps-environment-vars.html

Ensuring that the filename was server.js and setting the environment variable PORT to 80 worked like a champ for me.

Timothy Johns
  • 1,075
  • 7
  • 17
1

Just copying the AWS OpsWorks page for configuring the node.js app:

"By default we expect your Node.js app to listen on port 80. Furthermore, the file we pass to node has to be named "server.js" and should be located in your app's root directory."

Regards.

Carlos Ballock
  • 145
  • 1
  • 3
0

I played around this for a bit as well and hopefully my path to success will help someone. Node.js usually needs elevated privileges to run on port 80 so I discovered that while naming the sample app app.js was fine, you need to modify line 2 of the default OpsWorks Node.js deploy chef recipe to use sudo:

  • Node does need elevated permissions to run on port 80 as its a reserved port, however OpsWorks seems to run everything as the root user for the instance. Typically this is really bad, as a security problem could then lead to malicious code being executed as root (think Rails...). However because EC2 instances are kinda just fancy VMs, running as root cant have any effect outside of the instance anyways. – Nick Mitchinson Feb 21 '13 at 18:31
  • Also how would running as sudo let the filename be app.js instead of server.js? – Nick Mitchinson Feb 21 '13 at 18:34
  • Right so from my experience, the default Node.js layer for OpsWorks is not looking specifically for server.js, hence it working with an app.js filename. And yes any application needs root access to run on ports below 1024 which is why without using sudo, I was not able to get the app to launch automatically with the OpsWorks recipes. – Justin Lewis Feb 21 '13 at 20:11
  • Mhmm that weird cause your experience seems to directly conflict mine. I was able to listen on port 80 without modifying the defaults (as I said, EC2 instances will run those as root, thus not needing sudo). However I was unable to get anything started before I changed the filename to server.js. – Nick Mitchinson Feb 21 '13 at 21:11
  • My experience was similar to Nick's. The only thing I can think of is there might be a difference between the Ubuntu and Amazon Linux installs. Which OS were both of you using? I had chosen Ubuntu. – ZachRabbit Feb 21 '13 at 22:05
  • I used Amazon Linux, however that would not affect these differences as the same recipes are used on both installations. – Nick Mitchinson Feb 21 '13 at 23:30
0

A bit off topic maybe, but I spent a couple of hours on this so I figured it's worth sharing:

When setting up a Hapi.js server on OpsWorks, I had to ensure that I didn't use hostname localhost, but instead set it to 0.0.0.0. Otherwise it just kept failing silently.

Hope that helps anyone.

Kristofer Sommestad
  • 3,061
  • 27
  • 39