I am running a node/express react app, with mongoDB as my database, its being served on a EC2 instance AWS. I am using MobaXterm to ssh into my server. The problem I am encountering, when I go to signUp/Login, and it makes the http request, its not sending the Request to port:8081 where my DB is. My front end is being hosted on port:3000, as seen here url with port.
The home page of my app show display public content, but instead it shows this should display my content, instead displays html syntax. I am using PM2 to run both the front end and back end , they are 2 separate instances. Here is my ecosystem.config.js file that gets called to start the front end
module.exports = {
apps: [
{
name: 'frontend',
script: 'npx',
args: 'serve -s build -l 3000 -n',
interpreter: 'none',
env: {
NODE_ENV: 'production',
},
},
],
}
Here is my http-common.js file that sets up axios
import axios from 'axios';
const apiUrl = process.env.NODE_ENV === 'production' ? process.env.REACT_APP_PRODUCTION : process.env.REACT_APP_DEV;
export default axios.create({
baseURL: apiUrl,
headers: {
"Content-type": "application/json"
}
});
Here is where my public content on my home page is called
import http from '../http-common';
import authHeader from './auth-header';
class UserService {
getPublicContent() {
return http.get('api/test/all');
};
getUserBoard() {
return http.get('api/test/user', { headers: authHeader() });
};
getModeratorBoard() {
return http.post('api/test/mod', { headers: authHeader() });
};
getAdminBoard() {
return http.put('api/test/admin', { headers: authHeader() });
};
}
export default UserService;
and my .env.production file
REACT_APP_PRODUCTION=http://EC2-INSTANCE-URL-NOT-REAL:8081/
And you can see here that instead of the REQUEST using port:8081 it sends the request to port:3000
GET request to wrong port
**** Also my ports are open on 8081 , on the security group for the EC2 instance ***
Im new to the backend so im not sure what to do , or how to continue, I really want to have my project CI/CD working before I try to make any more progress.
I have set up several Nuxt applications using ExpressJS on Nuxt version 2.12.x, but the option is no longer present in the configuration setup with npx create-nuxt-app.
Previously, create-nuxt-app created a file server/index.js like this:
const express = require('express')
const consola = require('consola')
const { Nuxt, Builder } = require('nuxt')
const app = express()
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js')
config.dev = process.env.NODE_ENV !== 'production'
async function start() {
// Init Nuxt.js
const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server
await nuxt.ready()
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
// Give nuxt middleware to express
app.use(nuxt.render)
// Listen the server
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
})
}
start()
However, using create-nuxt-app with Nuxt version 2.13.2 no longer creates this server/index.js file. I have tried creating a server/index.js file and also server.js and neither change the default behavior of the nuxt command.
How can I configure my nuxt app to use Express other than downgrading to 2.12?
Please go through this below link:
https://nuxtjs.org/api/configuration-servermiddleware/
You just need to define the parameter named serverMiddleware in the nuxt.config.js file, and the value of this parameter is the path to your server/index.js file.
I'm building a that aims to serve a mobile application. Besides serving the client, it will have several back-office functionalities.
We are using swagger and we do want to be able to access the swagger docs of our back-office endpoints. However, we do not want to expose all of our endpoints publicly.
Assuming that having all endpoints public is a bad option one solutions we are thinking of is letting our server serve two ports, and then only exposing one port to the public. We have created a small sample repo that that serves a client module and a back-office module on two different ports.
The main.ts looks like the following:
import { NestFactory } from '#nestjs/core';
import { ClientModule } from './modules/client/client.module';
import * as express from 'express';
import * as http from 'http';
import {ExpressAdapter} from '#nestjs/platform-express';
import { BackOfficeModule } from './modules/backoffice/backoffice.module';
import { SwaggerModule, DocumentBuilder } from '#nestjs/swagger';
async function bootstrap() {
const clientServer = express();
const clientApp = await NestFactory.create(
ClientModule,
new ExpressAdapter(clientServer),
);
const clientOptions = new DocumentBuilder()
.setTitle('ClientServer')
.setDescription('The client server API description')
.setVersion('1.0')
.addTag('client')
.build();
const clientDocument = SwaggerModule.createDocument(clientApp, clientOptions);
SwaggerModule.setup('api', clientApp, clientDocument);
await clientApp.init();
const backOfficeServer = express();
const backOfficeApp = await NestFactory.create(
BackOfficeModule,
new ExpressAdapter(backOfficeServer),
);
const backOfficeOptions = new DocumentBuilder()
.setTitle('BackOffice')
.setDescription('The back office API description')
.setVersion('1.0')
.addTag('backOffice')
.build();
const backOfficeDocument = SwaggerModule.createDocument(backOfficeApp, backOfficeOptions);
SwaggerModule.setup('api', backOfficeApp, backOfficeDocument);
await backOfficeApp.init();
http.createServer(clientServer).listen(3000); // The public port (Load balancer will route traffic to this port)
http.createServer(backOfficeServer).listen(4000); // The private port (Will be accessed through a bastian host or similar)
}
bootstrap();
Another option would be to create a bigger separation of the codebase and infrastructure, however as this is a very early stage we feel that is unnecessary.
Our question to the Nest community is thus, has anyone done this? If so, what is are your experience? What are the drawbacks to separating our backend code like this?
Disclaimer: this solution is for express+REST combination.
Routing
Even thought nestjs can't separate controller's based on port, it can separate them based on host. Using that, you can add a reverse proxy in front of your application, that modifies the host header based on the port. Or, you can do that in an express middleware, to make things even more simpe. This is what I did:
async function bootstrap() {
const publicPort = 3000
const privatePort = 4000
const server = express()
server.use((req, res, next) => {
// act as a proper reverse proxy and set X-Forwarded-Host header if it hasn't been set
req.headers['x-forwarded-host'] ??= req.headers.host
switch (req.socket.localPort) {
case publicPort:
req.headers.host = 'public'
break
case privatePort:
req.headers.host = 'private'
break
default:
// this shouldn't be possible
res.sendStatus(500)
return
}
next()
})
const app = await NestFactory.create(AppModule, new ExpressAdapter(server))
http.createServer(server).listen(publicPort)
http.createServer(server).listen(privatePort)
}
Controllers:
#Controller({ path: 'cats', host: 'public' })
export class CatsController {...}
#Controller({ path: 'internal' host: 'private' })
export class InternalController {...}
Alternatively, you can simplify by creating your own PublicController and PrivateController decorators:
// decorator for public controllers, also sets guard
export const PublicController = (path?: string): ClassDecorator => {
return applyDecorators(Controller({ path, host: 'public' }), UseGuards(JwtAuthGuard))
}
// decorator for private controllers
export const PrivateController = (path?: string): ClassDecorator => {
return applyDecorators(Controller({ path, host: 'private' }))
}
#PublicController('cats')
export class CatsController {...}
#PrivateController('internal')
export class InternalController {...}
Swagger
For swagger, SwaggerModule.createDocument has an option "include", which accepts a list of modules to include in the swagger docs. With a bit of effort we can also turn the swagger serving part into an express Router, so both the private and public swagger can be served on the same path, for the different ports:
async function bootstrap() {
const publicPort = 3000
const privatePort = 4000
const server = express()
server.use((req, res, next) => {
// act as a proper reverse proxy and set X-Forwarded-Host header if it hasn't been set
req.headers['x-forwarded-host'] ??= req.headers.host
switch (req.socket.localPort) {
case publicPort:
req.headers.host = 'public'
break
case privatePort:
req.headers.host = 'private'
break
default:
// this shouldn't be possible
res.sendStatus(500)
return
}
next()
})
const app = await NestFactory.create(AppModule, new ExpressAdapter(server))
// setup swagger
let publicSwaggerRouter = await createSwaggerRouter(app, [CatsModule])
let privateSwaggerRouter: await createSwaggerRouter(app, [InternalModule])
server.use('/api', (req: Request, res: Response, next: NextFunction) => {
switch (req.headers.host) {
case 'public':
publicSwaggerRouter(req, res, next)
return
case 'private':
privateSwaggerRouter(req, res, next)
return
default:
// this shouldn't be possible
res.sendStatus(500)
return
}
})
http.createServer(server).listen(publicPort)
http.createServer(server).listen(privatePort)
}
async function createSwaggerRouter(app: INestApplication, modules: Function[]): Promise<Router> {
const swaggerConfig = new DocumentBuilder().setTitle('MyApp').setVersion('1.0').build()
const document = SwaggerModule.createDocument(app, swaggerConfig, { include: modules })
const swaggerUi = loadPackage('swagger-ui-express', 'SwaggerModule', () => require('swagger-ui-express'))
const swaggerHtml = swaggerUi.generateHTML(document)
const router = Router()
.use(swaggerUi.serveFiles(document))
.get('/', (req: Request, res: Response, next: NextFunction) => {
res.send(swaggerHtml)
})
return router
}
That's ok, but if you want to run two servers on 1 host, I would recommend to create two files like main-client.ts and main-back-office.ts and run them in different processes, because in that case failures of one server would not affect work of another.
Also if you are not run this in Docker I would suggest tools like forever, pm2, supervisor or my own very small library workers-cluster
If you run it in Docker and don't want big refactoring, I would recommend to create
single Dockerfile with running different CMD or ENTRYPOINT commands
The NestJS docs cover how to let one server serve multiple ports:
https://docs.nestjs.com/faq/multiple-servers#multiple-simultaneous-servers
The following recipe shows how to instantiate a Nest application that listens on multiple ports (for example, on a non-HTTPS port and an HTTPS port) simultaneously.
const httpsOptions = {
key: fs.readFileSync('./secrets/private-key.pem'),
cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const server = express();
const app = await NestFactory.create(
ApplicationModule,
new ExpressAdapter(server),
);
await app.init();
http.createServer(server).listen(3000);
https.createServer(httpsOptions, server).listen(443);
I'm using Neutrino as scaffolding tool for Webpack 3.1 and I'm looking for a proper Neutrino preset that combines Express and Webpack so that I see a 'Hello World' website. If someone gives me one proper preset and tells me how to install it, I'll accept this as an answer.
Thank you!
This should already be possible with the #neutrinojs/node preset:
// src/index.js
import express from 'express';
import { join } from 'path';
const port = process.env.PORT || 3000;
const app = express();
app.get('/', (request, response) => {
response.sendFile(join(__dirname, 'index.html'));
});
app.listen(port, () => console.log(`Server running on port ${port}`));
I follow this tutorial to create Gun server. But I need to do it with Hapi.
Now, I get the following error:
> node server.js
Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!
0.8 WARNING! Breaking changes, test that your app works before upgrading! The adapter interface has been upgraded (non-default storage and transport layers probably won't work). Also, `.path()` and `.not()` are outside core and now in 'lib/'.
WARNING! This `file.js` module for gun is intended for local development testing only!
/home/trex/dev/learn/gun/server/server.js:17
gun.wsp(server);
^
TypeError: gun.wsp is not a function
at Object.<anonymous> (/home/trex/dev/learn/gun/server/server.js:17:5)
Server source code:
const Hapi = require('hapi');
const Gun = require('gun');
const gun = new Gun();
const server = new Hapi.Server();
server.connection({ port: 3000, host: 'localhost' });
server.ext('onRequest', () => gun.wsp.server);
gun.wsp(server);
server.start((err) => {
if (err) {
throw err;
}
console.log(`Server running at: ${server.info.uri}`);
});
What is wrong here?
The bug solved in gun 0.8.8 https://github.com/amark/gun/pull/423
const Hapi = require('hapi');
const Inert = require('inert');
const Gun = require('../gun/');
const server = new Hapi.Server;
server.connection({ port: 8080 });
server.connections.forEach(c => Gun({ web: c.listener, file: 'data.json' }));
server.register(Inert, () => {});
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: __dirname,
redirectToSlash: true,
index: true
}
}
});
server.start();