I'm reasonably new to node, git, github and Heroku and I'm struggling to work out the best way of sending my application to Heroku without cluttering up the repo with my compiled, minified app and without doing too much in Heroku.
My node.js project looks a bit like this:
- client
... code
- server
... code
- node_modules
- package.json
- gulpfile.js
- dist
- client
- server
Everything apart from node_modules and dist goes into github.
The gulpfile compiles, minifies and concatenates everything ready for release in dist.
How do I push just the dist folder to Heroku, without also putting it into github? What is best practice? I'd rather not send my gulpfile to Heroku as it means moving the devDependencies in package.json and using a post update script, as it ties the project to Heroku more than I'd like.
Reasons for not using post hook are summed up well in these two posts: https://stackoverflow.com/a/15050864/344022 & https://stackoverflow.com/a/21056644/344022, unfortunately they don't provide an easy to understand alternative.
Heroku now has a static buildpack in development to handle this (see https://github.com/heroku/heroku-buildpack-static)
Create a static.json file to use the files from dist/ with .html suffix and to re-route all calls back to the SPA
{
"root": "dist/",
"clean_urls": true,
"routes": {
"/**": "index.html"
}
}
Extend package.json scripts to ensure dist/ directory is built, for example
"scripts": {
...
"heroku-postbuild": "gulp"
}
So that dev dependencies from package.json get installed
heroku config:set NPM_CONFIG_PRODUCTION=false --app
Multiple build packs so you can build and deploy
heroku buildpacks:add heroku/nodejs --app <app_name>
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-static.git --app <app_name>
Your procfile can be empty in this case.
I had the same problem of pushing only the dist folder to heroku app, Right now I am using a different approach, not sure the idle one, but it works for me. I created a deploy file and added the below code
import {spawnSync} from 'child_process';
function deploy(){
options = {
cwd: path.resolve(__dirname, './dist')
};
//push dist folder to deploy repo
console.log('Initialising Repository');
spawnSync('git',['init'],options);
console.log('Adding remote url');
spawnSync('git',['remote','add', remote.name, remote.gitPath],options)
console.log('Add all files');
spawnSync('git',['add','.','--all'],options)
console.log(`Commit with v${version}`);
spawnSync('git', ['commit','-m',`v${version}`], options)
console.log('Push the changes to repo');
spawnSync('git', ['push', '-f', remote.name, 'master'],options)
}
kept repo iformation in package.json and read here, I am running this after a webpack build task. So this will push my new build to heroku. Even if the .git inside dist gets deleted it will take care of it.
Go on, set up a post hook on heroku which builds you app and copies the files to where they'll be served. This is fairly normal practice, and once it's set up all you need to do is a git push to deploy your app, which is really rather handy. The alternative is to have a separate repository which you manually copy the files to and push from, but that doesn't seem as slick to me, greater chance of human error by messing up the dependencies, or forgetting to delete generated files which are no longer needed etc.
Related
So I've been at this for two days now and can't figure it out. I'm trying to deploy a Vue front end and express back end app to Heroku.
In my root folder I have a "public" folder which contains the front end and "server" folder for the back end.
In the root directory's package.json, the start script is
"start": "npm run pull && start npm run f && start npm run b",
"pull": "git pull",
"f": "cd ./public && npm run serve",
"b": "cd ./server && npm run dev"
This works perfectly fine for me to run locally, and even works with heroku locally as well using heroku local web but when I try to actually push to heroku using git push heroku main it doesn't even get past the git pull claiming:
fatal: not a git repository (or any parent up to mount point /)
I've tried simply getting rid of the git pull, but that just leads down a rabbit hole of other errors I've been trying to figure out for days and I'm hoping I'm just being dumb and missing something obvious. Any help would be greatly appreciated.
I'm going to try and list some things I've tried here:
Setting the heroku remote repository heroku git:remote -a heroku-name-here
Didn't change anything, pretty sure I already have this correct
Removing the git pull
Led to heroku not recognizing "start" sh: 1: start: not found
Removing the 'start' after git pull
Led to vue-cli-service not being found
Literally separating the back and front end into 2 separate repositories and 2 separate heroku things
This seemed to get the back end functioning, but the front end didn't seem to work. Unfortunately I don't remember exactly why but can try again if it would be helpful
All 3 comments from here: How to solve vue-cli-service: not found proplem on heroku?
I kind of fixed it kind of. Here's what I did
So I went back to the approach of kind of keeping them separate. I started by getting the server up and running.
In Heroku, I added the buildpack: https://github.com/timanovsky/subdir-heroku-buildpack.git BEFORE the heroku/nodejs buildpack to allow me to use a subdirectory rather than the whole repo
In Heroku settings, I added the config var PROJECT_PATH with the value server - In this case, server was the sub-directory immediately under my root
In vue.config.js of my front end, I changed the outputted build path to go INTO my server folder, using outputDir: path.resolve(__dirname, "../server/front-end")
In mongodb, under "Security" in "Network Access" which can be found towards the left in the navigation, I added the IP address 0.0.0.0/0 which I believe basically lets anyone access it. This might not be the most secure but it works.
Finally, this basically merged all my routes together which causes chaos because if I had a front end route /test-route and a back-end route /test-route it would like break which made sense. So I simply changed my index.js back end routes to go to /api/ instead of / so kind of like this
const mutators = require("./routes/mutators");
app.use(router.use("/api/", mutators));
Then at the end of my index.js file, I added
app.route("/*").get(function(req, res) {
res.sendFile(path.join(__dirname + "/front-end/index.html"));
});
so that front end routes like /test-route would then actually go to the site.
Following a course on Nuxt, I have chosen the SSR route when creating this application, separating admin, client and server into their individual files. This is the file structure:
- amazon-clone
- admin
- client
- server
The course material does not cover pushing to git or deploying to Heroku.
I have followed the steps as per Nuxt & Heroku docs, however because each file will have its own package.json and nuxt.config.js I am under the impression this will not work. As Heroku will expect a package.json in the root folder?
What is the best practise for deploying an app to heroku when client, server and admin are seperated?
The repository: https://github.com/TomBell95/amazon-clone
Heroku deployment steps:
Procfile: web: npm start
package.json: "heroku-postbuild":"npm run build"
"engines": {"node": "14.x"}
heroku buildpacks:set heroku/nodejs
heroku config:set HOST=0.0.0.0
heroku config:set NPM_CONFIG_PRODUCTION=true
I have found similar questions however nothing Nuxt specific (e.g. How to push both the client side and server side project folders together as a one project (api + front end) on github?).
I really don't see the purpose of having all of those 3 separate.
Never saw this kind of project structure and tbh, I don't even know how to host it properly.
At the end, there is a backend on this. So, you could probably split the backend (host it on Heroku) and the frontend (split it on the frontend). If you're learning Nuxt, this is probably not the way to go because it's not using a common structure from the start.
I can recommend:
Nuxt.js - Vue.js on Steroids, I took this one a while ago, it's done by Max, he is a great teacher and does a lot of great content
Mastering Nuxt is done by a Nuxt Ambassador and his team. It's very complete and plenty of good practices
Those are good resources that you can follow, which are well-known and good.
I am developing a NodeJS app that uses React on the front end. My folder structure is:
root -
- client (React App)
- api (express server)
My git folder is in the root folder for pushing the entire project to GitHub throughout development. But does my repo need to now be initialized in the api folder? Or is there a way to tell Heroku that the application is in the api folder?
Error on Heroku:
Build failed
There was an issue building your app. Please ensure your app is deployable to Heroku and try again.
! No default language could be detected for this app.
HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically.
See https://devcenter.heroku.com/articles/buildpacks
! Push failed
Also I feel it's worth mentioning that I set up the auto deploys in the Heroku GUI. So, it is attempting to build. I also have a Proc file and an app.json file.
app.json
{
"name": "Craig Bauer | Portfolio",
"description": "My web portfolio built as a MEAN stacjk app",
"repository": "https://github.com/craigbauerwebdev/Portfolio",
"logo": "",
"keywoeds": ["node", "react", "portfolio"],
"image": "heroku/nodejs"
},
{
"buildpacks": [
{
"url": "https://github.com/heroku/heroku-buildpack-node.js"
}
]
}
Procfile
web: node app.js
Thanks in advance
I found this solution and just wanted to share.
My entire production application is now in the api folder. This command worked well for me.
git subtree push --prefix api heroku master
For future projects I will structure this differently so I won't have to copy the build before each deploy.
I am trying to deploy a Rails 5 api with an Angular 2 front end, with the Angular code living an frontend folder inside of the main Rails project.
I was able to deploy using this tutorial (https://www.angularonrails.com/deploy-angular-2rails-5-app-heroku/), and specifically this custom Heroku buildpack (https://github.com/jasonswett/heroku-buildpack-nodejs/stargazers).
While this buildpack is absolutely awesome for existing, I am a little uncomfortable depending on the custom implementation in the long run. It also means I have to rename my frontend folder to client.
Is there a way to use the main Heroku Node buildpack, and somehow pass the path of my Angular frontend folder as an ENV variable? How would I go about doing this?
I've read through the Github conversations here (https://github.com/heroku/heroku-buildpack-nodejs/pull/192) and here (https://github.com/heroku/heroku-buildpack-nodejs/pull/203) but can't make heads or tails of it.
Please help!
the trick is to place a package.json at root with the following:
{
"scripts": {
"postinstall": "cd frontend && npm install"
}
}
substitute "frontend" with whatever folder the angular / node app is in.
See github issues discussion here: https://github.com/heroku/heroku-buildpack-nodejs/issues/323#issuecomment-227520485
I'm currently trying to deploy a hapi.js app to heroku with this file structure:
.git
client
server
The hapi.js server is inside the server folder along with it's package.json file, node_modules and all that stuff.
Inside the client folder, I have all the front-end related things (small angular app with bower_components and a gulp script to inject everything). The server.js from /server is serving both the bower_components and the angular app related files.
My current problem is that, obviously, Heroku doesn't find a way to deploy my app because of its structure, since it needs to have the server and package.json on the root of the project (which i'm trying to avoid at all costs).
So far I tried to put on my Procfile the following:
web: node server/server.js
but unfortunately it didn't let me push because it didn't match any of its buildpacks.
Have you add .bowerrc file
.bowerrc file contains
{
"directory": "client/bower_components"
}
and add bower.json in root.