I have a full web application using NodeJS, MongoDB (Mongoose as the driver) and ExpressJS.
The project works perfectly on my local machine. Today I decided to move everything to production. I'm using Google App Engine to host my application, and Compose (formally MongoHQ) to host my database.
App Engine servers my application perfectly, although my API does not seem to work. My API is served from example.com/api, and each request (GET, POST, DELETE and PUT) all returns a 502 (Bad Gateway) error.
I tried running my application on my local machine while connected to my remote MongoDB database and that worked perfectly fine. So it must be a problem with App Engine or NodeJS, not with MongoDB.
I have tried checking all error logs within Google Cloud, although there are no errors.
Why is App Engine/NodeJS serving my application's static content perfectly fine, although not allowing any requests to my API?
just make sure that your server listens on 8080 port
https://cloud.google.com/appengine/docs/flexible/custom-runtimes/build#listen_to_port_8080
502 Bad Gateway is usually an error on the Nginx side. Unfortunately those logs are not surfaced to Cloud Logging, yet.
A lot of times the problem is that your HTTP packets are too big for the buffers or something similar. The way you can see the nginx log is something like this:
Use just 1 VM. This isn't strictly necessary, but a lot of times it makes it easier to debug your application if you know that your requests on the one machine. You can accomplish this by adding this to your app.yaml:
manual_scaling:
instances: 1
then re-deploy
Switch the VM from "Google owned" to self-managed. This can be done in the Cloud Console. Go to Compute Engine, instances, click on the instance name that matches the App Engine version, and you should see an option to switch it to self-managed.
gcloud compute ssh <instance name> to SSH to the machine
docker ps to see your running containers. Look for the container named nginx and grab its id.
Once you have a container ID, you should be able to docker exec -it <container id> -- cat /var/log/nginx/error.log. You might want to ls that whole log directory.
You will likely see an error there which will be a bigger hint as to what's going wrong.
I know this is way more complicated than it should be :-\ If you have any problems with the steps above, leave a comment. If you do find an error and you're not sure what to do with it, also leave a comment.
I had the same problem, I was getting "nginx 502 bad gateway" error on GAE standard environment. There are many reasons for this but I finally got it working. Try these:
1) Run the app on the correct port. Google will set the PORT environment variable. I was running on port 8080, in the stackdriver logs I was getting this warning:
App is listening on port 8080. We recommend your app listen on the
port defined by the PORT environment variable to take advantage of an
NGINX layer on port 8080.
The code below gets the port from environment, if PORT is set otherwise defaults to 8080:
const PORT = process.env.PORT || 8080;
2) Go to google cloud console -> logging -> logs viewer. Select Google App Engine and then your service from the down and check you logs. Are you getting the requests at all or does it look like the requests do not react to your server. In my case, I was not getting them even after I fixed the port:
2020-03-02 21:50:07 backend[20200302t232314] Server listening on port
8081! 2020-03-02 21:50:08 backend[20200302t232314] "GET /create-user
HTTP/1.1" 502
Fix any error if it looks like your application is failing to start, throwing exceptions etc..
3) Don't pass an IP when you are running your server. It seems Google runs the app at a pre-defined IP address and do not want you to modify it:
server.listen(PORT);
4) Don't try to run on https! Google is running an nginx server in front of your app and it is handling the SSL and redirects to your app over http. You can use the environment variable NODE_ENV(it is set to "production" in GAE environment) to run on http on production and https elsewhere, like this:
let https = require('https');
let http = require('http');
if (process.env.NODE_ENV == "production") {
http.createServer(app).listen(PORT, function () {
console.log(`Server listening on port ${PORT}!`)
});
} else {
https.createServer({
key: fs.readFileSync('host.key'),
cert: fs.readFileSync('host.cert')
}, app).listen(PORT, function () {
console.log(`Server listening on port ${PORT}!`)
});
}
5) I didn't need to set any handlers in my yaml file, it might be causing errors for you if you have incorrect configuration. My yaml file is pretty straightforward:
runtime: nodejs12
env: standard
instance_class: F1
Related
I have a node app, that doesn't expose any port. It's just running some tasks in the background and returning some stuff onto the console that I occasionally need to look at.
I've deployed this onto Azure App Service - however it doesn't seem to run - in the logs I see
Waiting for response to warmup request for container xxx
I was wondering in my index.js I don't actually expose any port - namely there isn't a const server = http.createServer(). Is this required from Azure's side or can I disable it?
So my index.js literally looks like:
(async () => {
// Check some things and do something
}
Also, in the https://github.com/Azure-Samples/nodejs-docs-hello-world sample project there are the files:
web.config
process.json
Do I need these for the node app to run on Azure?
And finally, in teh sample node app above, it has const port = process.env.PORT || 1337; but where in Azure's portal is that being set? Or if its defaulting to 1337, how does Azure know that?
Any help appreciated.
Thanks.
If you just want to run some tasks in the background, you can use webjob instead. It is also very convenient to check the output.
By the way, the only ports open for Web Apps are 80 and 443. We should use process.env.PORT for nodejs app port. 1337 is for local test.
I have just started google app engine with nodejs. I have created a local project that works fine on my machine. And If I hit
http://localhost:7000/services/user/getuser
it returns a json object.
I have deployed the same project on google app engine using
gcloud app deploy
Now when I hit
http://help-coin.appspot.com/services/user/getuser
it is showing
Error: Server Error
The server encountered a temporary error and could not complete your request.
Please try again in 30 seconds.
I have checked the logs on server
Load controllers from path '/app/app/services' non recursive.
--------make-runnable-output--------
undefined
------------------------------------
Up and running on port 7000
Loading controller 'UserService.js'.
No error on the server side. What is this issue? Am I missing something?
Here is the project that I have deployed https://github.com/ermarkar/nodejs-typescript-sample
Your app must listen to 8080, not 7000 or any else port.
See this.
Listening to port 8080
The App Engine front end will route incoming requests to the appropriate module on port 8080. You must be sure that your application code is listening on 8080.
I'm trying to deploy a node.js app to a python Google Appengine application. The Node.js app is a custom runtime module, hosted in a Google Compute Engine VM.
I'm able to test it in localhost without any errors, but when I deploy to AppEngine and load a webpage, I get:
Error from HTTP-over-RPC proxy: No response
Has anyone else experienced this?
This error means that your app isn't responding to proxied requests.
The way that Managed VMs work is that your app runs inside a Docker container on a Google Compute Engine VM. This VM also runs a proxy that will direct external traffic on the appropriate port to the Docker container running your app. This error message indicates that there was no response from your app.
One possible cause is that your app is listening on the wrong port: are you respecting the $PORT environment variable?
You should also take a look at your application logs:
https://console.developers.google.com/project/<project>/appengine/logs
Take a look at the node.js "Hello World" app for an basic example with the ports correctly configured. Here's a relevant excerpt:
var server = app.listen(process.env.PORT || '8080',
'0.0.0.0',
function() {
console.log('App listening at http://%s:%s',
server.address().address,
server.address().port);
console.log("Press Ctrl+C to quit.");
});
I have set up up a node.js 0.10 gear in OpenShift which I deployed a simple server which is based off peerjs-server. All I want this server to do is act as a signalling server to communicate the connection info between peers connected to my application and from then on they communicate peer-to-peer using WebRTC. Everything works when pointing to the demo "PeerJS Cloud" signalling server but when trying to use my own server set up I keep getting returned 503 status codes.
Here is the server creation code I use:
var host = process.env.OPENSHIFT_NODEJS_IP;
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var server = new PeerServer({ port: port, host: host});
NB: I have added host to peerjs-server so I can use OpenShift's IP, not sure if this was necessary but it wasn't working without this either.
The server peerjs-server uses is restify. Here is the server create and listen code:
this._app = restify.createServer(this._options.ssl);
/* A lot of set up code that I have not changed from peerjs-server */
this._app.listen(this._options.port, this._options.host);
Where this._options.port and this._options.host are the ones defined in the previous code segment and I am not using SSL so nothing is being passed in there.
When deploying this code to OpenShift I get no errors but when accessing the site on port 80 or 8000 (the open external ports) I get 503's. I also checked rhc tail and this is what I get:
Screenshot (Can't post images because I have no reputation..). Not sure exactly what that means if anything.
Any help is much appreciated, and if more info is needed I can add more, was not sure what was important information or not.
UPDATE: It's a scaled application using 1-3 small gears.
from https://github.com/peers/peerjs-server/blob/master/lib/server.js:
// Listen on user-specified port and IP address.
if (this._options.ip) {
this._app.listen(this._options.port, this._options.ip);
} else {
this._app.listen(this._options.port);
}
So, use 'ip' and not 'host'. Worked for me.
I am building windows azure application which is primarily based on .NET, but I also have to build a socket.io server using node.js hence i need to deploy a socket.io server and use this socket.io url to connect in my .NET application.
I followed all the steps listed here . And I am able to get the socket.io running on my local but when i deploy to cloud, it doesnt start. Please find below a code snippet for socket.io
var app = require('express')()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server, { origins: '*:*' });
server.listen(4001);
When i hosted it in my local emulator, 127.0.0.1:81 was pointing to this in my browser
But 127.0.0.1:4001 showed "Cannot GET /" on the browser, which is an indicative that the socket.io server is running on that url.
But when i deploy the same to cloud, i get the same as the screenshot on the url where the cloud service is hosted but on port 4001 where the socket.io server should have started it says page cannot be displayed.
Please let me know if you need to see any other files like web.config etc.
I have been stuck on this issue from forever and its really crucial for my project, any suggestions or ideas would be deeply appreciated.
Thanks
The important part that you are missing from the sample is setting of the port number
var port = process.env.port || 1337;
and
.listen(port)
when you are running inside of the Azure environment (even emulated) the ports are assigned for you, the port environment variable will tell you where. 4001 is likely not the assigned port.
The 1337 would only be used if you are running by executing
node server.js
from the command line