Cannot Access Docker Container's Exposed Port - node.js

Hello I cannot access the exposed port. It's a node server (no framework). Chrome sends ERR_EMPTY_RESPONSE. Each time I change the file and test it I run docker-compose build. How can I get this up and running so my browser can ping port 3000?
EDIT: I included my server.js file incase I'm binding the port wrong in node.
Dockerfile
FROM node:8.11.1-alpine
WORKDIR /usr/src/app
VOLUME [ "/usr/src/app" ]
RUN npm install -g nodemon
EXPOSE 3000
CMD [ "nodemon", "-L", "src/index.js" ]
Docker-compose.yml
version: '3'
services:
node:
build:
context: ./node
dockerfile: Dockerfile
working_dir: /usr/src/app
volumes:
- ./node:/usr/src/app
networks:
- app-network
env_file: ./.env
environment:
- MESSAGE_QUEUE=amqp://rabbitmq
ports:
- "3000:3000"
links:
- rabbitmq
python:
build:
context: ./python
dockerfile: Dockerfile
working_dir: /usr/src/app
volumes:
- ./python:/usr/src/app
networks:
- app-network
env_file: ./.env
links:
- rabbitmq
rabbitmq:
image: rabbitmq:3.7.4
networks:
- app-network
networks:
app-network:
driver: bridge
Server.js
const mongoose = require('mongoose')
const hostname = '127.0.0.1';
const port = 3000;
const server = require('./controllers/index');
server.listen(port, hostname, () => {
// Connect To Mongo
mongoose.connect(process.env.MONGO_URI, { keepAlive: true, keepAliveInitialDelay: 300000, useNewUrlParser: true });
mongoose.connection.on('disconnected', () => {
console.error('MongoDB Disconnected')
})
mongoose.connection.on('error', (err) => {
console.error(err)
console.error('MongoDB Error')
})
mongoose.connection.on('reconnected', () => {
console.error('MongoDB Reconnected')
})
mongoose.connection.on('connected', () => {
console.error('MongoDB Connected')
})
console.log(`Server running at http://${hostname}:${port}/`);
});

Try to bind your app to 0.0.0.0 like this
const hostname = '0.0.0.0';
it will listen on all network addresses.

Related

PG Pool is not working inside Docker container

I am running a PERN application and currently trying to dockerize it. When I run the database as a container and the server and client locally I have no issues. However, when I containerize the server, client, and database respectively, I am unable to make requests. It results in 404 errors. This is the same behavior that occurs when I pass pool the wrong port or host. So I'm wondering if somehow I am giving the wrong host and/or port to pool or if I should change it when I containerize it.
This is the Pool Instance
const Pool = require('pg').Pool
const pool = new Pool({
user: 'docker',
password: 'docker',
host: "localhost",
port: 4000,
database: "docker"
})
This is part of the rest api in the server:
const express = require("express")
const router = express.Router()
const pool = require('../database/database.js')
router.get("/:login", async (req, res) => {
try {
let loginReq = JSON.parse(decodeURIComponent(req.params.login))
const user = await pool.query(
"SELECT user_id,first_name,last_name,email FROM \"user\" where email = $1 and password = $2",
[loginReq.email, loginReq.password]
)
if(user.rows.length) {
res.json(user.rows[0])
} else {
throw new Error('User Not Found')
}
} catch (err) {
res.status(404).json(err.message)
}
})
This is each of my dockerfiles for my client, server, and database
Client:
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install --production
CMD ["npm","start"]
EXPOSE 3000
Server:
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install --production
CMD ["node","index.js"]
EXPOSE 5000
Database;
FROM postgres:15.1-alpine
COPY init.sql /docker-entrypoint-initdb.d/
This is my docker-compose.yml
version: "3.8"
services:
client:
build: ./client
ports:
- "3000:3000"
restart: unless-stopped
server:
build: ./server
ports:
- "5000:5000"
restart: unless-stopped
database:
build: ./database
ports:
- "4000:4000"
environment:
- POSTGRES_USER=docker
- POSTGRES_PASSWORD=docker
- POSTGRES_DB=docker
- PGPORT=4000
volumes:
- kurva:/var/lib/postgresql/data
restart: unless-stopped
volumes:
kurva:
I don't understand why the behavior would be different between containerizing the server and running it locally when they all use the same ports. I have tried messing with the host and changing it to 0.0.0.0 but that did not help. Any help would be appreciated!
I found that it was a host issue and I needed to change the host accessed in the pool to the service name. Additionally, I needed to add that the server depends on the database service.
This is the updated pg pool:
const pool = new Pool({
user: 'docker',
password: 'docker',
host: "database",
port: 4000,
database: "docker"
})
This is the updated docker-compose.yml
version: "3.8"
services:
client:
build: ./client
ports:
- "3000:3000"
restart: unless-stopped
server:
build: ./server
ports:
- "5000:5000"
depends_on:
- database
restart: unless-stopped
database:
build: ./database
ports:
- "4000:4000"
environment:
- POSTGRES_USER=docker
- POSTGRES_PASSWORD=docker
- POSTGRES_DB=docker
- PGPORT=4000
volumes:
- kurva:/var/lib/postgresql/data
restart: unless-stopped
volumes:
kurva:

Docker - React app can not fetch from the server

Hello I am new to the docker and I am trying to dockerize my application that uses React as frontend, nodejs as backend and mySQL as database. However when I try to fetch data from server from my react app, it gives me error:
Access to fetch at 'http://localhost:3001/api' from origin 'http://localhost:3000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:3000' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
My react app is rendered and also when I go to http://localhost:3001/api I receive the data I would like to get. Just the communication between react and nodejs is somehow broken.
Here are my Docker files and env files:
.env:
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=123456
DB_NAME=testdb
DB_PORT=3306
MYSQLDB_USER=root
MYSQLDB_ROOT_PASSWORD=123456
MYSQLDB_DATABASE=testdb
MYSQLDB_LOCAL_PORT=3306
MYSQLDB_DOCKER_PORT=3306
NODE_LOCAL_PORT=3001
NODE_DOCKER_PORT=3001
CLIENT_ORIGIN=http://127.0.0.1:3000
CLIENT_API_BASE_URL=http://127.0.0.1:3001/api
REACT_LOCAL_PORT=3000
REACT_DOCKER_PORT=80
dockerfile for react:
FROM node:14.17.0 as build-stage
WORKDIR /frontend
COPY package.json .
RUN npm install
COPY . .
ARG REACT_APP_API_BASE_URL
ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL
RUN npm run build
FROM nginx:1.17.0-alpine
COPY --from=build-stage /frontend/build /usr/share/nginx/html
EXPOSE 80
CMD nginx -g 'daemon off;'
dockerfile for nodejs:
FROM node:14.17.0
WORKDIR /
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3001
CMD [ "node", "server.js" ]
docker-compose.yml :
version: '3.8'
services:
mysqldb:
image: mysql
restart: unless-stopped
env_file: ./.env
environment:
- MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
- MYSQL_DATABASE=$MYSQLDB_DATABASE
ports:
- $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
volumes:
- db:/var/lib/mysql
networks:
- backend
server-api:
depends_on:
- mysqldb
build: ./
restart: unless-stopped
env_file: ./.env
ports:
- $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
environment:
- DB_HOST=mysqldb
- DB_USER=$MYSQLDB_USER
- DB_PASSWORD=$MYSQLDB_ROOT_PASSWORD
- DB_NAME=$MYSQLDB_DATABASE
- DB_PORT=$MYSQLDB_DOCKER_PORT
- CLIENT_ORIGIN=$CLIENT_ORIGIN
networks:
- backend
- frontend
frontend-ui:
depends_on:
- server-api
build:
context: ./frontend
args:
- REACT_APP_API_BASE_URL=$CLIENT_API_BASE_URL
ports:
- $REACT_LOCAL_PORT:$REACT_DOCKER_PORT
networks:
- frontend
volumes:
db:
networks:
backend:
frontend:
My project folder structure is a bit weird as my server its things(node_modules, package.json...) are in the root where docker-compose, .env and Dockerfile for server is located.
React app and frontend is in /frontend folder where also Dockerfile for react is located.
In react I call fetch("http://localhost:3001/api").
Server is created with express :
const express = require('express');
const cors = require('cors');
const server = express();
var mysql = require('mysql2');
require("dotenv").config();
const port = 3001
server.use(express.static('public'));
var corsOptions = {
origin: "http://127.0.0.1:3000"
}
server.use(cors(corsOptions));
var con = mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD
});
server.get('/api', async (req, res) => {
console.log("START");
con.connect(function (err) {
if (err) throw err;
console.log("connected !");
con.query("use testdb;", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
con.query("select * from records;", function (err, result, fields) {
if (err) throw err;
res.send(result);
});
});
});
server.listen(port, () => {
console.log(`Server listening on port ${port}`)
})
I created this thanks to This tutorial
Thanks for any help.
change this: origin: "http://127.0.0.1:3000"
to this: origin: "http://localhost:3000"

Node.js app not connect to docker redis container

I connected with docker redis container.The redis working in the docker.If I execute the docker file with docker exec -it 96e199a8badf sh, I connected to redis server.
My node.js application like this.I use redis 4.1.0 version.
I don't know, what's going on.How can I fix this?
docker-compose.yml
version: '3'
services:
app:
container_name: delivery-app
build:
dockerfile: 'Dockerfile'
context: .
ports:
- "3000:3000"
volumes:
- .:/app,
- '/app/node_modules'
networks:
- redis
redis:
image: "redis"
ports:
- "6379:6379"
networks:
- redis
networks:
redis:
driver: bridge
Dockerfile
FROM node:16-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD ["node","server.js"]
code:
const redisClient = redis.createClient({
socket: {
port: 6379,
host: "redis"
}
});
await redisClient.connect();
redisClient.on('connect',function(){
return res.status(200).json({
success: true
})
}).on('error',function(error){
return res.status(400).json({
success: false
})
});
package.json
"redis": "^4.1.0"
I had the same issue and solved it by passing the host parameter as a socket object in createClient like this
{
socket: {
host: "redis"
}
}
This seems to be new because before you didn't have to use the socket object
Here's the documentation for node-redis createClient
https://github.com/redis/node-redis/blob/HEAD/docs/client-configuration.md

Cannot connect node js app to mongodb running in a docker swarm

I am trying to deploy nodejs app in docker swarm. However I'm struggling to make it connect to the mongodb service.
Below is my docker-compose file
version: '3'
services:
moitrack-teltonika-parser:
build: .
image: moitrack/moitrack-teltonika-parser:1.0.14
ports:
- "5001:5001"
networks:
- web
deploy:
mode: replicated
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
depends_on:
- db
db:
image: mongo
command: mongod --bind_ip_all
ports:
- "27017"
volumes:
- mongodata:/data/db
restart: "always"
deploy:
placement:
constraints: [node.role == manager]
networks:
- web
volumes:
mongodata: {}
networks:
web:
external: true
This is the node js script
var express = require("express");
const mongoose = require('mongoose');
var server = express();
const options = {
useNewUrlParser: true,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 500,
connectTimeoutMS: 10000,
};
const DB_URI = 'mongodb://db:27017/moiponeGateKeeper';
mongoose.connect(DB_URI, options).then(() => {
console.log("database connected");
}).catch(err => console.log(err));
server.listen(5001, () => { console.log("Server started"); });
I get the error below when I view the node service in the docker swarm.
enter image description here
'mongodb://db:27017/moiponeGateKeeper' is not a valid url,
You should specify a valid link to connect. Instead of db try using a valid ip of your mongodb server.

nodejs doesn't connect to rethinkdb with docker-compose

How run rethinkdb with nodejs on server ?
Is docker-compose.yml:
web:
build: ./app
volumes:
- "./app:/src/app"
ports:
- "8000:8000"
- "8080:8080"
- "28015:28015"
- "29015:29015"
links:
- "db:redis"
- "rethink:rethinkdb"
command: nodemon -L app/bin/www
db:
image: redis
ports:
- "6379"
rethink:
image: rethinkdb
is a folder app with nodejs-project and Dockerfile
Dockerfile
FROM node:0.10.38
RUN mkdir /src
RUN npm install nodemon -g
WORKDIR /src/app
ADD package.json package.json
RUN npm install
ADD nodemon.json nodemon.json
In the nodejs-project connection to rethinkdb:
module.exports.setup = function() {
r.connect({host: dbConfig.host /* 127.0.0.1*/, port: dbConfig.port /*is 28015 or 29015 or 32783*/ }, function (err, connection) {
...
});
};
And when run a docker-compose up, have an error
Could not connect to 127.0.0.1:32783.
Try exposing the port in you docker-compose.yml:
web:
build: ./app
volumes:
- "./app:/src/app"
ports:
- "8000:8000"
depends_on:
- db
- rethink
command: nodemon -L app/bin/www
db:
image: redis
ports:
- "6379:6379"
rethink:
image: rethinkdb
ports:
- "8080:8080"
- "28015:28015"
- "29015:29015"
Then dbConfig.host = rethinkdb and dbConfig.port = 28015:
module.exports.setup = function() {
r.connect({host: dbConfig.host /* 127.0.0.1*/, port: dbConfig.port /*is 28015 or 29015 or 32783*/ }, function (err, connection) {
...
});
};
Hope you find this helpful.

Resources