cloud build trigger in app engine -Nodejs runtime error - node.js

WARNING: Your package.json does not specify a supported Node.js version. Please pin your application to a major version of the Node.js runtime.
Application detection failed: Error: node.js checker: Neither "start" in the "scripts" section of "package.json" nor the "server.js" file were found.
I added below in package.json
"engines": {
"node": "^13.8.0",
"npm":"^6.13.4"
},
app.yaml file
# [START runtime]
runtime: nodejs
env: flex
service: dev
handlers:
- url: /.*
secure: always
script: auto
redirect_http_response_code: 301
automatic_scaling:
min_num_instances: 1
max_num_instances: 2
cool_down_period_sec: 60
cpu_utilization:
target_utilization: 0.80
package.json
"scripts": {
"start": "serve -s ./build",
"prestart": "npm i -g serve",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
cloudbuild.yaml
steps:
- name: gcr.io/cloud-builders/npm
entrypoint: 'npm'
args: [ install ]
- name: gcr.io/cloud-builders/npm
entrypoint: 'npm'
args: [ run, build, --prod ]
- name: gcr.io/cloud-builders/gcloud
entrypoint: 'npm'
args: [ app, deploy, '[public/app.yaml]', --version=$SHORT_SHA ]

If you're using the GAE standard, keep in mind that it currently supports Node.js 10 and 12 runtimes.
Also, as the official GCP documentation mentions:
By default, the runtime starts your application by running node
server.js. If you specify a start script in your package.json file,
the runtime runs the specified start script instead.
"scripts": {
"start": "node app.js"
}
Please, have a look at this GitHub repository, which contains a simple app for GAE standard, which you could use as a reference.
EDIT
You need to make sure that your start script is starting a web server that responds to HTTP requests on the port specified by the PORT environment variable, typically 8080 (link).
Here you can see an example for the GAE flexible environment, where the app.js contains
// Start the server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
While the package.json has
"scripts": {
"start": "node app.js"
}
This error can be reproduced when deploying that sample on GAE with Cloud Build after removing the start script or if the app is not starting the server.

Related

Error on deploying a next.js app to cloud66

Im trying to deploy a basic next.js app which I just created on cloud66 vm.
This is my package.json of my next.js project:
{
"name": "cloud66",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"lint": "next lint",
"start": "next start",
"cloud66-build": "npm run build && npm run start"
},
"dependencies": {
"next": "13.0.3",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"engines": {
"node":">=14.6.0"
},
"devDependencies": {
"eslint": "^8.27.0",
"eslint-config-next": "^13.0.3"
}
}
when im deploying my app to cloud66 the deployment will be successfull but in the error logs of the server im getting the following error which ends up in not showing anything under my address:
Error: Could not find a production build in the '/app/.next' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id
optimistic-shy-swallow — at NextNodeServer.getBuildId (/app/node_modules/next/dist/server/next-server.js:165:23)
optimistic-shy-swallow — at new Server (/app/node_modules/next/dist/server/base-server.js:58:29)
optimistic-shy-swallow — at new NextNodeServer (/app/node_modules/next/dist/server/next-server.js:67:9)
optimistic-shy-swallow — at NextServer.createServer (/app/node_modules/next/dist/server/next.js:143:16)
optimistic-shy-swallow — at async /app/node_modules/next/dist/server/next.js:155:31
optimistic-shy-swallow — at async NextServer.prepare (/app/node_modules/next/dist/server/next.js:130:24)
optimistic-shy-swallow — at async /app/node_modules/next/dist/cli/next-start.js:116:9
now from what i found searching on the internet I had the idea to add a custom script to my package.json: "cloud66-build": "npm run build && npm run start" and call it. Cloud66 provides a way to call commands in an extra file defining the command which will be called. I added my script there, but the above error is still there. Does anybody have an idea?
production: # Environment
last_thing: # Hook point
- command: npm run cloud66-build # Hook type // <-- calling the script from my package.json
target: any # Hook fields
execute: true

CI with google cloud build and unit testing Jest in NodeJS

I'm setting up a CI/CD pipeline using Google cloud build, I'm doing 3 simple steps : install, test and deploy, here is my CloudBuild.yaml file :
steps:
- name: "gcr.io/cloud-builders/npm"
args: ["install"]
- name: "gcr.io/cloud-builders/npm"
args: ["run", "test"]
- name: "gcr.io/cloud-builders/gcloud"
args: ["app", "deploy"]
And here is my package.json where I need to specify the hole path of the jest so it can identify it, otherwise I set it : "test": "jest" the step 2 of the build will fail and it will not recognize it.
"scripts": {
"start": "node index.js",
"test": "sh node_modules/.bin/jest",
"test:watch": "jest --watch"
},
In this case I need to always push the node_modules to the github repo to find the module jest, but it's not a good practise.
Any ideas how can I fix this ?
Thanks

Google App Engine: Setting environment variables for React Production Build

I'm running a basic create-react-app production build on App Engine, but I'm not able to access my pre-defined environment variables. Is there any extra step I'm missing? I'm guessing it has something to do with the build process and serving a production build, but I'm not sure where to set the variable in this case.
app.yaml:
service: client-dev
runtime: nodejs10
env_variables:
TEST: "development"
package.json:
"scripts": {
"start": "serve -s build",
"start-dev": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
console.log(process.env.TEST) //undefined
According to CRA documentation, environmental variables are embedded during build time in a React app. They will not be available to static files during runtime.
In App Engine, contents of app.yaml are used during deployment which happens after React has finished building.
To make environmental variables available during build time, you can:
include them in a .env file in the root of your project if you are manually triggering the build process via yarn build or npm run build.
include them in a cloudbuild.yaml file for automatic builds using a continuous development platform like Cloud Build.
Note that the CRA documentation referenced above advises to begin every custom environment variable with REACT_APP_. For example your variable should be added like REACT_APP_TEST=development.

How to run production site after build vue cli

I'm using VueCLI 2 and build as production. THe build.js is built and compiled into 200KB. When I re-run the server as development, it loaded 3MB. I'm sure the build.js inside dist folder is 200KB. I tried to open index.html but it doesn't work and redirect to root directory on website.
Package.json
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
Webpack
module.exports = { ...
module:{
...
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
jQuery: 'jquery'
})
],
devtool: '#eval-source-map'
},
...
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: true
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
return module.context && module.context.indexOf('node_modules') !== -1;
}
})
])
}
HTML
<body>
<script src="/dist/vendor.js"></script>
<script src="/dist/main.js"></script>
</body>
Command
npm run build
npm run dev
npm run build creates a dist directory with a production build of your app.
In order to serve index.html in a browser you need an HTTP server.
For example serve:
npm install -g serve
serve -s dist
The default port is 5000, but can be adjusted using the -l or --listen flags:
serve -s build -l 4000
Docs:
https://create-react-app.dev/docs/deployment#static-server
https://github.com/zeit/serve
https://cli.vuejs.org/guide/deployment.html#previewing-locally
Production build can be run locally by utilizing Vue CLI's tooling simply by running:
vue-cli-service serve --mode production
For convenience, this can be added to package.json scripts:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"production": "vue-cli-service serve --mode production"
}
Command:
$ npm run production
Very easy with express, and highly extensible/configurable.
Install
npm install -D express
Compose
server.js
// optional: allow environment to specify port
const port = process.env.PORT || 8080
// wire up the module
const express = require('express')
// create server instance
const app = express()
// bind the request to an absolute path or relative to the CWD
app.use(express.static('dist'))
// start the server
app.listen(port, () => console.log(`Listening on port ${port}`))
Execute
node server.js
The Vue CLI tooling (vue-cli-service serve --mode production) still seemed to be serving the development files for me, albeit with process.env.NODE_ENV === 'production'.
To serve the contents of dist, the following worked for me without having to install any extra packages:
npm run build
npx serve dist
With custom port and SSL key/certificate:
npx serve dist -l 8095 --ssl-cert .\cert.pem --ssl-key .\cert-key.pem
You can also put this command into your package.json, e.g.
"scripts": {
"serve": "vue-cli-service serve",
"prod": "npx serve dist",
...
}
Then just do:
npm run prod
Build should be deployed to the server, Hence, I don't think that there is any inbuilt way in vue-cli to run build locally.
To run build locally, we need to configure the server separately and run the build on the server as follow,
1) Install lite server via below command
$ npm install -g lite-server
2) Add below scripts in package.json
"lite": "lite-server –port 10001",
"start": "npm run lite"
3) In root directory create bs-config.js file and add below script
module.exports = {
port: 3000,
server: {
baseDir: './dist'
}
}
4) Lastly, Run it via below command
$ npm run start

Heroku: How to deploy a node app with client and server running on different ports?

I have a nodejs API as server and React/Redux app as client located in one git project: https://github.com/lafisrap/fcc_nightlife.git
I want to deploy it on Heroku using the heroku cli.
The scripts section in package.json is:
"scripts": {
"start-dev": "concurrently \"yarn run server\" \"yarn run client\"",
"start": "yarn run server | yarn run client",
"server": "babel-node server.js",
"client": "node start-client.js",
"lint": "eslint ."
},
start-client.js:
const args = [ 'start' ];
const opts = { stdio: 'inherit', cwd: 'client', shell: true };
require('child_process').spawn('yarn', args, opts);
In the client folder I have another package.json which defines the client. The scripts section of it:
"scripts": {
"start": "react-scripts start",
}
I did:
heroku create
git push heroku master
The api is running fine. But I don't know how to start/access the client.
You CAN NOT deploy two services in one Heroku app. In short, you have to deploy them to separate Heroku dynos to deploy two apps.
More information is provided in this stackoverflow answer to a similar question.
PS: It is always an option to serve JS files from your API server after building React files.
Hope this helps!
This repo shows the setup of Node.js serving up a React frontend running on a single Heroku dyno: https://github.com/mars/heroku-cra-node I was able to get one up and running using this as a guide.
Actually you must not want to run on different ports. because of cors and other issues. Implement proxy in nodejs OR implement nginx as a gateway for both server and client requests.

Resources