Good day,
my very basic Nodejs app is deployed on a Google Cloud App Engine instance is not starting. The app works locally, deployment with app deploy runs without error - and on the app instance the app runs successfully when started manually through Cloud shell (with >npm start).
However, as soon as the Cloud Shell is closed my app is dead. What am I missing? How do I start-up the app to run permanently?
The app consists of
bot4.js file,
npm dependencies
app.yaml
package.json
app.yaml:
runtime: nodejs8
handlers:
- url: /
script: auto
package.json:
{
"name": "blexplorer",
"version": "1.0.0",
"description": "",
"main": "bot4.js",
"scripts": {
"start": "node bot4.js"
},
"author": "oystersauce",
"license": "ISC",
"dependencies": {
"discord.js": "^11.4.2",
"request": "^2.88.0"
}
}
Again, the app is running fine when started through the Cloud Shell but no longer, as soon as the Cloud Shell is closed. Also, it's a super simple discord-bot - hence there is no front-end whatsoever.
EDIT:
this is how I thought I started the app manually - but what I did here is starting the app within the cloud shell and not on the app instance:
here is how I deploy the app:
From GAE perspective the cloud shell is simply a shell on a "local" development machine which just happens to be hosted in the cloud. The instance running the cloud shell has no special relationship with GAE whatsoever.
What you're doing when running npm start is not actually starting the GAE instance, you're just starting a "local" execution of your service, just like when you'd be doing the same on your local machine.
With your configuration GAE should start your app automatically as soon a request for it is received. On an app with a frontend just clicking on the link you circled in the snapshot would get you on it. Since yours doesn't have a frontend it would probably be just started, but you'd have to rely on the dashboard info and/or your app's logs to confirm it is running.
Related
I am trying to integrate PM2 to Google Cloud App Engine but I just couldn't work it around. I am using PM2 for my site's staging site and I am very impressed with it. I use Digital Ocean droplet for staging. I realized that Google Cloud App Engine is not that flexible.
This is my package.json:
"main": "server.js",
"scripts": {
"start": "NODE_ENV=production npm run server:prod",
"server:prod": "node server.js",
"server:stage": "NODE_ENV=stage pm2 start server.js --exp-backoff-restart-delay=100 -i max",
"dev": "nodemon server.js",
"gcp-deploy-stage": "gcloud app deploy app.backend.stage.yaml --project=xxxxx",
"gcp-deploy-prod": "gcloud app deploy app.backend.prod.yaml --project=xxxx -v=alpha-16"
},
When I set production script start as staging like this:
"server:prod":"pm2 start server.js --exp-backoff-restart-delay=100 -i max"
and deploy this Google Cloud App Engine normally crashes because there is no global PM2 installed via NPM to start PM2.
Is there anybody went through this and made it work? Or any piece of code or any documentation that could lead me to the right solution?
Or the only option is migrating this to Google Cloud Compute Engine?
Thank you for reading this and your help.
If you want to use any module, you're going to have to include it in your package.json. Have you tried running npm install --save-dev pm2, and then redeploying your site? My guess is, that's going to get you where you want to go.
All of that aside - this probably isn't a good idea :) pm2 does a lot to manage processes on the machine, specifically dealing with crashes. App Engine Flexible does a lot of this at the infrastructure layer, automatically looking at instance health. It uses docker under the hood, which has it's own restart strategy. And then on top of that, if the the docker retry strategy doesn't work, the Google Load Balancer kicks in and will start a new compute instance for you. It's entirely possible doing process level monitoring and restarting like this will work, I just want to make sure you understand everything else that's happening under the hood.
Curiosity killed the cat - why did you end up going with App Engine Flexible over App Engine Standard?
I can run the app locally without any issue by yarn start command. here I have provided photographs which represent my problem. I googled and noticed several people faces the same problem. but their context is different.
By default, Now publishes your files as a static directory. You can add a builder to your now.json file to tell Now how to build and deploy your site.
In a case where app.js contains a web server application, your now.json might look like this:
{
"version": 2,
"name": "my-project",
"builds": [
{"src": "app.js", "use": "#now/node"}
]
}
This tells Now to use the #now/node builder to generate a lambda that runs app.js to respond to requests.
If your app is purely js+html to be run on the client machine, you wouldn't need the lambda, but you can still build the source before deploying it as static files with #now/static-build.
Check out the Now docs for more info: https://zeit.co/docs/v2/deployments/basics/#introducing-a-build-step
I have a node application on GAE (Google App Engine) flex environment. In the code, package.json specifies: "node": "8.11.4":
{
"name": "prismic-universal-app",
"version": "1.0.0",
"description": "",
"main": "public/js/compiled/server.js",
"engines": {
"node": "8.11.4"
},
"scripts": {
...
But when I open a Cloud Shell window from the google cloud console the project and run 'node --version', I get v8.9.4
Reading through google's documentation, I don't see anything yet about using a different version from what's in package.json. Does anyone know if google has another way to determine what version of node will ultimately be used? Or is there another spot where Node.js version can be set that may be conflicting with package.json?
The Cloud Shell is a GCP product separate from GAE (flexible). It does not execute on your GAE flexible app instance. From Virtual machine instance:
When you start Cloud Shell, it provisions a g1-small Google Compute
Engine virtual machine running a Debian-based Linux operating
system.
The info you obtained is from that VM.
To check the info on your GAE flexible app instance, you need to connect to it specifically, see Connecting to the instance.
I am trying to deploy my Meteor React app on Google's cloud but when I try deploying it, I get the error saying that MONGO_URL needs to be specified. I build my meteor app and cd to my bundle folder where I do gcloud app deploy. Here is my package.json
{
"private": true,
"scripts": {
"start": "node main.js",
"install": "(cd programs/server && npm install)"
},
"engines": {
"node": "6.6.0"
}
}
How can I find out my meteor mongo username and password. Running regular meteor did not ask me for my username and password. And here is my app.yaml
runtime: nodejs
env: flex
threadsafe: true
automatic_scaling:
max_num_instances: 1
env_variables:
MONGO_URL: 'mongodb://[user]:[pass]#[host]:[port]/[db]'
ROOT_URL: 'https://...'
METEOR_SETTINGS: '{}'
I don't know what to put for MONGO_URL and ROOT_URL if I am deploying on gcloud. Also I have settings file for my project. Should it go under METER_SETTINGS in app.yaml? I apologize for asking too many question but this is my first time dealing with gcloud :)
This question is a little old, but it's still getting some views from Google so let's answer by parts, first you need to understand how Meteor interacts with MongoDB in development and production. When you're coding your app, just executing meteor run does all the magic, because Meteor deploys an internal MongoDB. This is not recommended for real production usage and won't work well under any container based architecture (such as Docker, Google App Engine, Heroku etc.).
Given that, you'll need to deploy a separate instance in Google Compute Engine based on MongoDB. Google has them ready to launch in the Google Cloud Launcher, just search for "MongoDB".
I recommend the Bitnami's one, which is easier to configure if you're just beginning.
Google will create an instance automatically and you'll be given a root username and password, alongside a public IP address to connect to the instance.
Run the command below to access Mongo from a terminal:
# Use this template for the command
mongo "mongodb://root:PASSWORD#IP_ADDRESS/" --authenticationDatabase admin
# For example, with sample values
mongo "mongodb://root:8sdjkfh8876#127.0.0.1/" --authenticationDatabase admin
Now, create a new user for Meteor to connect on your newly created database. Never give it the root credentials, it won't work and it's not safe. For example, naming the database as myapp.
use myapp;
db.createUser({
user: "meteor_app",
pwd: "A_SECURE_PASSWORD",
roles: [ "readWrite", "dbAdmin" ]
})
Now, you exit this connection and test your new user.
mongo "mongodb://meteor_app:A_SECURE_PASSWORD#IP_ADDRESS/myapp"
If everything is OK, you now have your MONGO_URL.
# Put this in the app.yaml file, env variables sections
MONGO_URL: "mongodb://meteor_app:A_SECURE_PASSWORD#IP_ADDRESS/myapp"
I'm struggling to figure out how to deploy multiple nodejs services on google app engine flexible.
I'm using multiple nodejs classes with firebase-queue to process my tasks.
Right now, i'm using my package.json to trigger starting everything at once.
However, this has become problematic. I would like to be able to push a change to one particular service/script without having to stop every other script.
My package.json currently looks like something like this:
"scripts": {
"task1": "node ./src/task1.js",
"task2": "node ./src/task2.js",
"start": "npm-run-all -p task1 task2"
}
I'm using different .yaml files to determine which build variant I want to push (Debug or Release) but am finding it hard to deploy each task individually. I found documentation on how to do so in python, but nothing on nodejs. Does anyone have any suggestions?
(Answering my own question, big thanks to Justin for helping)
I was specifically having issues dynamically changing the script to start in my package.json.
I found the package.json can access environment variables using '$'
package.json:
"scripts": {
"start": "node $SCRIPT_TO_RUN"
}
myService.yaml
runtime: nodejs
vm: true
api_version: 1
instance_class: B4
manual_scaling:
instances: 1
service: cart-monitor-dev
env_variables:
SCRIPT_TO_RUN: './src/mytask.js'
Then deploy using:
gcloud app deploy myService.yaml
This is exactly why App Engine services exist :) You can create a {serviceName}.yaml for each service you want to deploy. Then, call gcloud app deploy service.yaml for each one. That creates multiple services in the same app. For an example see:
https://github.com/JustinBeckwith/cloudcats
Hope this helps!