Openshift node app error when restarting - node.js

I have a node/socket.io chat app hosted on openshift, and while it starts correctly if i ssh into the server and do "node main.js" (where main.js is the server script that starts the chat), I can't start the app on the server by web interface, where it would go on automatically; If i just start the app by ssh, it would stop working as soon as i exit the terminal.
I get this error when starting the app by the web interface:
Starting Node.js application...
Application is already stopped.
Warning! Could not start Node.js application!
Failed to execute: 'control restart' for /var/lib/openshift/57003fbe7628e1491d00011e/nodejs
In case it's relevant, my package.json file is
{
"name": "rainychat",
"version": "1.0.0",
"description": "rainychat, my chat app",
"main": "main.js",
"dependencies": {
"express": "^4.13.4",
"socket.io": "^1.4.5",
"validator": "^5.1.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "JG",
"license": "ISC"
}
And here you can see the files of the app by ftp:
I can't decode what that error means...
My main.js code
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function (req, res) {
res.sendFile(__dirname + '/chat.html'); // /home/redadmin/public_html/rainychat.com
console.log('enviado');
});
app.set('port', process.env.OPENSHIFT_NODEJS_PORT || 8080);
app.set('ip', process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1');
http.listen(app.get('port'), app.get('ip'), function () {
console.log('Listening on port ' + app.get('port'));
});
//... More code

If you're creating a new Node project, start with npm init to create the package.json file. You can add the --auto option to give it safe defaults.
Remember, the JSON file must be valid JSON, so test it with jsonlint or a tool like an online validator.
Any dependencies your project has should be spelled out in the package file. This is done automatically with things like npm install express --save.

Related

Receive data on front-end React app from webhook

I am building a headless CMS with Strapi. I am testing the webhooks section and want to show the received data from the webhook on my React front-end.
I created a new folder webhooks on my local machine and ran npm init -y.
It created a package.json file with this content in it:
{
"name": "webhooks",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
}
}
I added a index.js file to the root folder with this content and installed express and body-parser:
const express = require("express")
const bodyParser = require("body-parser")
const app = express()
const PORT = 3001
app.use(bodyParser.json())
app.post("/webhook", (req, res) => {
console.log(req.body)
res.status(200).end()
})
app.listen(PORT, () => console.log(`🚀 Server running on port ${PORT}`))
After that I added this line in my package.json:
"start": "node index.js"
So it will start up with npm start instead of node index.js.
I added this URL to my strapi webhooks: http://localhost:3001/webhook and tested the trigger from the Strapi admin. It works fine.
After this I ran npx create-react-app client to create my react front-end app.
My next question is now how can I receive the contents from the webhook in my react front-end app?

How to deploy socket io & express server on heroku

I'm trying to deploy socket io + express server on heroku for a chat application but i am facing a trouble while deploying the server .
First this is my server code
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
users = [];
connections = [];
server.listen(process.env.PORT || 3000);
console.log('Server running...');
io.sockets.on('connection',function(socket){
connections.push(socket);
console.log('Connected %s sockets connected ', connections.length);
//Disconnect
socket.on('disconnect', function(data){
users.splice(users.indexOf(socket.username),1);
connections.splice(connections.indexOf(socket),1);
console.log('Disconneted : %s sockets connected',connections.length);
});
});
This is my package.json file
{
"name": "",
"version": "1.0.0",
"description": "chat application",
"main": "index.js",
"scripts": {
"start": "node index"
},
"author": "",
"license": "ISC",
"dependencies": {
"socket.io": "*",
"express": "*"
}
}
But I'm getting this error
Cannot GET /
Had the same problem (socket.io with express and react).
You can add to server this line:
app.use(express.static('some path to a static file'));
e.g.
app.use(express.static('client/build'))
works for me assuming in package.json has this line at "scripts":
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
This error has nothing wrong deployed application. Your app still waits for connection on port 3000 (or port from process.env.PORT). App responds "Cannot GET /" because you don't have any routes.
To see how routes can be implemented look at this -> https://expressjs.com/en/starter/hello-world.html
To see how connect using socket.io (client part) look at this -> https://socket.io/get-started/chat/#Integrating-Socket-IO

How to deploy node app on openshift and run it?

Just created a very simple hello world app using node:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
var server_port = process.env.OPENSHIFT_NODEJS_PORT || 8080
var server_ip_address = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1'
app.listen(server_port, server_ip_address, function () {
console.log( "Listening on " + server_ip_address + ", port " + server_port )
});
and it works as it is expected in my local machine,
put that on github and deployed it on openshift, pod created and server running fine:
but when I browse the route which I could find it in Application>>routes menu it says:
Application is not available
The application is currently not serving requests at this endpoint. It may not have been started or is still starting.
I guess I'm using the latest version of openshift since just created an account.
I'm expecting it to show me the Hello world!
update1:
here is my package.json:
{
"name": "npmtest",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.16.2"
}
}
Your application server IP address needs to be 0.0.0.0. So you either specify an environment variable for that, or hard code it.
have you configure main file in package.json
and maybe you need to get port dynamically from the environment variables check below link for openshift sample
https://github.com/openshift/nodejs-ex

Node.js host on OpenShift keeps "Service Temporarily Unavailable"

I am trying out to host a node.js project on Openshift, here is my package.json:
"scripts": {
"start": "node index.js"
},
"main": "index.js",
"dependencies": {
"express": "^4.13.3",
"formidable": "^1.0.17"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
...
and here is my index.js
var express = require('express');
var app = express();
var http = require('http');
app.set('port', process.env.OPENSHIFT_NODEJS_PORT || process.env.PORT || 8080);
app.set('ip', process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1");
app.get('/', function(req,res){
res.send("Hello World");
});
http.createServer(app).listen(app.get('port') ,app.get('ip'), function () {
console.log("✔ Express server listening at %s:%d ", app.get('ip'),app.get('port'));
server();
});
What am I missing and how can I successfully see the expected "Hello World" message? Thanks!
I don't see anything wrong with your could, and I bet “Service Temporarily Unavailable” means exactly that, in this case. Simply try again later after the scheduled maintenance.
Also, check the scheduled maintenances at http://status.openshift.com/ or #openshift_ops

502 Bad Gateway Deploying Express Generator Template on Elastic Beanstalk

I used the express generator to create a simple express app, which when started on dev works fine on localhost:3000.
When I push this to elastic beanstalk using the eb command-- git aws.push, however, I get a 502 error on the production server.
Looking into the logs, the error I get is:
2014/04/01 19:29:40 [error] 24204#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.2.178, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8081/", host: "macenvexp-env-hqv9ucmzev.elasticbeanstalk.com"
2014/04/01 19:29:40 [error] 24204#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.2.178, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:8081/favicon.ico", host: "macenvexp-env-hqv9ucmzev.elasticbeanstalk.com"
I'm using the default nginx configuration. When I run a node.js sample app without Express, it works fine. Here's the express code in app.js:
var express = require('express');
var http = require('http');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes');
var users = require('./routes/user');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
app.get('/', routes.index);
app.get('/users', users.list);
/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
And here's the package.json file:
{
"name": "macEnvExp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "DEBUG=macEnvExp node bin/www"
},
"dependencies": {
"express": "~3.4.8",
"static-favicon": "~1.0.0",
"morgan": "~1.0.0",
"cookie-parser": "~1.0.1",
"body-parser": "~1.0.0",
"debug": "~0.7.4",
"jade": "~1.3.0"
}
}
And here is bin/www:
#!/usr/bin/env node
var debug = require('debug')('my-application');
var app = require('../app');
app.configure(function(){
app.set('port', process.env.PORT || 3000);
});
console.log(app.get('port'));
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
For clarity, I'll state the answer from the comments.
AWS ELB runs node app.js BEFORE npm start. node app.js doesn't give an error, but it doesn't open any ports.
The solution is to simply rename app.js to anything else except server.js (ie main.js) and reference that in bin/www by pointing to it in the /bin/www file: var app = require('../app'); to var app = require('../main');
Then it should be working correctly!
For clarity, here is what my directory looks like:
The package.json file will get called by ELB when it launches the application server. Here it has the instruction to run the start script node bin/www
This is the bin/www file that gets run. We see the require to ../main and the app.set('port'...)
Then the main.js file that runs the routing and all:
When I created the project, the main.js file was named app.js. The problem this caused was based on the priority ELB start sequences. ELB will launch the application and check first to see if app.js exists -- if it does exist, it runs node app.js, otherwise it will check if package.json exists and try to run npm start.
When the main.js had the name app.js ELB tried to start the whole application by running it. However this file doesn't open any ports.
An alternative to renaming app.js is to create an elastic beanstalk configuration file. Add a .config file into the .ebextensions folder, for example, .ebextensions/34.config. Change the NodeCommand setting in the namespace aws:elasticbeanstalk:container:nodejs to whatever command you want to run to start the server. For example, this is a minimal .config file to run npm start instead of app.js:
option_settings:
- namespace: aws:elasticbeanstalk:container:nodejs
option_name: NodeCommand
value: "npm start"
See http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_nodejs_custom_container.html and http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options.html#command-options-nodejs for more information.
Edit:
An even easier way - using the AWS console, Configuration/Software has the "Node command" option - just set that to npm start.
Set running port to 8081
app.set('port', 8081);
Actually, there is another option.
At the Elastic Beanstalk console, inside your app-environment section, there is a Configuration menu item on your left side (right bellow Dashboard menu option). If you click there, you will find many configuration options. Click at Software Configuration and then define which is your node command. There explain the order of commands it tries indeed: "Command to start the Node.js application. If an empty string is specified, app.js is used, then server.js, then "npm start" in that order"
My mistake was at my start command script. It was starting nodemon:
"scripts": {
"start": "NODE_ENV=production && nodemon ./bin/www"
Then I changed to node and it worked:
"scripts": {
"start": "NODE_ENV=production && node ./bin/www"
Hope I helped someone.
If you use port 8081 for running your express app and use sudo for running node server, Your application will be accessed directly from elasticbean url without port numbers, otherwise it will display a 502 Gateway error from nginx.
Nginx proxying 8081 port by default for node app on elastibeanstalk.
Create file: .ebextensions/nodecommand.config and put the option settings below:
option_settings:
aws:elasticbeanstalk:container:nodejs:
NodeCommand: sudo pm2 start server.js (server command with sudo ie. sudo node /bin/www)
You can create another file for container commands: .ebextensions/01_init.config and put the desired commands which will be run before deployment. For example:
container_commands:
01_node_v6_install:
command: sudo curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
02_install_node:
command: sudo yum -y install nodejs
03_npm_install_gulp_webpack:
command: sudo npm install -g gulp webpack pm2
04_npm_install:
command: sudo npm install
05_webpack_run:
command: sudo webpack
In case anyone did the silly thing I did, make sure your bin folder is committed if you are using express. I had mine in my .gitignore file and this is why I was getting a 502 error.
Just remove /bin from .gitignore, commit, and the deploy changes to EB.
new to AWS and been a while since i webdeved, but was stuck tonight on same issue, and thanks to everyone in the thread, i am very happy to say that basic socket.io tutorial works now like a charm, i was just forgetting one line in package.json :
"scripts":
{
"start": "node app.js"
}
oh, and port !
the only thing i kept from elasticbean sample node.js app is this value instead of pure 3000 value :
var port = process.env.PORT || 3000;
Note: I ran into this issue and none of the solutions were working for me.
My solution was to make sure the devDependencies in package.json were actually in dependencies.
For example:
{
"name": "whaler-test",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"create-db": "cd dynamodb && node createDonorsTable.js && cd ..",
"delete-db": "cd dynamodb && node deleteDonorsTable.js && cd ..",
"load-data": "cd dynamodb && node loadDonorsData.js && cd ..",
"read-data": "cd dynamodb && node readDataTest.js && cd .."
},
"dependencies": {
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"express": "~4.16.0",
"http-errors": "~1.6.2",
"jade": "~1.11.0",
"morgan": "~1.9.0",
"nodemon": "1.17.5",
"cors": "2.8.4",
"aws-sdk": "^2.270.1"
}
}
Not:
{
"name": "whaler-test",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"create-db": "cd dynamodb && node createDonorsTable.js && cd ..",
"delete-db": "cd dynamodb && node deleteDonorsTable.js && cd ..",
"load-data": "cd dynamodb && node loadDonorsData.js && cd ..",
"read-data": "cd dynamodb && node readDataTest.js && cd .."
},
"dependencies": {
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"express": "~4.16.0",
"http-errors": "~1.6.2",
"jade": "~1.11.0",
"morgan": "~1.9.0",
"nodemon": "1.17.5"
},
devDependencies {
"cors": "2.8.4",
"aws-sdk": "^2.270.1"
}
}

Resources