How to run Bower on Heroku - node.js

I'm trying to deploy a NodeJs App on Heroku and this app uses bower.
I did what have been suggested here, but I'm having this error on Heroku after a push:
bower error status code of git: 128

Here is what I use in my app:
Adding proper scripts to package.json
"scripts": {
"start": "node web.js",
"postinstall": "bower cache clean && bower install"
},
Add bower to dependency list
"dependencies": {
...
"bower": "~1.3.12",
...
},
Publishing flow for Heroku is following
It pulls recent version
Runs install
Runs postinstall
Runs start
My Sample
https://github.com/gevorg/typeitquick/blob/master/package.json

Well, doing that may not fix this problem, but you can use
git config --global url."https://".insteadOf git://
to tell git to use HTTPS instead of GIT which worked out for me to install npm dependencies.

Apparently people have cleaned their cache?
https://github.com/bower/bower/issues/50
You can run arbitrary commands on your heroku host by using:
heroku run console

Related

How to Serve a React App with Django on Elastic Beanstalk?

I used to have my app on Heroku and the way it worked there was that I had 2 buildpacks. One for NodeJS and one for Python. Heroku ran npm run build and then Django served the files from the build folder.
I use Code Pipeline on AWS to deploy a new version of my app every time there is a new push on my GitHub repository.
Since I couldn't figure out how to run npm run build in a python environment in EB, I had a workaround. I ran npm run build and pushed it to my repository (removed the build folder from .gitignore) and then Django served the files on EB.
However, this is not the best solution and I was wondering if anyone knows how to run npm run build the way Heroku can do it with their NodeJS buildpack for a python app on EB.
So I figured out one solution that worked for me.
Since I want to create the build version of my app on the server the way Heroku does it with the NodeJS buildpack, I had to create a command that installs node like this:
container_commands:
01_install_node:
command: "curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash - && sudo yum install nodejs"
ignoreErrors: false
And then to create the build version of the react app on a Python Environment EB, I added the following command:
container_commands:
02_react:
command: "npm install && npm run build"
ignoreErrors: false
So of course, after the build version is created, you should collect static files, so here is how my working config file looked at the end:
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: <project_name>/wsgi.py
aws:elasticbeanstalk:application:environment:
DJANGO_SETTINGS_MODULE: <project_name>.settings
aws:elasticbeanstalk:container:python:staticfiles:
/static/: staticfiles/
container_commands:
01_install_node:
command: "curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash - && sudo yum install nodejs"
ignoreErrors: false
02_react:
command: "npm install && npm run build"
ignoreErrors: false
03_collectstatic:
command: "django-admin.py collectstatic --noinput"
Hope this helps anyone who encounters the same 🙂
I don't know exactly Python but I guess you can adapt for you case.
Elastic Beanstalk for Node.js platform use by default app.js, then server.js, and then npm start (in that order) to start your application.
You can change this behavior with configuration files. Below the steps to accomplish with Node.js:
Create the following file .ebextensions/<your-config-file-name>.config with the following content:
option_settings:
aws:elasticbeanstalk:container:nodejs:
NodeCommand: "npm run eb:prod"
Edit your package.json to create the eb:prod command. For instance:
"scripts": {
"start": "razzle start",
"build": "razzle build",
"test": "razzle test --env=jsdom",
"start:prod": "NODE_ENV=production node build/server.js",
"eb:prod": "npm run build && npm run start:prod"
}
You may faced permission denied errors during your build. To solve this problem you can create .npmrc file with the following content:
# Force npm to run node-gyp also as root
unsafe-perm=true
If you need more details, I wrote a blogpost about it: I deployed a server-side React app with AWS Elastic Beanstalk. Here’s what I learned.

Deploying a Gulp app to Heroku in a subdirectory

I'm trying to deploy a Rails/Angular app to Heroku.
Part of my directory structure looks like this:
client/package.json
client/gulpfile.js
My package.json and gulpfile.js aren't at the root; they're in a subdirectory.
The Heroku Node buildpack of course expects package.json to be at the root. How can I get Heroku to recognize my Gulp/Angular app?
Here's how you can do it without a custom buildpack:
Add the node heroku buildpack
heroku buildpacks:add --index 1 https://github.com/heroku/heroku-buildpack-nodejs
Add a package.json to the root of your rails project.
Add a postinstall or a heroku-postbuild script to the top-level package.json like this:
//top-level package.json
"scripts": {
"postinstall": "cd client && npm install && gulp build"
}
Add client/node_modules to the Heroku cache by adding this to the top-level package.json:
//top-level package.json
"cacheDirectories": ["client/node_modules"]
Enjoy
Source:
https://devcenter.heroku.com/articles/nodejs-support#customizing-the-build-process
You'd need to use a custom buildpack to build your front end: https://devcenter.heroku.com/articles/buildpack-api#composing-multiple-buildpacks. You'd compose this custom buildpack with the Rails buildpack to get a complete build working.
The nodejs buildpack has examples on how to run npm install and load package.json which may be helpful.

How to deploy node that uses Webpack to heroku

I'm using webpack.
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 webpack build command) after deploy and setup my server (it's already looking for public folder).
It seems me a bad idea to commit before upload. Maybe there are some gentle decisions... Any thoughts?
Forked from: How to deploy node that uses Gulp to heroku
"heroku-postbuild": "webpack -p --config ./webpack.prod.config.js --progress"
this is better because if you use postinstall, everytime you do npm i the build script get fired
Do it in a postinstall script as suggested by #orlando:
"postinstall": "webpack -p --config ./webpack.prod.config.js --progress"
In this approach make sure to heroku config:set NODE_ENV=production heroku config:set NPM_CONFIG_PRODUCTION=true
OR
You can find this custom buildpack heroku-buildpack-webpack usable.
These links might help you build understanding:
heroku hook-things-up
npm scripts
In 2019, the simplest way to do this is to use the heroku/nodejs buildpack (automatically selected if you have a package.json at the root of the repository) and add a build script to package json:
"build": "webpack --mode production --config ./webpack.prod.config.js"
Heroku will automatically run this script on deploy. Bonus points because this is the intuitive script to run to test the build locally or in CI.
This is described in Heroku's Best Practices for Node.js Development document:
npm’s lifecycle scripts make great hooks for automation. Heroku provides custom hooks that allow you to run custom commands before or after we install your dependencies. If you need to run something before building your app, you can use the heroku-prebuild script. Need to build assets with grunt, gulp, browserify, or webpack? Do it in a build script.

AWS Elastic Beanstalk run Grunt task

I want to run a node.js application on elastic beanstalk. I have a client which gets build by a grunt job (jade, less, concat, etc.) I excluded this folder from git
I can localy run this by grunt buildClient which is executed by grunt-cli
I added grunt and grunt-cli in my packages dev-dependencies
I want to run the grunt build before the application is launched, i already setup a configuration in .ebextensions/app.config
container_commands:
01_build_client:
command: grunt buildClient
I guess my cwd is /tmp/deployment/application/
but there is says Fatal error: Unable to find local grunt. I guess grunt-cli is installed, but why is this error?
i also tried putting the grunt job in the postinstall section of package.json, but this doesnt work as well.
How do i build my grunt job on a EBS instance?
When running Grunt on a paas, it's best to install a local copy of grunt-cli and grunt locally in the project. That way it's always available and is the exact version you'll need. Then you run npm install instead of grunt so your postinstall works properly.
For example, your package.json might look like this:
"grunt": "0.4.5",
"grunt-cli": "0.1.13",
You can first specify the path to your gruntfile using the --gruntfile <pathToGruntfile> option on the grunt command. However, you'll also need to npm install grunt before running this, or you'll receive the same error.
I've just run into a similar problem whilst trying to get webpack bundilng on elastic beanstalk. I found that when elastic beanstalk runs an npm install it includes the --production flag. This means that you'll need to move your dev dependencies into the dependencies block.
Something else that caught me out is that eb doesn't seem to run the postinstall script which is really annoying! I did find that it runs the prestart script though.
My package.json file ended up looking something like this:
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"prestart": "node node_modules/webpack/bin/webpack.js"
},
"dependencies": {
"backbone": "^1.2.1",
"backbone.marionette": "^2.4.1",
"webpack": "^1.9.10",
...
}
}

How can I invoke npm on heroku command line (to install bower components)?

Bower is for client side Javascript what npm is for the server side and reads a component.json file to recognize dependencies that should be fetched at deploy time so I'd be happy it heroku would run it at slug compilation time.
Unfortunately I can not invoke npm or bower from a heroku console or one-off command (heroku run "npm help") (heroku run bash -> npm help) as it's possible with ruby's rake. I've put npm and node (latest/x versions) in my package.json but in the engines section, not the dependencies.
I think this could be solved by customizing the node buildpack but I consider this a little too heavy task just for activating something so obvious.
You can also setup a postintall command, something like this in your package.json
"dependencies": {
"bower": "0.6.x"
},
"scripts": {
"postinstall": "./node_modules/bower/bin/bower install"
}
Then npm install will also install bower dependencies.
Pros : one command to rule them all.
Cons : you unnecessarily embed bower as a dependency.
You can use run like this:
heroku run npm install git://github.com/webjay/kaiseki
You should declare NPM dependencies in the package.json file
All you install from shell will be deleted on exit shell. You are in a cloned instance.
You can use bower directly like this
"dependencies": {
"bower": "^1.7.9"
},
"scripts": {
"postinstall": "sudo bower install --allow-root "
}

Resources