I'm rather new to NodeJS and I'd like to deploy the API and the application on the same server, which means same IP but on different ports.
From different search I saw it's possible but I don't know how.
Can I use Restify for this redirection ?
in this code app.listen(PORT HERE); on your two apps just define a different ports for each one.
For example
in App1 = app.listen(3000);
in App2 = app.listen(8000);
then to access each one is like :
App1 = http://localhost:3000
App2 = http://localhost:8000
Related
I'm starting out learning Linux and NodeJS development and part of my current project has an API for which I'm serving documentation with Swagger UI. To support the "try it out" functionality of Swagger I need to specify a host name of the server in the API specs. Everything works fine when I'm running things locally and have the server hard coded to localhost:3000, but in production I obviously want this to show up as myactualdomain.example and not localhost.
Is there a convention for communicating to domain name of a server back to itself? I tried using a HOSTNAME environment variable as follows:
const HOSTNAME = process.env.HOSTNAME || "localhost";
var PORT = process.env.PORT || 80;
const apiSpecs = YAML.load("./api-spec.yml");
apiSpecs.servers = [{ url: `http://${HOSTNAME}:${PORT}` }];
app.use("/api-docs", swaggerUI.serve, swaggerUI.setup(apiSpecs));
This works, but sets the URL to the random host name the Docker container my app is running in is assigned. I could of course override HOSTNAME to myactualdomain.example but I'm not sure if this is "correct" way to do this or if the convention is to use a different environment variable or use another method entirely?
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'm trying to run 2 instances of NodeJS on the same port and server from diffrent server.js files (diffrent dir, config etc). My server provider gave me an information that vhost is running for a diffrent domain, and there is the question. How to handle it in NodeJS Express app ? I've tried to use vhost from https://github.com/expressjs/vhost like that :
const app = express();
const vhost = require('vhost');
app.use(vhost('example1.org', app));
// Start up the Node server
app.listen(4100, () => {
console.log(`Node server listening on 4100`);
});
And for second application like that:
const app = express();
const vhost = require('vhost');
app.use(vhost('example2.org', app));
// Start up the Node server
app.listen(4100, () => {
console.log(`Node server listening on 4100`);
});
But when I'm trying to run second instance I'm getting EADDRINUSE ::: 4100, so vhost doesn't work here.
Do you know how to fix it ?
You can only have one process listen to one port, not just in Node.js, but generally (with exceptions that don't apply here).
You can achieve what you need to one of two ways:
Combine the node apps
You could make the apps into one application, listen once and then forward requests for each host to separate bits of code - if you wanted to achieve code separation still, the separate bits of code could be NPM modules that are actually written and maintained in isolation.
Use webserver to proxy the requests
You could run the 2 node processes on some free port, say 5000 and 5001, and use a webserver to forward requests to it automatically based on host. I'd recommend Nginx for this, as its proxying capabilities are both relatively easy to set up, and powerful. It's also fairly good at not using too many system resources. Apache and others can also be used for this, but my personal preference would be Nginx.
Conclusion
My recommendation would be that you install a webserver and forward requests on the exposed port to the separately running node processes. I'd actually recommend that you run node behind a proxy as default for a project, and only expose it directly in excpetional circumstances. You get a lot of configuration options, security, and scalability benefits if your app already involves a well hardened server setup.
I'm currently running two StrongLoop LoopBack apps (Nodejs apps) on a single server with different ports. Both apps were created using slc lb project and slc lb model from the command line.
Is it possible to run these apps on a single ports with different path and/or subdomain? If it is, how do I do that on a Linux machine?
Example:
http://api.server.com:3000/app1/ for first app.
http://api.server.com:3000/app2/ for second app.
thanks.
Since LoopBack applications are regular Express applications, you can mount them on a path of the master app.
var app1 = require('path/to/app1');
var app2 = require('path/to/app2');
var root = loopback(); // or express();
root.use('/app1', app1);
root.use('/app2', app2);
root.listen(3000);
The obvious drawback is high runtime coupling between app1 and app2 - whenever you are upgrading either of them, you have to restart the whole server (i.e. both of them). Also a fatal failure in one app brings down the whole server.
The solution presented by #fiskeben is more robust, since each app is isolated.
On the other hand, my solution is probably easier to manage (you have only one Node process instead of nginx + per-app Node processes) and also allows you to configure middleware shared by both apps.
var root = loopback();
root.use(express.logger());
// etc.
root.use('/app1', app1);
root.use('/app2', app2);
root.listen(3000);
You would need some sort of proxy in front of your server, for example nginx. nginx will listen to a port (say, 80) and redirect incoming requests to other servers on the machine based on some rules you define (hostname, path, headers, etc).
I'm no expert on nginx but I would configure it something like this:
server {
listen: 80;
server_name api.server.com;
location /app1 {
proxy_pass http://localhost:3000
}
location /app2 {
proxy_pass http://localhost:3001
}
}
nginx also supports passing query strings, paths and everything else, but I'll leave it up to you to put the pieces together :)
Look at the proxy server documentation for nginx.
I'm planning to do three sites using node.js. I have got some common templates among the sites. Should I run all three sites on single node.js instance?
I'm aware of 'vhost' middleware that allows you to run multiple domains on single http server. Is there any better option to do this?
I've also got some static html templates and not sure how to deal with these in node.js?
Finally I would like to know hosting options for this kind of setup?
I myself just had to do this exact same thing. What you want to do is use some sort of reverse proxy.
The one I use is here: https://github.com/nodejitsu/node-http-proxy
Simply install the proxy package: npm install http-proxy
What I do is have the proxy running on the server on port 80. I set the DNS up on each domain to point to this server.
Each application is running on the same server (im using screens).
For example:
MySiteApplication1 - 3001
MySiteApplication2 - 3002
MySiteApplication3 - 3003
Then your proxy server file would look like this
var httpProxy = require('http-proxy');
var server = httpProxy.createServer({
router: {
'mysite1.com': 'localhost:3001',
'mysite2.com': 'localhost:3002',
'mysite3.com': 'localhost:3003'
}
});
server.listen 80