3

Disclaimer: I'm a node.js/grunt/bower newbie.

I have a node.js/grunt/bower application that I'm trying to deploy on Heroku. Heroku builds the application as expected, but then it tries to run "npm start" which I did not specify in the package.json file. This command fails, I'm guessing because it is not a server application, and I can not see the actual application deployed in it's place on Heroku. My application can be found here: https://github.com/uzilan/sufusku

So - how do I get Heroku not to run the "npm start" command, and what should it run instead? After running grunt build, the application is available on the dist folder.

package.json:

{
    "name": "sufusku",
    "version": "0.0.1",
    "description": "Sufusku - makes your annoying sudoku easier",
    "repository": {
        "type": "git",
        "url": "git://github.com/uzilan/sufusku.git"
    },
    "license": "(MIT OR Apache-2.0)",
    "dependencies": {
        "bower": "^1.4.1",
        "grunt": "0.4.5",
        "grunt-cli": "0.1.13",
        "grunt-contrib-clean": "^0.6.0",
        "grunt-contrib-concat": "^0.5.1",
        "grunt-contrib-connect": "^0.11.2",
        "grunt-contrib-copy": "^0.8.0",
        "grunt-contrib-cssmin": "^0.13.0",
        "grunt-contrib-htmlmin": "^0.4.0",
        "grunt-contrib-uglify": "^0.9.1",
        "grunt-contrib-watch": "^0.6.1",
        "grunt-ng-annotate": "^1.0.1",
        "load-grunt-config": "^0.17.2",
        "time-grunt": "^1.2.1"
    },
    "devDependencies": {},
    "engines": {
        "node": ">=0.8.0"
    },
    "scripts": {
        "postinstall": "./node_modules/bower/bin/bower install && grunt build"
    }
}

Gruntfile.js:

module.exports = function (grunt) {
    var appname = require('./package.json').name;

    require('load-grunt-config')(grunt, {

        data: {
            dist: 'dist/' + appname,
            app: 'src',
            distscripts: 'dist/' + appname + '/scripts',
            diststyles: 'dist/' + appname + '/styles',
            disthtml: 'dist/' + appname,
            disttest: 'dist/' + appname + '/test',
            appstyles: 'src/css'
        }
    });

    require('time-grunt')(grunt);

    grunt.registerTask('build', ['clean:dist', 'ngAnnotate:application', 'uglify', 'htmlmin', 'cssmin', 'copy:serve', 'concat:components']);

    grunt.registerTask('serve', ['build', 'connect:livereload', 'watch']);

    grunt.registerTask('default', function () {
        grunt.task.run(['build']);
    });
};

Heroku log:

...
heroku[web.1]: Starting process with command `npm start`
app[web.1]: npm ERR! argv "/app/.heroku/node/bin/node" "/app/.heroku/node/bin/npm" "start"
app[web.1]: npm ERR! Linux 3.13.0-57-generic
app[web.1]: npm ERR! npm  v2.11.3
app[web.1]: npm ERR! missing script: start
app[web.1]: npm ERR! Please include the following file with any support request: 
app[web.1]: npm ERR! 
app[web.1]: npm ERR! node v0.12.7
app[web.1]: 
app[web.1]: npm ERR!     /app/npm-debug.log
app[web.1]: npm ERR! If you need help, you may report this error at:
app[web.1]: 
app[web.1]: npm ERR!     <https://github.com/npm/npm/issues>
heroku[web.1]: Process exited with status 1
heroku[web.1]: State changed from starting to crashed
heroku[web.1]: State changed from crashed to starting
heroku[web.1]: Starting process with command `npm start`
app[web.1]: npm ERR! Linux 3.13.0-57-generic
app[web.1]: npm ERR! node v0.12.7
app[web.1]: 
app[web.1]: npm ERR! missing script: start
...
uzilan
  • 2,554
  • 2
  • 31
  • 46

2 Answers2

21

npm start is the default web process run when no other process has been specified in a Procfile. Since you say you don't want a server (a web process), the first thing to do is to scale the default process to zero:

heroku scale web=0

Next, you'll want to tell Heroku what process you want to run instead of web by adding its process types to a file called Procfile. For instance, if your app starts with node foobar.js, you could create a Procfile that looks like:

bot: node foobar.js

Then scale the 'bot' process up to at least one:

heroku scale bot=1

Looking at your code above, even though you say it isn't a server-based application, it looks very much like a server-based application. How do you start your app locally? Whatever the answer that should probably go into the Procfile, which you can learn more about here:

disclosure: I'm the Node.js platform owner at Heroku

hunterloftis
  • 13,386
  • 5
  • 48
  • 50
  • Well I do not create any server in my application, it's just a client-side angular application with no back-end. Locally, I'm starting the application using the command grunt serve, which starts a web server on port 9000 and starts a browser pointing to the localhost:9000 adress, but I guess I can't run this in Heroku. What should I run instead? – uzilan Aug 23 '15 at 19:17
  • I also found this: https://medium.com/@3runjo/how-to-deploy-a-grunt-project-on-heroku-c227cb1ddc56 which claims I need a nodejs-grunt buildpack. Do you think it is necessary? – uzilan Aug 23 '15 at 19:19
  • 1
    If you want to serve your client-side application, you'll need a server. There's a tutorial on using grunt with heroku here: https://devcenter.heroku.com/articles/node-with-grunt – hunterloftis Aug 23 '15 at 23:47
  • Thanks for your help. I looked at the tutorial and combined it with the solution found in here: http://stackoverflow.com/questions/26079611/node-js-typeerror-path-must-be-absolute-or-specify-root-to-res-sendfile-failed – uzilan Aug 24 '15 at 21:28
  • I have `heroku scake web=0` in my Procfile but it still tries to launch and crash every few hours. How can I completely disable this? I have a post here on it http://stackoverflow.com/questions/32850885/heroku-prevent-starting. Thanks – cyberwombat Oct 10 '15 at 17:09
  • [Would you mind taking a shot at answering this question please and thank you?](https://stackoverflow.com/q/59709604/1640892) It's hard to find Heroku Node.js experts. – Let Me Tink About It Jan 13 '20 at 03:11
  • I had to add `web: yarn start` in my Procfile since `npm start` was crashing – Chris Claude Dec 14 '21 at 15:37
-7

Thanks for the answer. After trying the tutorial mentioned above and looking at the solutions in node.js TypeError: path must be absolute or specify root to res.sendFile [failed to parse JSON] I ended up writing a server.js file which solved the problem. And it looks like this:

var express = require('express');
var app = express();

app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
});

app.get(/^(.+)$/, function (req, res) {
    res.sendFile(__dirname + req.params[0]);
});

var PORT = process.env.PORT || 3000;

app.listen(PORT);
Community
  • 1
  • 1
uzilan
  • 2,554
  • 2
  • 31
  • 46
  • 5
    you wrongly applied the right answer to yourself - It should belong to @hunterloftis based on addressing your request - use a procfile to specify which service to run on a given dyno during spinup – Frankenmint Mar 18 '17 at 08:03