I have an application using Node.js with Aurelia on the front-end, which I want to deploy on Heroku.
To run the app locally, I need to execute following commands:
1. npm start
2. cd public > gulp watch
After installing heroku-cli, tried publishing it using git push heroku master.
The problem is, Heroku only runs npm start when it's deploying the app on cloud. So it is able to start the server.
However, it doesn't know anything about cd public and gulp watch.
My question is, how can I tell Heroku to change directory to public and execute gulp watch command, once it has started the server?
Edit:
I forgot to address an important point. Since you only mentioned Aurelia in your question, I (wrongly) assumed that that's all you had.
Ultimately, for a production app you'll want to have a proper webserver hosting your Aurelia app.
Example:
For Aurelia apps I've built, I typically have 3 distinct processes running, each with their own port (or hostname):
IdentityServer
ASP.NET Web Api
OWIN FileServer
The third one is what hosts my Aurelia app as a static bundle.
There is no gulp or anything like that involved here. The server doesn't even have npm installed and sees it just like any other server-side application. And that's exactly how I deploy it; no node-related commands needed.
If you're using nodejs for your server-side stuff, use http-server to serve the static bundle.
When you host your aurelia app within your own serverside application you get the added benefit of being able to send some bootstrapping configuration directly along with the bundle, so you don't have to hard-code urls and such.
That's what I implied with "don't host a static site on heroku": bundle it up, and let your web application host it. My original answer would only apply if there is no server-side stuff involved.
Original answer:
It's generally not recommended to host static sites on heroku, see this blog post. The bottom line is that Aurelia sites are static, and a static site doesn't need an app server. It's unnecessarily expensive and doesn't have as good distribution as most CDNs do.
With that said, if you insist on hosting a static Aurelia site on Heroku then your best bet is to combine all your script calls into a single call which, as you say, already runs. So make your npm start script call gulp watch.
You'd probably want to npm install your dependencies and call ../node_modules/.bin/gulp watch instead of calling gulp globally.
When it comes to Heroku however, gulp watch in itself probably won't work because that will start a development server which will have no port binding in Heroku. It will run, but it won't be accessible from the outside.
gulp watch is not something you want to run on a server anyway because it will watch for file changes (which never happen there) and run things like browsersync which will be useless. Just bundle your app and start a normal http-server or better yet, upload the bundle ready-to-start into the correct folder and you're done.
You want to build your app and then deploy as if it were a fully-compiled, static application. With Aurelia CLI, that would be au build --env prod and then copy the scripts folder, index.html, and any dependencies like css, fonts, etc. to a separate folder. gulp build works the same way.
From there, you will publish the compiled app to Heroku as shown in this medium.com article:
https://medium.com/#winnieliang/how-to-run-a-simple-html-css-javascript-application-on-heroku-4e664c541b0b
The main part of the article is below, but here is the kicker - you are "tricking" heroku into thinking it is a PHP app. Serious!
Head to root directory of the repo that contains index.html which dictates the main HTML page.
Run touch composer.json to create a file called composer.json.
Add the following line: {} inside.
Run touch index.php to create a file called index.php.
Add the line: <?php include_once("index.html"); ?> inside.
Now update the repo on Github if it’s connected to your account or Heroku command git push heroku master . Wait for the automatic deploy to work its magic and tada!
There are some other steps to make your compiled app into a repo (ie, git init) but this should work for you. It did for me.
Related
I am working on react js project & using node js for backend(to handle DB as well as to run CRON JOBs). At my local machine I had created 2 folders "botclient" & 'botserver". I starts the server using "node server.js" in 1 command prompt & in another command prompt, I satrs client using "npm start". Now in browser I use "http://localhost:3000 & my application works.
Now my client has given me 1 shared hosted domain something like http://mybot.hismaindomain.in.
Now he has given me cPanel credentials to deploy this app. I have no idea how should I deploy it on server. I had tried lots of threads like "running nodejs react in one directory" or "react js nodejs deployment on hosted server" But I could not deploy the application on Hosted server.
I am total newbie in this technology so please help me to solve this problem. Whether I am doing wrong folder structure? Whether I need 2 sub domains?(for client and server separately)
Please help me. Thanks in advance.
(This should be a comment but I csan't comment yet)
Maybe try using cPanel cron job to run the node command
You do not need two sub-domains. Neither do you need a specific folder structure to have shared hosting.
To run node two or more servers on the same host, from the same repository, from just one command line, you can use a package like 'concurrently' or 'npm-run-all', which lets one npm start-command activate a number of processes in parallell. For example: concurrently \"node server.js --port 4000\" \"webpack --config client/webpack.config.js --port 3000\" \"node cron-jobs.js\". In this example, the server is in the project root, and the react app is in client subfolder with its own package.json.
Then, to share a domain it is necessary to setup a reverse proxy, so that the backend's port can be accessed via a designated path, ie: /api. There are many ways to do it and there are others who would explain it better than me. Try google react node config reverse proxy or similar. Good to know is that the easiest solutions might be limited to a dev server, while the more complicated ones (like nginx) are independent on your tech stack (which you might not need).
For cron jobs, you could try a package like 'node-cron', check this guide for the basics
This is my file tree containing a folder for my Vue app (client folder) and my NodeJS server (server folder).
When I try uploading to Heroku, I get an error saying that no matching buildpacks could be found, and that's I believe due to my source folder not having a package.js and that being because I have one in the client and server folders.
So how can I accomplish deploying both my client and server-side in one Heroku app, or would I need to split my whole app in one Heroku Front-End App and one Heroku Back-End App?
I'm sorry for such a stupid question, but I am really confused on how to put my app live, since it's finally finished after a month of work.
No Buildpack found while deploying to Heroku .. When I try uploading to Heroku, I get an error saying that no matching buildpacks could be found, and that's I believe due to my source folder not having a package.js
Correct, this error "no buildpack found" happens because Heroku looks at (only) your root directory and cannot determine what language/framework you are using.
The package.json file defines the dependencies that should be installed with your application. To create a package.json file for your app, run the command npm init in the root directory of your app.
https://devcenter.heroku.com/articles/deploying-nodejs#declare-app-dependencies
I'd recommend reading the heroku node docs and deploying a "hello world" application first, as a learning experience. You'll also want to read about the Procfile.
Deploying a client-server application to Heroku is quite common, all rails apps work this way (a single deploy). But, for node apps, there are many different ways to deploy, and there is no official (documented) way to organize your code, AFAIK.
I currently a web app involving a Vue.js frontend with a Flask backend acting as a REST API. They are divided into the client and server folders in my repo, respectively. I am looking to deploy it to Heroku via the Github deployment feature but am running into some errors and questions I need clarified.
All code can be found in this Github Repo: https://github.com/justintranjt/thrive-test
In development, I have been running the application like so:
In one terminal run thriveApp.py. In another terminal run npm run dev. Navigate to localhost:8080 which is the local server running
the Vue.js application.
Is this how the application will be run on Heroku? Or is the Vue application run using npm run build? In that case I would have to take the produced build folder and serve it in the Flask application, correct?
In addition, some of my links between the frontend and backend specify localhost:8080 and localhost:5000 (8080 is Vue and 5000 is Flask) which work locally. But will this work when deployed to Heroku?
<b-form>
<b-button variant="primary" href="http://localhost:5000/loginPage">Login via CAS</b-button>
</b-form>
As you can see here, I have a button in my Vue application that links to a login page routed by my Flask application. Will I have to change the portion of the URL that says localhost:5000 when running on Heroku?
Finally, When I currently try to build the application on Heroku only the Python portion of the code is recognized as modules from the Vue app specified by package.json are not installed while plugins for Python specified by requirements.txt ARE installed by Heroku.
I have a feeling all of these questions are generally related to each other. Any other advice or tips regarding Heroku deployment would also be helpful as I'm quite confused about deployment at the moment.
Is this how the application will be run on Heroku?
No! npm run dev spins up an entire development server with vue in dev mode and hot reloading. That's a lot of overhead, especially when it comes to file sizes.
Or is the Vue application run using npm run build?
Kind of. Vue doesn't need to run on your server at all, it's all client-side. npm run build bundles and minifies your files to a dist folder, you'll be left with only html, css and javascript - this is all of the frontend code that needs to be on your production environment - no need to deploy any of the source files. All you need to do is serve those static files from any server. This could be done by your flask, or just any apache, nginx etc.
But will this work when deployed to Heroku?
That will be very tricky to setup. It's one of the reasons why I would not deploy front- and backend on the same (virtual) server.
modules from the Vue app specified by package.json are not installed
If you deploy your bundled frontend instead of the source code this wont be an issue anymore. I still recommend serving the frontend from a different environment.
I am trying to deploy an application I am building with the MEAN stack to Heroku and am having some trouble. I think the issue is with the structure of my application. I have all my server code in a folder called server, which has its own package.json and src folder that contains the actual server code.
Right now I am simply trying to get Heroku to deploy the client side of the application. I am only getting an error... I know that the database and server are not running but I cannot even get past the initial displaying of the app. I have one web dyno set up to run ng serve (npm start) on the app.
If someone would be willing to look at the structure of my application and sees why I am unable to deploy to Heroku without really digging into the code, that would be much appreciated.
Here is the code
Please note that it is on the deploy branch, and this is on purpose. I do not want to push anything to the master until I am sure it is working.
The Angular web server targets localhost:4200 by default. That can be changed with a couple command-line options. --port accepts a port and --host accepts a host IP address.
So you could modify the ng serve script as follows: ng serve --host [host-ip] --port [port-number] --disableHostCheck. That last flag (--disableHostCheck) tells the dev server to bypass host checking when normally ng serve fails on anything except localhost. Terrible idea if meant for anything except private development/testing.
Another issue: Heroku runs off web dynos and from what I understand about them, they use a random port and IP each time. While the random port is stored under the variable $PORT, the IP does not seem to have a similar variable. Web dynos keep that information to themselves.
Heroku does offer this command: heroku local web. It runs your application on localhost:5000. That means ng serve --port 5000 works perfectly with this command. This should tell you how your front-end will run on Heroku. Your angular dev server will function as expected too.
For actual deployment to Heroku, use that express server of yours. Run ng build from your file system and it will spit out an index.html in the dist folder. This file holds your entire front-end application. You can then upload that file into your browser from the server.
For express that usually breaks down into:
app.get('*', function(req, res) {
res.sendFile('path/to/index.html');
});
Hopefully this helps! Let me know if I missed the mark anywhere.
I have a Yeoman web app up and running. It fails to retrieve livereload.js and can take up 21s before timing out and the page then goes on to load.
I don't even need the livereload functionality. This is a web app that is finished with development.
I use forever to start the web app. I navigate to the root folder of my app which contains my Gruntfile.js. I then run the command - forever start /usr/local/bin/grunt
What do I need to do to disable this livereload functionality?
You can disable running livereload server from the grunt file. However, that will still load the livereload js file in website footer and result in very slow page loads.
The reload script is being added from the server side. Edit the file server/config/express.js and comment out the line:
app.use(require('connect-livereload')());
Note: You seem to have bigger problems as well. You said, the site has completed development, but livereload works which is possible only when the server is running in development mode(unless you have edited Gruntfile to that effect). What you need is grunt serve:dist instead of simple grunt serve. Running the server in dev environment is a security as well as performance problem.
PS: I started with a similar set up but found later that sometimes the app.js will throw an error while grunt will continue running. This will put forever useless. You shall need the grunt-forever npm module to make sure forever is monitoring the right file.