Docker Error occured while trying to proxy to: localhost:5000 - node.js

I get the following error when using a express-react app on docker.
i referred to this
React Proxy error: Could not proxy request /api/ from localhost:3000 to http://localhost:8000 (ECONNREFUSED)
and the solution doesn't seem to work.
setupProxy.js
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/auth/github', { target: 'http://[::1]:5000/' }))
app.use(proxy('/api/users/auth/github', { target: 'http://[::1]:5000/' }))
app.use(proxy('/api/users/', { target: 'http://[::1]:5000/', "secure": false }))
app.use(proxy('/api/posts/', { target: 'http://[::1]:5000/' }))
}
Dockerfile
FROM node:8.10.0-alpine
EXPOSE 5000
COPY . /home/app
WORKDIR /home/app
RUN npm install
CMD ["npm", "start"]
docker-compose.yml
# docker-compose.yml
version: "3"
services:
app:
build: .
restart: always
depends_on:
- postgres
ports:
- 5000:3000
postgres:
image: postgres:9.6.8-alpine
expose:
- 5432
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: user
POSTGRES_DB: db
Package.json
{
"name": "sequelize-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"client": "cd ./client && npm start ",
"server": "nodemon app.js --ignore client",
"build": "echo 'hello build'",
"start": "concurrently --kill-others \"npm run server\" \"npm run client\""
},
"author": "",
"license": "ISC",
"dependencies": {
"async": "^2.6.1",
"bcrypt": "^3.0.3",
"body-parser": "^1.18.3",
"concurrently": "^4.1.0",
"cookie-parser": "^1.4.3",
"cookie-session": "^2.0.0-beta.3",
"cors": "^2.8.5",
"crypto": "^1.0.1",
"dotenv": "^6.2.0",
"express": "^4.16.4",
"express-flash": "0.0.2",
"express-session": "^1.15.6",
"jsonwebtoken": "^8.4.0",
"morgan": "^1.9.1",
"nodemailer": "^5.1.1",
"nodemon": "^1.18.9",
"passport": "^0.4.0",
"passport-github": "^1.1.0",
"passport-github2": "^0.1.11",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"pg": "^7.8.0",
"pg-hstore": "^2.3.2",
"sequelize": "^4.42.0"
}
}
app.js
var express = require('express');
var app = express();
var userRoute = require('./routes/users');
var postRoute = require('./routes/posts');
var bodyParser = require('body-parser');
var logger = require('morgan');
var models = require('./models');
var User = require('./models/user');
var session = require('express-session');
var cookieParser = require('cookie-parser') ;
var cookieSession = require('cookie-session');
var dotenv = require('dotenv');
var env = dotenv.config();
var cors = require('cors');
const port = process.env.PORT || 5000;
const passport = require('passport');
const path = require('path');
// CORS Middleware
app.use(cors());
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
secret : 'nodeauthsecret',
resave: false,
saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
require('./config/passport-github')(passport);
app.use(function(req, res, next) {
res.locals.user = req.user; // This is the important line
console.log(res.locals.user);
next();
});
// app.use(function(req, res, next) {
// res.setHeader("Access-Control-Allow-Origin", "*");
// res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// });
app.use('/api/users', userRoute )
app.use('/api/posts', postRoute )
app.listen(port, function() {
console.log(`Server is running on ${port}`);
});

Let's make sense of this:
The API server listens for requests on default port of 5000 in the docker container.
The API service is composed using docker-compose to publish port 5000 in the node machine for target port 3000 in the container.
Then, the client server is set up to proxy API requests to port 5000 in the node machine.
Clearly, there isn't any service running on 3000 in the container.
You can correct the target port by setting it to 5000 in docker-compose.yaml
ports:
- 5000:5000

Related

I am trying to deploy MERN App on VERCEL but getting NOT FOUND

I am trying to deploy MERN App on Vercel but getting NOT FOUND
When i put NODE_ENV as PRODUCTION then it works fine and serves the static files on local machine when run npm start but it is not working on vercel.
.
My Directory Structure is
My app.js file is
const express = require("express");
const app = express();
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const PostRoutes = require("./Routes/posts");
const CategoryRoutes = require("./Routes/categories");
const UserRoutes = require("./Routes/user");
const AuthRoutes = require("./Routes/auth");
const bodyParser = require("body-parser");
const multer = require("multer");
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads/images/");
},
filename: (req, file, cb) => {
cb(null, Date.now() + "_" + file.originalname);
},
});
var upload = multer({ storage: storage });
const cors = require("cors");
dotenv.config();
app.use(express.json());
app.use("uploads/images/", express.static("uploads/images/"));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
if (process.env.NODE_ENV == "production") {
const path = require("path");
app.get("/", (req, res) => {
app.use(express.static(path.resolve(__dirname, "frontend", "build")));
res.sendFile(path.resolve(__dirname, "frontend", "build", "index.html"));
});
}
mongoose
.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(console.log("connected to Mongo database "))
.catch((err) => {
console.log(err);
});
app.use("/api/posts", upload.single("photo"), PostRoutes);
app.use("/api/categories", CategoryRoutes);
app.use("/api/auth", upload.none(), AuthRoutes);
app.use("/api/users", upload.single("profile_pic"), UserRoutes);
app.listen(process.env.PORT || 3001, () => {
console.log(`Server Listening on the port ${process.env.PORT}`);
});
package.json file
{
"name": "backend",
"version": "1.0.0",
"description": "Backend to the blog app ",
"main": "app.js",
"scripts": {
"start": "node app.js",
"dev-start": "nodemon app.js --ignore client",
"start-client": "npm start --prefix frontend",
"dev": "concurrently \"cd ./frontend && npm start\" \"npm run dev-start\""
},
"author": "Shiv Shankar Prasad",
"license": "MIT",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.0",
"concurrently": "^7.4.0",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"express-async-handler": "^1.2.0",
"express-validator": "^6.14.2",
"jsonwebtoken": "^8.5.1",
"minifaker": "^1.34.1",
"mongoose": "^6.5.3",
"multer": "^1.4.5-lts.1",
"nodemon": "^2.0.19"
}
}
Please help.
I have found a solution and it was the changes in the vercel.json file.
Now i used the vercel CLI and it is much more easy to use.
{
"version": 2,
"builds": [
{
"src": "./index.js",
"use": "#vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/"
}
]
}

I can't connect to MongoDB using mongoose

I keep getting a error "MongooseError: The uri parameter to openUri() must be a string, got "undefined". Make sure the first parameter to mongoose.connect() or mongoose.createConnection() is a string.". I've been looking at other questions that get a similar error butI did not find a solution after trying multiple different things.
in package.json
{
"dependencies": {
"bcrypt": "^5.1.0",
"body-parser": "^1.20.1",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"gridfs-stream": "^1.1.1",
"helmet": "^6.0.1",
"jsonwebtoken": "^9.0.0",
"mongoose": "^6.7.0",
"morgan": "^1.10.0",
"multer": "^1.4.4",
"multer-gridfs-storage": "^5.0.2"
},
"name": "server",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
in index.js
import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import cors from "cors";
import dotenv from "dotenv";
import multer from "multer";
import helmet from "helmet";
import morgan from "morgan";
import path from "path";
import { fileURLToPath } from "url";
/* CONFIGURATIONS */
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
dotenv.config();
const app = express();
app.use(express.json());
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
app.use(morgan("common"));
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
app.use("/assets", express.static(path.join(__dirname, "public/assets")));
/* FILE STORAGE */
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/assets");
},
filename: function (req, file, cb) {
cb(null, file.originalname);
},
});
const upload = multer({ storage });
/* MONGOOSE SETUP */
const PORT = process.env.PORT || 6001;
mongoose
.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
app.listen(PORT, () => console.log(`Server Port: ${PORT}`));
})
.catch((error) => console.log(`${error} did not connect`));
in .env
MONGO_URL = 'the connection string'
PORT = 3001

Unable to deploy my node.js server via Heroku error heroku[router]: at=error code=H10

I followed a YouTube tutorial and created a full stack (MERN) social media application. I am having issues deploying it. I have tried every solution I could find related to heroku[router] code=H10, but none of them solved my issues. Here are my files related.
package.json
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.0.1",
"body-parser": "^1.20.0",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^6.5.1",
"multer": "^1.4.5-lts.1",
"nodemon": "^2.0.19"
}
}
index.js
import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import dotenv from "dotenv";
import cors from "cors";
import AuthRoute from "./Routes/AuthRoute.js";
import UserRoute from "./Routes/UserRoute.js";
import PostRoute from "./Routes/PostRoute.js";
import UploadRoute from "./Routes/UploadRoute.js";
// Routes
const app = express();
//Public images
app.use(express.static('public'))
app.use('/images', express.static('images'))
// Middleware
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
dotenv.config();
mongoose
.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() =>
app.listen(process.env.PORT, () =>
console.log("Connected")
)
)
.catch((error) => console.log(error));
// Usage of routes
app.use("/auth", AuthRoute);
app.use("/user", UserRoute);
app.use("/posts", PostRoute);
app.use('/upload', UploadRoute);
I have also edited the config variables and have
MONGO_URI linked to my MongoDB.
I originally had my start script as nodemon index.js. I changed it to direct node to start at index.js. Perhaps that is part of the issue. I changed it to just run node instead of nodemon.
What am I doing wrong?

React / React-Router/ Express / Heroku routing issue

I've deployed a React/Express app on Heroku. I'm using BrowserRouter. Everything worked fine locally. My issue is the backend routes are not working. The only route that works is the catchall route. The catchall route is also being called three times for some reason. I console logged the request path using 'req.path' to see which path was being called. It should have been '/google'. Instead the three calls give three different logs for req.path. They are: '/static/css/main.814455d3.chunk.css.map', '/static/js/main.06bdb7f0.chunk.js.map', '/static/js/1.1baafe13.chunk.js.map'. I'm hoping someone can help.
I've been stuck for over a day now. Here are my package.json and static.json from the client side:
static.json
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
package.json
{
"name": "workout_tracker",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"jw-paginate": "^1.0.2",
"jw-react-pagination": "^1.0.7",
"normalize.css": "^8.0.0",
"query-string": "^6.2.0",
"random-id": "0.0.2",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-headroom": "^2.2.2",
"react-icons-kit": "^1.1.6",
"react-redux": "^5.0.7",
"react-router-dom": "^4.3.1",
"react-scripts": "^2.0.5",
"react-swipe-to-delete-component": "^0.3.4",
"react-swipeout": "^1.1.1",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"devDependencies": {
"redux-devtools-extension": "^2.13.5"
},
"proxy":"localhost:4000",
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
And this is my package.json from express
{
"name": "expresstest",
"version": "1.0.0",
"description": "app to test express and mysql",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"node app.js",
"heroku-postbuild": "cd client && npm install && npm run build"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.18.3",
"connect-flash": "^0.1.1",
"cookie-session": "^2.0.0-beta.3",
"cors": "^2.8.4",
"express": "^4.16.3",
"mysql": "^2.16.0",
"passport": "^0.4.0",
"passport-google-oauth20": "^1.0.0"
}
}
This is part of the code from the server. I omitted the other routes as none besides the catchall route are being called anyway.
let express = require("express");
let cors= require("cors");
let mysql = require("mysql");
const util = require("util");
const keys = require("./config/keys");
const passport = require("passport");
const passportSetup = require("./config/passport-setup");
const bodyParser = require("body-parser");
const flash= require("connect-flash");
const path= require("path");
console.log("process env");
console.log("-------");
console.log(process.env.PWD);
const cookieSession = require("cookie-session");
let app = express();
app.use(bodyParser.json());
app.use(cookieSession({
maxAge:24 * 60 * 60 * 1000,
keys:[keys.session.cookieKey]
}));
app.use(passport.initialize());
app.use(passport.session());
if (process.env.NODE_ENV === 'production') {
console.log("inside prod");
app.use(express.static('client/build'));
}
let connection =keys.connection;
app.get("/google", passport.authenticate("google",{
scope:['profile'],
failureFlash:"failure"
}),(req,res)=>{
// console.log(req.flash());
console.log("/google route");
});
const port = process.env.PORT || 4000;
let http = require("http");
let server = http.createServer(app,(req,res)=>{
res.writeHead(200, {"Access-Control-Allow-Origiin": "*"})
});
app.get('/*', (req, res) => {
console.log("catchall");
console.log(req.hostname);
console.log(req.path);
console.log(path.join(__dirname + '/client', 'build', 'index.html'));
res.sendFile(path.join(__dirname + '/client', 'build', 'index.html'));
})
server.listen(port, ()=>{
console.log("Listening on "+ port)
});
Here is my folder structure:
Link to pic of my folder structure
EDIT: I got it working, here is the code that works. I don't know why it works, though. I just tried some things I found on blogs for React/Express/Heroku projects. If anyone can tell me why it works it would be greatly appreciated.
let express = require("express");
let cors= require("cors");
let mysql = require("mysql");
const util = require("util");
const keys = require("./config/keys");
const passport = require("passport");
const passportSetup = require("./config/passport-setup");
const bodyParser = require("body-parser");
const flash= require("connect-flash");
const path= require("path");
console.log("process env");
console.log("-------");
console.log(process.env.PWD);
const cookieSession = require("cookie-session");
let app = express();
app.use(bodyParser.json());
app.use(express.static(__dirname));
app.use(cookieSession({
maxAge:24 * 60 * 60 * 1000,
keys:[keys.session.cookieKey]
}));
app.use(passport.initialize());
app.use(passport.session());
if (process.env.NODE_ENV === 'production') {
console.log("inside prod");
app.use(express.static('client/build'));
}
let connection =keys.connection;
app.get("/google", passport.authenticate("google",{
scope:['profile'],
failureFlash:"failure"
}),(req,res)=>{
// console.log(req.flash());
console.log("/google route");
});
const port = process.env.PORT || 4000;
let http = require("http");
let server = http.createServer(app,(req,res)=>{
res.writeHead(200, {"Access-Control-Allow-Origiin": "*"})
});
app.get("/service-worker.js", (req, res) => {
res.sendFile(path.join(__dirname + "/client","build", "service-worker.js"));
});
app.get('/*', (req, res) => {
console.log("catchall");
console.log(req.hostname);
console.log(req.path);
console.log(path.join(__dirname + '/client', 'build', 'index.html'));
res.sendFile(path.join(__dirname + '/client', 'build', 'index.html'));
})
server.listen(port, ()=>{
console.log("Listening on "+ port)
});

When I deploy my nodejs app on heroku, build success but got a "Application Error"

I have already run my nodejs app successfully on my localhost, but when I deploy it on heroku, build success, but I got a "Application Error", when I use "heroku logs", it show like this:
console screenshot
I can't figure out what's wrong with my app, hope to get your help, thanks!
Here's my package.json
{
"main": "index.js",
"scripts": {
"test": "mocha --harmony test",
"start": "cross-env NODE_ENV=production pm2 start index.js --node-args='--harmony' --name 'adolt-blog'"
},
...
"dependencies": {
"config-lite": "^1.5.0",
"connect-flash": "^0.1.1",
"connect-mongo": "^1.3.2",
"cross-env": "^3.1.3",
"ejs": "^2.5.2",
"express": "^4.14.0",
"express-formidable": "^1.0.0",
"express-session": "^1.14.2",
"express-winston": "^2.0.0",
"marked": "^0.3.6",
"moment": "^2.17.0",
"mongolass": "^2.3.2",
"objectid-to-timestamp": "^1.3.0",
"sha1": "^1.1.1",
"winston": "^2.3.0",
"pm2": "^2.2.3",
"mocha": "^3.2.0"
}
}
and index.js
var path = require('path');
var express = require('express');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var flash = require('connect-flash');
var config = require('config-lite');
var routes = require('./routes');
var pkg = require('./package');
var winston = require('winston');
var expressWinston = require('express-winston');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
name: config.session.key,
secret: config.session.secret,
cookie: {
maxAge: config.session.maxAge
},
store: new MongoStore({
url: config.mongodb
}),
saveUninitializedSession: true,
resaveSession: true
}));
app.use(flash());
app.use(require('express-formidable')({
uploadDir: path.join(__dirname, 'public/img'),
keepExtensions: true
}));
app.locals.blog = {
// title: pkg.name,
// description: pkg.description
title: 'Adolt\'s Blog',
description: 'Learn Node.js'
};
app.use(function (req, res, next) {
res.locals.user = req.session.user;
res.locals.success = req.flash('success').toString();
res.locals.error = req.flash('error').toString();
next();
});
app.use(expressWinston.logger({
transports: [
new (winston.transports.Console)({
json: true,
colorize: true
}),
new winston.transports.File({
filename: 'logs/success.log'
})
]
}));
routes(app);
app.use(expressWinston.errorLogger({
transports: [
new winston.transports.Console({
json: true,
colorize: true
}),
new winston.transports.File({
filename: 'logs/error.log'
})
]
}));
if (module.parent) {
module.exports = app;
} else {
const port = process.env.PORT;
app.listen(port, function () {
console.log(`${pkg.name} listening on port ${port}`);
});
}
Thanks to the help of #Lucas Katayama, the problem finally solved.
First, add main.js according to the use-pm2-with-cloud-providers.
And then modify the Procfile like this
web: node main.js
Finally, rebuild your app and see if it works!
Hope it can help! Good luck!

Resources