Heroku applications and building process - node.js

I have just one question:
Why when you push to heroku, it do same all tasks to execute app?
For example I just modified one file index.js, ok, I need to git add index.js, git commit -am "Message" and heroku push origin master, but when I'm pushing to heroku, it pushing one file but do a lot of unnecessary things like
Again installing Node
Again installing dependencies (node modules), there are the same but heroku again download all dependencies
Again build cache of node modules
Why Heroku can't analyze package.json and do not install again new modules? Why it installs again Node if in Procfile I have the same web: npm run server? These actions are eating a lot of time and resources, I'm don't understand that.

you can create a ci/cd pipeline and deploy directly from your github page

Related

deploying Node on heroku error after build successful

i have been trying to deploy a node.js app on heroku. the app run successfully on local machine and it build successful with git heroku push master. but when try to open the app on heroku, it shows a blank page and on the console i got the bellow error.
so i my app i uses owlcarousel, and react -carousel. thanks
Try running it locally with NODE_ENV=production node index.js to see if you can reproduce the error like that. Check the .gitignore to see if you are not leaving out some important files. Check the package.json If a module that is included in the package.json is missing from the build or the production app, it may have been removed by Heroku during pruning. And also, in order to create a smaller slug size for apps, the buildpack will prune out the devDependencies from the package.json at the end of the build, so that the slug will only include the dependencies that are listed at runtime. If there is a dependency that is in the devDependencies that is needed after the prune occurs, move the dependency to dependencies, so it is not removed. Look here for more info, troubleshooting Node.js deployment on Heroku.

How to install and deploy node.js application?

I'm new to node.js. After creating modularized project with express, tests, .nvmrc etc. it's finally time to deploy the app. How it should be done? in java you bundle your project into a single file, self containing and you put in into a server with some configuration. what about node.js?
Should i just copy the whole directory with sources and node_modules to production machine and use systemd, pm2 or other process manager to just run it? but i heard some of the dependencies might be system-dependend so they may work incorrectly
or should i copy only sources and run npm install --production on the production machine? but this way the deployment is only possible when npm repositories are online. also it takes time to build the application and it has to be done on all machines in the cluster. also what about quickly rolling back to previous version in case there is some bug? again, time and online npm repos are needed
another option is to build a docker image. but it seems awkward that the only way to easily and safely deploy the app is using third party technology
how it's being done in real life scenarios?
sure don't copy the whole directory especially node_modules.
all the packages installed on your system should be installed with --save option example: npm install --save express if you do so you will have in your package.json the dependencies required for your project whether they are dev dependencies or production dependencies.
I don't know what your project structure looks like, but as a node application you have to run npm init . in your project to setup the package.json file and then you can start adding your dependencies with --save.
usually we use git
version control system
to deploy to the server, first we push our code to a git repository then we pull from it to the server git
you have to add .gitignore in your project and ignore node_modules from being committed to your git repository.
then you can pull to your server and run npm install on the server. and sure you need to launch your web server to serve your application example ngnix
you can try Heroku for an easy deployment, all you have to do is to setup your project with Heroku, and when you push your code, Heroku manages the deployment . Heroku

How to compile Bootstrap from source as part of build process on heroku?

I am building a simple node app and using Bootstrap to style my frontend. I want to deploy the app to Heroku by loading it from the GitHub repository. I don't want to put any compiled CSS/JS files in the repository, which means that they need to be compiled on Heroku after the source is pulled from GitHub.
The problem: Bootstrap's default package.json has its build dependencies in devDependencies, so the dependencies will not be installed on Heroku, which runs npm install in production mode.
Specifically, the problem comes up in my postinstall script, which consists of cd node_modules/bootstrap && npm install && ../.bin/grunt dist. My own npm install command does not end up installing anything because the overarching npm install --production is ignoring Bootstrap's devDependencies.
What is the best workaround to get Bootstrap's dependencies to be installed locally? I'm open to changing my workflow as long as (1) I don't have to put compiled files in my source repository and (2) I can still run the main npm install in production mode.
EDIT: Unless someone can think of a better solution, I think my options at this point are as follows:
Build a custom Github fork of Bootstrap that has its dependencies in dependencies instead of devDependencies
Build a custom Heroku buildpack that somehow leaves Bootstrap's dependencies intact
Abandon principle and compile Bootstrap locally, and put the compiled files in my source
Just use Heroku in development mode (obviously not a good idea)
I think I'm going to try for option 1, and go for option 3 if that fails. I'd still be interested in hearing any other ideas that people come up with.
I would look into using postinstall. The official documentation is on Heroku here.
Since you're doing some build steps at deploy time, you need some devDependencies (bootstrap sources in your case), but heroku will only install in production mode, like you said.
When connected with the heroku toolbelt client, run :
heroku config:set NPM_CONFIG_PRODUCTION=false
You'll have your devDependencies and you'll be able to build.
You only have to do that once (no need to do that each time you deploy).
PS: I don't know about your project, but maybe you need to put the NODE_ENV to production, here is the command:
heroku config:set NODE_ENV=production
You don't need yo put back the NPM_CONFIG_PRODUCTION flag back to true, this is the purpose of making the build on heroku.
But if you prefer, here is the workflow you could use (you said you were opened to change workflow):
ignore dist folder from your source repo (it should already be ignored)
make dist folder a git repo & add the git remote of heroku in repo of the dist folder
cd dist
git init
git remote add origin git#heroku.com:project-name.git
git pull origin master
make sure your build routine doesn't remove this /dist/.git folder - you can use the following glob (if you're using rimraf or something like it with grunt/gulp or whatever) : ['/dist/**/*','/dist/!.git/**/*']
This way, your workflow will be:
build (with your tool)
cd dist
git add .
git commit -m "new version bundled"
git push origin master there, you are in dist folder where origin is the remote for your heroku
You might do the same kind of things with github pages ...

Local or Private NPM module when deploying to Heroku

I have a node app that has a local npm module npm link ./local and I'm trying to deploy the app to heroku. Heroku runs npm install when I deploy, but npm link's aren't saved in package.json so my local module is missing.
I'm new to heroku and Procfiles, I'd like to run a script or just run npm link ./local before on the heroku box.
Alternatively I could put the module on github as a private repository and link it from there. But as far as I know Heroku isn't able to download private repo. Can I give Heroku access to my github repository via keys so that it could download it?
I'd love for somekind of solution! Anything!
I think you need yo put modules in node_modules folder and push that to heroku
Procfiles are easy to maintain and heroku will read that
I have sample Procfile like
web: bin/hubot -a campfire
Even heroku also says that best is to include node_modules into repo so you can just include your local packages into that.
See more here Heroku Node Deploy

How to deploy node app that uses grunt to heroku

I'm using grunt and also grunt plugins like grunt-contrib-copy, grunt-contrib-mincss (that listed as npm dependencies for my application).
Also I don't commit npm_modules folder and public folder, where all generated files are. And I can't figure out how to build my app (I have grunt build command) after deploy and setup my server (it's already looking for public folder).
I saw some stuff like grunt-heroku-deploy, but it seems me a bad idea to commit before upload. Maybe there are some gentle decisions... Any thoughts?
npm has a support for a postinstall step (among many others) that might be just what you're looking for.
The node.js heroku buildpack runs this command when you push to heroku to resolve build dependencies:
$ npm install --production
https://devcenter.heroku.com/articles/nodejs-support#build-behavior
If you take a look at the npm documentation, you can setup a series of scripts to run either before or after anyone runs npm install for your package. It's configured in the scripts property of package.json. The scripts property allows to run custom scripts (including grunt) when certain things happen in a package's lifecycle.
For example, to echo some text and run the grunt command whenever anyone (including Heroku) runs npm install, add this to your package.json:
{
...
"scripts": {
"postinstall": "echo postinstall time; ./node_modules/grunt-cli/bin/grunt <your task name>"
},
...
}
https://npmjs.org/doc/scripts.html
Important caveats:
You might have to change the path to the grunt binary in the postinstall script, check the error output if the grunt command doesn't execute.
grunt and grunt-cli must be listed as a dependency in your package.json so it gets installed by Heroku. Listing them under devDependencies is not sufficient since Heroku won't install those. Also, note that Heroku won't install it as a global package so to execute it on Heroku you're going to have to use a relative path (as it is configured above).
If this doesn't work (you'll probably need to fiddle with the relative paths a bit), then you might want to consider writing your own custom buildpack for Heroku.
Update
As of 0.4, the grunt package no longer contains the grunt binary, which is now part of the grunt-cli package. The answer has been updated to reflect this.
This looks like it will largely be solved when the Heroku Platorm API slug and release features make it into the mainline. At that point, you can build your code locally (or on a ci server), package it up and send it to heroku via an API call and release it from there.
This is still in the beta period and was only announced on December 19, 2013.
https://devcenter.heroku.com/articles/platform-api-deploying-slugs
I was never super happy with how many people seemed ok with checking in your generated code into git or the NPM postinstall hook. :(
Plus from a philosophical stance, doing a build during a release is simply another potential failure point.
Just for fun: Since that's not finalized yet, here's a bash script I threw together you can use for the time being to build your code on a deployment branch, commit it, deploy it to heroku and then remove the deployment branch. (I really am not a fan of bash deployment scripts, so I'm really looking forward to the platform API additions)
#!/bin/bash
set -e
# Delete current deploy branch
git branch -D deploy
# Create new deploy branch based on master
git checkout -b deploy
# Grunt comands to build our site
grunt build:production
# the dist/ directory is in my .gitignore, so forcibly add it
git add -f dist/
git commit -m "Deploying to Heroku"
# Push it up to heroku, the -f ensures that heroku won't complain
git push heroku -f deploy:master
# Switch it back to master
git checkout master
Grunt (et al.) is a build tool, not (really) something you should be packaging up and running on production. A different approach would be to use Grunt to prepare your project locally (or better on a CI server) before only pushing the built files to Heroku. As already mentioned Heroku will do an npm install on your app after its pushed which should be enough on its own to finally prepare your app.
I have it set up so that the Grunt derived/built Heroku app lives in a totally separate Git repo to my main app source code repo. So that when I do a grunt deploy it optimises and copies the relevant files to the Heroku repo, tidies it up (git add -A etc.) and then git push heroku master (or whatever).
It seems like a cleaner separation of concerns if your live servers are only responsible for running a pre-built app package.
YMMV of course, and the accepted answer above is totally valid too ... especially on a well understood and stable live environment like Heroku.
Heroku buildpack works fine for me. Great stuff.
To get this working with grunt 4.0 I followed the instructions here https://discussion.heroku.com/t/grunt-on-heroku/98/2 . The only change I had to make was to remove the path to grunt as using unix style slashes would make it fail in windows and vice versa. Luckily you don't even need to specify the path as NPM will look for grunt in the node_modules/.bin folder https://npmjs.org/doc/scripts.html#path.
make sure you have both grunt and grunt-cli installed locally in your package.json even if grunt tells you to install the cli globally: $: npm i -S grunt grunt-cli
add a postinstall step to your package.json that looks like this: "postinstall": "grunt prod"
The npm postinstall step is probably your best option, since you can invoke grunt from there. But you should also check out a custom buildpack, such as heroku-buildpack-nodejs-grunt.
This post is Rails-specific but I don't see why you couldn't use it with any back-end framework and just swap the Ruby buildpack with whatever you're using.
The solution is basically to use multi buildpacks, and have the Node/Grunt buildpack run grunt build for you right on Heroku.
Significantly, this solution does not have you check build artifacts into version control. (Yay!!!)
http://www.angularonrails.com/deploy-angular-rails-single-page-application-heroku/

Resources