Express.js routes do not work in docker container - javascript

When I run my Express.js application with node app.js everything works as expected, including this example route:
router.get('/config/get', function(req, res, next) {
return res.json("hi");
});
However, when I build my docker image and run it, my browsers shows me my index page on this route. In fact, it shows my index page at pretty much every single route, nomatter if I set it up or not. So when I go to /this/route/is/non-existing/ I see my index page as well. This only works through docker. When I visit this page by running the node application without docker, I get a 404.
Be aware that I use connect-history-api-fallback for my vue.js frontend. My app.js looks like this:
require('dotenv').config()
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var history = require('connect-history-api-fallback');
var app = express();
// history mode for making vue.js router work: https://router.vuejs.org/guide/essentials/history-mode.html
app.use(history());
history({
index: '/dist/index.html'
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/', indexRouter);
// serving vue.js prod build
app.use(express.static('dist'));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
app.listen(process.env.PORT, () => console.log(`${process.env.NAME} listening on port ${process.env.PORT}!`))
This is my Dockerfile:
FROM node:10
# Create app directory
WORKDIR /usr/src/app
# use non-root user to run commands and give him chown permissions for the directory
USER node
COPY --chown=node:node ./backend .
EXPOSE 8080
CMD [ "node", "app.js" ]

Related

A routing problem with workbox vuejs in production and express

I am creating a forum application to learn about VueRouter in Express. What I am trying to do is create a routing in vuejs and then take it to production. When I compile everything works fine. The view files go directly to the public folder in express and work almost perfect. I can change the route perfectly but when I touch CTRL + F5 from a different route to the main one, it returns a GET error.
For example this is my index and work perfect:
I can even change the route:
I touch F5 and reload the page without any problem, but when I touch CTRL + F5 to make the request again, obviously it returns an error because I don't have the route declared in express,
but vuejs returns only one html index as a view, I can't render any other files because they don't exist.
These public folder at image are the files created by vue by the build command:
This is my express configuration:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersNotifications = require('./routes/notifications');
var usersNotifications = require('./routes/notifications');
var app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/notifications', usersNotifications);
module.exports = app;
this is my index route on express:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
The only option I have is to render the only index that vuejs offers. How can i Fix that?
The other problem is that I would not like these console workbox messages, how can i remove them so they never appear:
and this is the vuejs registerServiceWorkers.js file:
/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
/***
* Note that here were some methods also display messages
* on the console and I deleted them. Methods like
*/
})
}
Any ideas?
Since vue router is handling page routing, you'll have to render index for all requested paths like:
router.get('*', function(req, res, next) {
res.render('index');
});
// in server
app.use('*', indexRouter);
If you're exposing other endpoints from server you'll have to mount this as the last route middleware like, say in your case:
app.use('/notifications', usersNotifications);
app.use('*', indexRouter);

TypeError: Router.use() requires a middleware function but got a Object nodejs [duplicate]

I am getting this error when I run npm start to run my express app.
TypeError: Router.use() requires middleware function but got a Object
my app.js code
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
my index.js code
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});
/* GET Hello World page. */
router.get('/helloworld', function(req, res) {
res.render('helloworld', { title: 'Hello, World!' })
});
module.exports = router;
I am quirte new to using Node and express. I cant see where I have gone wrong. Can anybody see what my problem is?
I found the answer in the comments from Kop4lyf:
check your users.js. It should also be exporting the router like
index.js, if you can try that.
However, this question was my top search result when I ran into this issue, so I am promoting to an answer.
The error is caused because one of your route modules is not being exported - meaning Express does not have access to it when it tries to identify all of your routes.
You can fix this by adding module.exports = router; to the end of each of your route files.
Example:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
//Do whatever...
});
module.exports = router;
More information about module.exports can be found on this question or the offcial Node.js documentation.
I have fixed this by adding which i am using somewhere. So please check your all exports.
module.exports = router;
If you use in routes
exports default router
Your solution can be
module.exports = router
I had the same error , fixed it by replacing app.use('view engine', 'ejs') with app.set('view engine', 'ejs').
For reference I used this webpage Migrating from 3.x to 4.x
I didn't have to make any changes to either index.js or application.js. For more information on EJS one could refer Using EJS with Express and Express 4.x API
Your index.js file is fine you just have to create users.js and export it.
let express = require('express');
let router = express.Router();
//Login Page - GET REQUEST
router.get('/login',(req,res)=> {
res.send('login page');
})
//Register Page - GET REQUEST
router.get('/register',(req,res)=> {
res.send('register page');
});
module.exports = router;
in every module **export the router** and **keep one handler for the default
path '/'**
// in index.js
const authRoute = require("./routes/authRoute");
app.use("/auth", authRoute);
// in authRoute.js
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
// code
});
module.exports = router;
This error comes when you forgot to export the module which uses the Router.
Your mentioned code works perfectly with some tweaks.
if your app.js is main/starting point of the app.
it should have
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port}...`));
instead of
module.exports = app;
(optional)Generally index.js is used for starting point of app. Rename index.js as helloworld.js and change same at require statement
var routes = require('./routes/index');
to
var routes = require('./routes/helloworld');
run this app using the following command
node app.js
If you have checked all the solution than also having this error than check this one
Another cause of having this error is calling a method which is not exist or not not exported.
In my case i am calling login method but i forgot to define them
I was trying to call this method
app.post('/api/login', db.login);
but i had forgot to create login method so i got this error. also try to check spelling mistake may be you might have typed wrong spell
I had the same problem, and then I discovered that I was missing this line in one of my controllers !
return api; //it might be return routerfor your code !
I added this line to my code and it worked fine.
Whew, my problem was that i was doing module.exports = { router } instead of module.exports = router
I found it after lot of struggle! as everything syntactically correct, nothing wrong with code that was written, it was due to the code that was not written yet! This could happen if you have implemented index.js but not yet users.js. However, you have already defined both lines
app.use('/', routes);
app.use('/users', users);
If you are eager to test index.js right away without waiting for users.js to be implemented. That's exactly when it errors out.
if you are still facing this problem and try every solution then just replace router with routes and it worked fine
For anybody using EJS:
In my case I was receiving this error as I used
app.use("view engine","ejs")
instead of
app.get("view engine","ejs")
I fixed it by removing the app.use(/users, users);
I don't need this at the minute so maybe that is why it started breaking.

How to structure my project folder when building a secured NodeJs REST API

I am building a REST API using NodeJS and Express, powered by a MongoDB database.
I've been struggling for days now trying to get the right folder structure nailed down. So far, I can connect to my database and add new users without an API, but by simply doing GET, POST, etc. requests. I've seen several tutorials online on how to build API using node, but none of them have a more standardized way for setting their folder structure. And that is the reason why I am having such a hard time making it work given my current folder structure.
Here is my Folder Structure
app
---models
------user.js
---api.js
---routes.js
config
---auth.js
---database.js
---passport.js
public
views
package.json
server.js
Server.js
// server.js
// set up ======================================================================
// get all the tools we need
var express = require('express');
var app = express();
var port = process.env.PORT || 2016;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var configDB = require('./config/database.js');
// configuration ===============================================================
mongoose.connect(configDB.url); // connect to our database
require('./config/passport')(passport); // pass passport for configuration
app.configure(function() {
// set up our express application
app.use(express.logger('dev')); // log every request to the console
app.use(express.cookieParser()); // read cookies (needed for auth)
app.use(express.bodyParser.json()); // get information from html forms
app.use(bodyParser.urlencoded({ extended: true }));
app.set('views', path.join(__dirname + '/views'));
app.set('view engine', 'ejs'); // set up ejs for templating
// set the static files location /public/img will be /img for users
app.use(express.static(__dirname + '/public'));
// required for passport
app.use(express.session({ secret: 'xxxxxxxxx' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
});
// routes ======================================================================
// require('./app/routes')(app, passport); // load our routes and pass in our app and fully configured passport
// require('./app/api')(api, passport);
app.use('/', require('./app/routes')(app, passport));
app.use('/api', require('./app/api')(api, passport));
// error handlers
// Catch unauthorised errors
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401);
res.json({"message" : err.name + ": " + err.message});
}
next();
});
// launch ======================================================================
app.listen(port);
console.log('Live on port ' + port);
api.js
var User = require('./models/user');
var express = require('express');
var apiRoutes = express.Router();
app.use('/api', apiRoutes);
module.exports = function(apiRoutes, passport){
apiRoutes.get('/testapi', function (req,res) {
res.json({SecretData: 'abc123'});
});
}
Every time I hit the endpoint /testapi I get the error "Cannot GET /testapi"
I think my main issue is how to organize my files and folder properly and import/require them the right way. Can anyone help me figure this out?
Server.js
on this line app.use('/api', require('./app/api')(api, passport));
Here you are telling Express to use ./app/api as an middleware by passing "api" and "passport" as arguments.
where you have defined api variable ?
Lets assume its a typo.. in that case from "app/api.js" you are exporting a function and you trying to execute it in server.js app.use('/api', require('./app/api')(api, passport)); which returns undefined.
Express will be expecting a function as middleware not a return value from function.
app/api.js
on line 4 you have app.use('/api', apiRoutes); which doesn't make any sense, because api.js has no idea about "app".
Cleanup your server.js and api.js and try again
This tutorial might help Node with Express

Node.JS will not release localhost

I was building another application in node locally and have now deployed it and am working on another application.
EDIT
However whenever I start node (v5) with express(v4.13) on my localhost it will just hang and not make any connections I am also on a Mac running El Capitan. All that I ever see in the console (By Console I mean the Terminal via Logging) is:
GET / -- ms --
Here is my code below for guidance.
var express = require('express');
var fs = require('fs');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParer = require('body-parser');
var path = require('path');
var app = express();
var settings = app.settings;
var env = process.env;
var entrance = require('./route/siteBase');
app.set('view engine', 'jade');
app.set('view cache', false);
app.set('views', __dirname + '/source');
app.set('/assets', express.static(__dirname + '/source/assets/'));
app.use(logger('dev'));
app.use(cookieParser);
app.get('/', function (req, res) {
res.send('Hello World!');
});
/**
* 404 Error Handler
* Creates an error object to be used and passed to pages.
* TODO move this out of the server.js
* TODO create generic 500/404 page
* NOTE this must always be the last route called (i.e. if the server cannot find any other routes this will be called)
*/
app.use(function(err, req, res, next){
// error page
res.status(500).render('error', {error : err});
});
app.use(function(req, res, next) {
// logic - TODO: Create Error handling here
// console.log(req);
res.status(404).render('error', { error: req.originalUrl });
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
module.exports = app;
please help!
Ok so after a few more hours of debugging the trace led back to some bad NPM package installs which were somehow causing the issue.
I am still not entirely sure what happened, but basically just had to start over from a fresh project and rebuild.
Thank you for the assistance.
The following things you have to keep in your mind.
install dependencies:
$ cd your_app_name && npm install
Install supervisor and use it:
npm install supervisor -g
Edit package.json file and replace below lines :
"scripts": {
"start": "supervisor ./bin/www"
},
run the app with debug mode:
$ DEBUG=your_app_name:* npm start
run app on different port with debug mode:
$ PORT=8080 DEBUG=your_app_name:* npm start
check port is already running or not:
$ netstat -anp tcp | grep 3000
$ sudo netstat -lpn |grep :3000
Kill the running port:
$ sudo fuser -k 3000/tcp
Convert HTML to Jade: here
http://html2jade.aaron-powell.com/
I hope with above information you can sort out your problem.
In express the ordering matters
You have the hello world route after the error and 404 handler.
You need to reorder them.
// even better create a routes file and include it here
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.use(function(req, res, next) {
res.status(404);
res.send('404: Page not found');
});
app.use(function(err, req, res, next){
res.status(500);
res.send('500');
});
Take a look at a express-boilerplate for more details on including routes

Error while running app.js in node

I am completely new to node and trying to work with webRTC application.
I have installed node,express and socket.io in my project, However when I try to run app.js I get error. I am unable to debug because I am not experienced enough to spot the error.
The following is the code in app.js
var express = require('express')
, routes = require('./routes')
, http = require('http');
var app = express();
var server = app.listen(3000);
var io = require('socket.io').listen(server); // this tells socket.io to use our express server
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
console.log("Express server listening on port 3000");
When I write the command node app.js it shows the following error.
I have setup exprees in my project.
The file structure inside webRTC directory is as follows
Here is the link to webpage that accompanies step by step to setup node,npm express and socket.io inside a peoject . I have followed every step properly but the part where it says to run app.js after downloading socket.io it shows error.
How to install node in ubuntu
Here is the index.js code inside route folder where the error is occuring
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
and here is the image which was previously not visible properly

Categories