How to deploy a React SSR application to Heroku? - node.js

I have simple running react Server Side App .
GitHub Link for the repo, in the local env i have a build script that runs using npm start which starts the client and server builds and then i have a watcher which listen's to changes in file. This set up works really well locally.
"scripts": {
"start": "npm run dev",
"dev": "npm-run-all --parallel dev:*",
"dev:server": "nodemon --watch build --exec \"node build/bundle.js\"",
"dev:build-server": "webpack --config webpack.server.js --watch",
"dev:build-client": "webpack --config webpack.client.js --watch"
},
I tried to deploy these changes as a prod app to heroku here for some odd reason it never works and returns 503 . I have not added any changes to the build scripts in the package.json and tried deploying as is.
I thought it should work as the build log dosent give any errors on heroku but while trying to access the app it shows error and asks me to check app log but i am not using heroku cli and not planning on using it , and
thinking of auto deployment from github.
I am quite new to script/ largely build scripts trying to learn more on them.
How can we make sure this small React SSR git repo deploys and i am
able to access the home page .

I am not using heroku cli and not planning on using it
You should and I really recommend, as it's the best way to see errors that occurs after the build, why your app crashed and see the full logs. Even though you can see the logs from your heroku dashbord (More -> View logs), this only gives you the tail of the logs.
How can we make sure this small React SSR git repo deploys and i am able to access the home page.
Make sure the server is listening on the right port
by using process.env.PORT as heroku expose a dynamic port.
const port = process.env.PORT || 3000
app.listen(port, () => {
console.log('Listening on Port ' + port);
})
On heroku the NODE_ENV environment variable is set toproduction by default,
which means heroku will prune thedevDependencies after the build,
but in your case, you still need these dependencies to start your app with webpack.
You can fix this in two ways :
Customize your build process by adding a build script:
From your github
repo
:
"start": "webpack --config webpack.client.js; webpack --config webpack.server.js; node build/bundle.js"
to
"scripts": {
"start": "node build/bundle.js",
"build": "webpack --config webpack.client.js & webpack --config webpack.server.js",
"build:start": "webpack --config webpack.client.js && webpack --config webpack.server.js && node build/bundle.js",
}
Set the NODE_ENV to any other value to skip pruning your
devDependencies
heroku config:set NODE_ENV=development //(Another reason to use the CLI)
Check this link for more details

Related

Passing environment variable to pm2 is not working

I have two API in node js using babel and I have a package.json commands to use to make the application working this is the commands:
"build": "del-cli dist/ && babel src -d dist --copy-files",
"serve": "cross-env NODE_ENV=production node dist/index.js",
"start:noupdate": "cross-env NODE_ENV=development babel-node src/index.js",
"start:serve": "cross-env NODE_ENV=production node dist/index.js",
I have two domains one is https://api.website1.com.br and another is https://website2.com.br/api.
They have the same env file name but with another data for each database, that is .env.production and .env.development
When I make this "yarn build", my Linux execute this command :
"build": "del-cli dist/ && babel src -d dist --copy-files",
And this is working fine when I try to put in production mode on my real webservers, i go to the folder from the project and run this command to make the app online with PM2:
pm2 start npm -- run-script start:serve NODE_ENV=production
That will make this command work:
"cross-env NODE_ENV=production node dist/index.js"
The app runs just fine, but I have a problem he only runs one and doesn't create a new PM2 APP he just restarts what I start.
Example if I go to the folder in my https://api.website1.com.br and run this command first in this he starts, but I go to the another he doesn't start that but reload my already early app don't create a new one, what I'm doing wrong?
I manage to work this using pm2 ecosystem, that I found in this documentation from http://pm2.keymetrics.io/docs/usage/application-declaration/
I configure the default file and put a name my APP:
module.exports = {
apps : [{
name: "app",
script: "./app.js",
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
}
}]
}
and use this command pm2 start ecosystem.config.js and now is working, I post here to know if someone has the same problem

Node NextJS app recompiling when running in dev = true mode

I have an NextJS app that I build on a build server then deploy to another server to host it.
When I start the app in development mode npm wants to recompile the app even though all of the built components still exist. (.next folder, etc...)
When I run the app in a non development mode for next the app will start up with no build attempts.
Why does npm want to rebuild the app when const app = next({ true });?
In server/server.js
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
In package.json
"scripts": {
"dev": "NODE_ENV=development npm start",
"staging": "NODE_ENV=staging npm start",
"prod": "NODE_ENV=production npm start",
"build": "next build",
"start": "node server/server.js"
}
How I'm starting the app:
Development: npm run dev
Production: npm run prod
For a lack of better description the .next folder is the "optimized" version of your application. In development you need to continuously rebuild the .next folder because this is where you are serving your files from. During development you can actually see the .next rebuilding itself. In production you should only build the application once.
I imagine if you're deploying in Now it will build the .next folder as long as you have scripts like they define in setup. However, I use Docker for my builds so I have to build my .next folder via a build step. Here is an example of a Dockerfile and a corresponding package.json.
Dockerfile
FROM node:10-alpine AS builder
WORKDIR /app
COPY ./app .
RUN yarn install && yarn next-build
EXPOSE 80
CMD yarn start
package.json
...
"scripts": {
"next-build": "next build",
"start": "NODE_ENV=production node server/app.js",
...
So in production my build steps are
1. Install npm modules
2. Build my .next folder
3. Start my server.
In short:
In production since you aren't running a "next-build" script before you run "npm run prod" you aren't rebuilding the .next folder. In development next.js rebuilds each time you start your server so it can capture your changes in the .next folder.

Going from a budo local server setup to deployment on google cloud app engine

I trying to deploy a website which works flawlessly on my local Budo server. I'm trying to deploy it to Google App Engine, but I don't have enough knowledge about node.js and package.json to specify the configurations to run my website on App Engine.
My app has the following scripts running in my package.json file:
"scripts": {
"start": "budo main.js:dist/bundle.js --live --host localhost",
"watch": "watchify main.js -v --debug -o dist/bundle.js",
"prep": "yarn && mkdirp dist",
"build": "browserify main.js -o dist/bundle.js",
"lint": "eslint main.js --fix",
"deploy": "yarn build && uglifyjs dist/bundle.js -c -m -o dist/bundle.min.js"
},
I know the simple commands to deploy the server and the surrounding configurations of the Google Cloud Platform, but I don't know how to change my dependencies to work on the App Engine.
When I deploy the current setup I simply get 503 connection error.
So how do I port this to a setup that will work in production?

How to run 2 different commands on deploy and restart using Node.js on Heroku?

I am writing a Node.js app and using Heroku to host it. And also I use Webpack + Babel to bundle all my server files into one and to use ES2015 syntax. But the thing is, I need to build my app before running it. So I put this command into package.json:
"scripts": {
"start": "webpack && node build/server.js"
},
This works, but the problem is, when I run heroku restart, my app runs only after rebuild. And the same story when my app crashes.
So I guess I need 2 different commands: one on deploy (webpack) and one in npm start (node build/server.js)
How can I accomplish this?
Actually it was not that hard. Just had to change my package.json to
"scripts": {
"heroku-postbuild": "webpack",
"start": "node build/server.js"
}
(according to this article: Heroku Node.js Support)

Uploading my Node + HTML Canvas game to Heroku

I finished a small canvas based game and I would like to upload it to the web via Heroku.
All the code is written at the Src directory and I bundle it to the dist directory via Webpack. I then use a simple express server to serve the static files.
This is all there is to it:
On development mode this works just fine. However, when I upload to Heroku I get "Cannot GET /".
I tried several option to make this work but for some reason I'm not able to fix this.
I did try to write this as well:
app.get('/', (req, res) => {
res.sendFile('index.html');
}
or some variation of this but to no avail.
This is the scripts part of my package.json:
"scripts": {
"start": "node server.js",
"dev": "webpack --watch",
"prod": "webpack --config webpack.production.config.js -p"
}
When I run on development I use "npm install" followed by "npm run prod" to bundle to 'dist' and then "npm start".
What am I missing here?
Thanks!

Resources