I want to run multiple Node js apps on the same server, and so far I made some progress checking solutions for similar questions here (links below). Let's say I have 2 apps, each serving some html file, and I'd like to access each by visiting
https://example.com/app1 and
https://example.com/app2
So far, I have my main app, and my approach was to call this app which will then redirect a client to one of these 2 apps.
My main app looks like this:
const express = require('express');
const app = express();
app
.use('/app1', require('./app1/index.js'))
.use('/app2', require('./app2/index.js'))
.listen(80);
Each of my two sub-apps (app1 and app2) looks like this
const express = require('express');
const bodyParser = require('body-parser');
const routes = require('./routes/api');
const mongoose = require('mongoose');
require('dotenv/config');
const app = express();
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true, useUnifiedTopology: true }, () =>
console.log('Connected to DB')
);
mongoose.Promise = global.Promise;
app.use(express.static('public'));
app.use(bodyParser.json());
app.use('/', routes);
app.use(function (err, req, res, next) {
res.status(422).send({ error: err.message })
});
The issue is that I don't get anything after deploying these apps and visiting e.g. https://example.com/app1
I'm super new in all this so there is likely a beginner's mistake in here. Can anyone help?
Related questions How to mount express.js sub-apps? and Running multiple Node (Express) apps on same port
If you want to run totally different application in node you might use proxy_pass/reverse proxy of apache/nginx.
To do so each of your app should operate on theirs own ports and some other server (apache/nginx/etc) passing requests to each of them
example for apache: https://www.digitalocean.com/community/tutorials/how-to-use-apache-as-a-reverse-proxy-with-mod_proxy-on-ubuntu-16-04 sadly with python examples as apps, but the principle is the same.
example for nginx https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
Im hosting several node apps using this technique and they are working really nice (nginx is much faster than apache). Also you might thinking about blocking access from internet to node apps ports directly.
Related
I've built a web app with an express backend and using the ejs view engine.
When I run it on my computer it works fine but I'm trying to host in on digitalocean. I cloned it to the droplet(Ubuntu 22.10 x64) and served it on port 80. When I visited it in the browser at 46.101.145.210:80, I got these errors.
GET https://46.101.145.210/javascripts/cookieHandler.js net::ERR_CONNECTION_REFUSED
GET https://46.101.145.210/javascripts/domain.js net::ERR_CONNECTION_REFUSED
Here's my file structure,
Here's the code in index.js.
const express = require("express");
const app = express();
const fs = require("fs");
const path = require("path")
const assert = require("assert");
const PORT = 80
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use(express.static('public'));
app.set("view engine", "ejs")
app.listen(PORT, () => {
console.log("Server running on port " + PORT.toString());
});
const domains = ... // Not important
app.get("/", (req, res) => {
res.render("index")
//res.redirect("/domain")
})
app.get("/domain", (req, res) => {
res.render("domain", {domains: domains})
})
I've tinkered with the firewall config and the express.static to see if it would make a difference. I couldn't figure anything out though.
Update: I've checked the requests out a bit. They are https requests. When I use postman and change the request to be http it works.
I solved it by adding a valid ssl certificate.
Looking your file structure and the code, I can say, you must define the full path of the public directory using
express.static(__dirname+'/public')
Or can be like
const path = require('path');
// .... your code ...
app.use(express.static( path.join(__dirname, 'public') ));
with this you are forcing to define where the public directory is on the ubuntu, and validate you are accessing your files
Hope you can solve with this
Update: checking carefully, I can see that your are trying to request using https, but your code is working on port 80 (http), so you said, on postman worked without https because of the port. If you want to have working your code with port 443 (https), you must have a certificate (with domain but not required), then try with https://46.101.145.210/javascripts/cookieHandler.js otherwhise try http://46.101.145.210/javascripts/cookieHandler.js.
I want to merge three small, separate Express.js apps (with separate functionality/sockets) into one application by creating a landing page with three buttons that will redirect to each while passing some context. Each individual app has a server.js file that will serve its own client-side files.
server.js example:
const express = require("express");
const app = express();
const httpServer = require("http").createServer(app);
const io = require("socket.io")(httpServer, {cors: {origin: "*"}});
io.on("connection", socket => {
// socket events
});
app.use(express.static("public"));
httpServer.listen(3000, () => {
console.log("Server running on port 3000.")
});
I'm thinking of creating a "main" server that specifies routes to each individual app (e.g. app.get('/app1), app.get('/app2) ...) but I'm not really piecing together how to execute the server.js file in each of the individual apps upon navigation. Any pointers are appreciated.
I have a custom domain set up in Heroku which works fine.
I can access my site using both my app name and custom domain.
I can access a route using my standard Heroku URL, but not using the custom domain.
For example:
Works:
https://{myappname}.herokuapp.com
https://{myappname}.herokuapp.com/callback
https://{customdomain}.com
Does not work:
https://{customdomain}.com/callback
Server config:
const express = require("express");
const path = require("path");;
const callback = require("./callback");
const app = express();
// Body parser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Serve static assets if in production
if (process.env.NODE_ENV === "production") {
app.use("/callback", callback);
// Set static folder
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
// Init server/port
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));
I know its too late but I am writing for those who face this issue in the future.
I was also facing this issue and solved through this.
Was Not Working
https://{customdomain}.com/callback
This Worked for me.
https://www.{customdomain}.com/callback
I figured this out, it was pretty simple and I feel stupid, however I will answer this here in case anyone ever has the same issue.
Problem:
I had a React route/component called Callback. This React component was calling a Node.js route also called Callback, which processes information then redirects to a new React route/component.
Simple fix was to change my React route/component to callbackPage, leaving my Node.js route as Callback.
So in summary, I had a webpage URL with the same name as a server API route. when I visited this page, instead of the page being rendered, the API route was run and basically did nothing and timed out. I'm still confused as to why it worked with my app URL but not my custom domain.
I'm trying to follow Crowdbotics' Messenger bot tutorial, however. I did exactly as he mentioned but i am getting this.
My folder:
Okay so, first of all i run node index.js and get the following:
Right after that. We initialize our ngrok server by ngrok http 5000 and get the following:
But on EVERY http request i get the classic Cannot GET /.
On the hindsight, my index.js only contain:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.listen(5000, () => console.log('Webhook server is listening, port 5000'));
I can't really point out what i am doing wrong, your help is truly appreciated.
Based on your express js code, I think you haven't define the routes to '/'
add this before the app.listen on the index.js file
app.get('/', (req, res) => res.send('Hello World!'))
Your index.js has started a server that listens and respond to the HTTP protocol - but it does not "serve files" the same way a web server such as Apache does.
As #Yana notes, you need to explicitly set a route to do something, such as send a text response back.
If you want the favicon.ico file to be sent when requested, then you need to setup a static route for that as part of your index.js code.
I try to connect backend (NodeJS, Express) with Frontend (Angular 2), but have a problem.
When I start two servers separately, both client-side and server-side work fine.
In my situation:
localhost:4200 - Angular
localhost:3000 - NodeJS, Express
When I render any static html file in my VIEWS folder, it works correctly, but when I change the content of the html file to Angular Index.html, that uses components, it doesn’t work. I mean, it works, but doesn't load my components.
I suppose that problem is in the configuration, and my index.html doesn't know how to find and load components, but I don’t understand exactly where a mistake might be.
When I try to start both servers at the same port, my frontend part stops working.
I use Angular-CLI, NodeJS, Express and EJS.
My server.js code is:
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var tasks = require('./routes/tasks');
var port = 3000;
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view enjine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(express.static(path.join(__dirname, 'views')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use('/', index);
app.use('/api', tasks);
app.listen(port, function () {
console.log('Server started on port ' + port);
});
In the ROUTES folder my index.js code is:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index.html');
});
module.exports = router;
My folders structure:
Picture of foldes
node_modules
routes
ruen-app
views
package.json
server.js
ruen-app is my client (Angular 2) folder.
So, my questions are:
How to connect these two parts?
Is it correct to start two servers at the same time - one for the frontend, another for the backend?
What is the best practice for MEAN applications to start from the scratch? I mean, what is the best way - two servers or one?
Spent 3 days, but found the solution.
On the stackoverflow:
Different ports for frontend and backend. How to make a request?
Angular-CLI proxy to backend doesn't work