Deploy NodeJS app to GCP AppEngine with customize start command - node.js

Here is my package.json
"scripts": {
"start": "react-scripts start",
"start:develop": "env-cmd -f env/.env.develop react-scripts start",
"start:stage": "env-cmd -f env/.env.stage react-scripts start",
...
}
env folder structure
env
├─ .env.develop (env=develop)
├─ .env.stage (env=stage)
When run on local (MacOS)
"yarn start" runs NodeJS app on local with default "env" = local (which is defined in other file)
"yarn start:develop" runs NodeJS app on local with "env" = develop
But now when I want to deploy this to GCP AppEngine, it's always deploy with "start" command (equivalent to "yarn start" on local)
How can I deploy "yarn start:develop" to AppEngine without declaring more environment variables in app.yaml?

From the documentation about what happens when you deploy your program,
Node.js modules are installed in the cloud as listed in your package.json and package-lock.json files and your service is started by using npm start.
I interpret the above to mean your project on the cloud is always run with start script and GAE will not/does not know how to use another script.
A possible workaround could be to deploy your app using a different version name e.g. dev i.e. you have
Your default version with "start": "react-scripts start"
dev version with "start": "env-cmd -f env/.env.develop react-scripts start"
Both of your versions use only the start script but they do different things

Related

How to deploy a React SSR application to Heroku?

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

npm run points to different .env file

We are working on nodeJs/ExpressJs we have configured multiple .env files for development and production and pointing it to package.json for different execution process, we have naming conversation issues at scripts.
Whenever we run npm run prod it takes to preprod configuration. what could be the issues?
Update: we have figured that the suffix of the script key is the same in the next script, after update/rename preprod to preProd the both runs fine. but why?
Eg :
"scripts": {
"dev": "clear; env-cmd -f ./config/hostedDev.env nodemon --exec babel-node index.js",
"prod": "clear; env-cmd -f ./config/prod.env nodemon --exec babel-node index.js",
"preprod": "clear; env-cmd -f ./config/preprod.env nodemon --exec babel-node index.js"
},
Apparently the issue is with the word 'pre'.
If you would have noticed it runs both preprod and prod commands (pre running first).
If you change the script name to 'postprod' the postprod script will run later.
So, I guess npm uses 'pre' as to run before the 'prod' script and then running 'prod' script itself.

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.

How to deploy an npm project to Heroku?

I currently have an npm project built with vue-cli and socket.io server.
This is how my project is structured:
Project/
|--node_server/
| |--server.js
|--src/
| |--main.js
| |--App.vue
| |--other .vue files and folders
I do not know how to deploy this app on Heroku because I will need to run two scripts while deploying that is node server.js (in the node_server folder) and npm run build or npm run dev (in the root folder).
What are the steps on how to deploy it successfully? Heroku takes my project from github whenever I push and builds it automatically. I have tried deploying but it ends up with an error page.
Let's say you need to build the front-end with build script first, and then you need to run nodejs server with start script which is node server.js.
...
"scripts": {
"build": "gulp or something idk"
"prestart": "npm run build",
"start": "node node_server/server.js",
},
...
But if you need to run these two scripts at the same time you can achieve this with something like that:
...
"scripts": {
"build": "gulp or something idk"
"start": "npm run build & node node_server/server.js",
},
...
I hope it would be helpful.
For an example, you can take a look at the package.json of one of my project: https://github.com/hisener/pirate-radio/blob/master/package.json
For more information, please refer https://docs.npmjs.com/misc/scripts

Resources