Docker container does not respond to http request - node.js

I'm trying to send an http request through axios, from my localhost (node server) to a docker container (which contains a simple server in node too) which belongs to a docker network, and identified by an specific IP.
I have used postman, xmlhttprequests, and axios but nothing seems to work. I have also tried with get and post requests but any of those get any answer from the container side.
Do you have any Idea of what am I doing wrong?
the .sh file that Im running to launch the container is:
docker build -t connectimg .
docker network create --subnet=119.18.0.0/16 mynet
docker run -d --name instance2 -p 4002:4000 --net mynet --ip 119.18.0.2 connectimg
and the docker logs result for the instance post-launch is:
{
lo: [
{
address: '127.0.0.1',
netmask: '255.0.0.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true,
cidr: '127.0.0.1/8'
}
],
eth0: [
{
address: '119.18.0.2',
netmask: '255.255.0.0',
family: 'IPv4',
mac: '02:42:77:12:00:02',
internal: false,
cidr: '119.18.0.2/16'
}
]
}
Example app listening on port 3000
My Docker Instance Node app code is:
const express = require('express')
const app = express()
const port = 3000
const cors = require('cors')
var os = require('os');
app.use(cors());
app.use(express.json());
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
app.get('/listen', (req,res) => {
console.log('got it');
})
var networkInterfaces = os.networkInterfaces();
console.log(networkInterfaces);
And my Node server piece of code responsible of sending the get request to the instance is:
const connect = (req,res) => {
axios.get('http://119.18.0.2:3000/listen').then(resp => {
console.log(resp.data);
});
}
and the error I keep getting is:
ETIMEDOUT 119.18.0.2:3000
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16)

Firstly, your URI http://119.18.0.2:3000/listen is incorrect. The docker network cannot be accessed directly as it is not a network that the host knows of.
The option -p 4002:4000 is what is exposing your docker container to the host(and the network you're connected to). 4002 is the port exposed to the host and port 4000 is the port your container is exposing INSIDE the docker network
To access the container from the host your URI would become http://localhost:4002/listen
To access the container from a different machine on the same network the URI would become http://<ip-address-of-this-machine>:4002/listen. You can find your IP using ipconfig in command prompt on Windows, or ifconfig in terminal on Linux based systems.
Secondly, your port allocations are mismatched. You set the port in your node app using const port = 3000 and exposed port 4000 of the container using -p 4002:4000 in your docker run command.
Either change your node application to expose port 4000 using const port = 4000
OR
Change your docker run command to expose port 3000 of the container by using -p 4002:3000.
Docker networks can be a bit confusing at first. Read up on them or check the documentation(hella useful), it will serve you well in future development. :)
EDIT: You can properly containerize your node application using a DockerFile similar to this:
FROM node:lts-alpine3.15
LABEL maintainer="MyDevName"
WORKDIR /usr/app
COPY ./myNodeApp ./
RUN npm install
CMD ["npm", "start"]
So that your node app runs automatically on start.

the .sh file that Im running to launch the container is:
docker build -t connectimg .
docker network create --subnet=119.18.0.0/16 mynet
docker run -d --name instance2 -p 4002:4000 --net mynet --ip 119.18.0.2 connectimg
if will leverage docker-compose, you might not need the script.
I'm trying to send an http request through axios, from my localhost (node server) to a docker container (which contains a simple server in node too) which belongs to a docker network, and identified by an specific IP.
seems like 2 things need to be tweaked:
use 0.0.0.0:4200 in the dockerized server.
verify the network that you associate with the container is reachable from your host operating system. if the docker network is not that important, you can just ditch it

Related

Cannot access a Node.js server when hostname set to 127.0.0.1 but works for 0.0.0.0 [duplicate]

This question already has answers here:
Docker app server ip address 127.0.0.1 difference of 0.0.0.0 ip
(2 answers)
Closed 8 months ago.
I am trying to dockerize a Node.js server.
I use the following index.js and Dockerfile files:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
FROM node:latest
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm i
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
Then I run docker build . -t webapp and docker run -p 8080:3000 webapp, but when I try to open the app in the browser I see "The webpage at http://localhost:8080/ might be temporarily down or it may have moved permanently to a new web address."
Then when I change the hostname in the index.js to 0.0.0.0, it seems to work fine and I can access my app in the browser under http://localhost:8080/.
What is the difference between running an app in a container on the localhost vs. on 0.0.0.0?
In a container, localhost is the container itself. So when you bind to 127.0.0.1 your program will only accept connections coming from inside the container.
You need to bind to 0.0.0.0 for it to accept connections from outside the container.

How to access Linux Docker Container's TCP Port from windows 10 host

I have installed Docker for windows on windows 10 . I am running Linux containers on docker. I have a python app which has ZeroMQ which has a zmq server listening on port 3000 . I want to send images from my c# app deployed on windows host to connect to the zmq app running on docker linux containers and send images through tcp using zeromq .
I am unable to access the container tcp port from windows app .
Please advise .
I tried the below:
C:\Windows\system32>docker run -p 3000:3000 server-zmq10 docker:
Error response from daemon:
driver failed programming external connectivity on endpoint condescending_kilby
(fc383d60832ae98a5601ba62e215a4033936f74b64577ca6b14f7c47f1f27f9a): Error starting
userland proxy: mkdir /port/tcp:0.0.0.0:3000:tcp:172.17.0.2:3000: input/output error.
Python code:
context = zmq.Context()
socket = context.socket(zmq.REP)
print('Binding to port 3000')
socket.bind("tcp://127.0.0.1:3000")
I have done on the DockerFIle when creating the image:
EXPOSE 3000
Is there anything else which is required here ?
After exposing 3000 port is there any service running for listening?
or use -p 5000:5000 in docker run command

Why does my app listen on port 80 instead of port 3000 as I set it running inside docker container?

What I'm trying?
I'm trying to run my nodejs app inside a docker container and want to use it outside of the container(through my browser on port 3000).
DockerFile
FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
RUN npm run build
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]
app.ts(Relevant portion)
const port = process.env.port || 3000;
let app = express();
app.listen(port, () => {
console.log(`Listening on port ${port}!`);
});
command I'm using to run
$ docker run --net=host <imgName>
OS --> Windows 7
And in the Oracle Virtual Box I've changed network settings to bridged networks.
The command runs successfully and the server starts listening on port 80. And I can access it from outside the container on port 80 through postman,curl,browser,etc.
Where I am doing wrong? How can I make it to listen on port 3000? And also how is it even able to listen on port if I haven't exposed it explicitly?
I think the docker is passing port as an environment variable and setting it to 80 as I am not passing any environment variable myself.
Please help I'm very new to docker.
Just exposing in your Dockerfile won't do it for you. You will need to map it when you do docker run or execute using docker-example.yaml.
To achieve that you will need to use $ docker run -p 3000:3000. Following that you won't need to use --net=host that should be the reason why the service is available on port 80.
Hope it helps!
Cheers!

docker connection refused nodejs app

I launch docker container:
docker run --name node-arasaac -p 3000:3000 juanda/arasaac
And my node.js app works ok.
If I want to change host port:
docker run --name node-arasaac -p 8080:3000 juanda/arasaac
Web page is not loaded, logs from browser console:
Failed to load resource: net::ERR_CONNECTION_REFUSED
http://localhost:3000/app.318b21e9156114a4d93f.js Failed to load resource: net::ERR_CONNECTION_REFUSED
Do I need to have the same port both in host and container? It seems it knows how to resolve http://localhost:8080 so it loads my website, but internal links in the webpage go to port 3000 and it's not as good :-(
When you are running your node.js app in a docker container it will only expose the ports externally that you designate with your -p (lowercase) command. The first instance with, "-p 3000:3000", maps the host port 3000 to port 3000 being exposed from within your docker container. This provides a 1 to 1 mapping, so any client that is trying to connect to your node.js service can do so through the HOST port of 3000.
When you do "-p 8080:3000", docker maps the host port of 8080 to the node.js container port of 3000. This means any client making calls to your node.js app through the host (meaning not within the same container as your node.js app or not from a linked or networked docker container) will have to do so through the HOST port of 8080.
So if you have external services that expect to access your node.js at port 3000 they won't be able.

Docker node.js app not listening on port

I'm working on a node.js web application and use localhost:8080 to test it by sending requests from Postman. Whenever I run the application (npm start) without using Docker, the app works fine and listens on port 8080.
When I run the app using Docker, The app seems to be running correctly (it displays that it is running and listening on port 8080), however it is unreachable using Postman (I get the error: Could not get any response). Do you know what the reason for this could be?
Dockerfile:
FROM node:8
WORKDIR /opt/service
COPY package.json .
COPY package-lock.json .
RUN npm i
COPY . .
EXPOSE 8080
CMD ["npm", "start"]
I build and run the application in Docker using:
docker build -t my-app .
docker run my-app
I have tried binding the port as described below, but I also wasn't able to reach the server on port 8181.
docker run -p 8181:8080 my-app
In my application, the server listens in the following way (using Express):
app.listen(8080, () => {
console.log('listening on port 8080');
})
I have also tried using:
app.listen(8080, '0.0.0.0', () => {
console.log('listening on port 8080');
})
The docker port command returns:
8080/tcp -> 0.0.0.0:8181
Do you guys have nay idea what the reason for this could be?
UPDATE: Using the IP I obtained from the docker-machine (192.168.99.100:8181) I was able to reach the app. However, I want to be able to reach it from localhost:8181.
The way you have your port assignment setup requires you to use the docker machine's ip address, not your localhost. You can find your docker machines ip using:
docker-machine ip dev
If you want to map the container ip to your localhost ports you should specify the localhost ip before the port like this:
docker run -p 127.0.0.1:8181:8080 my-app
Similar question:

Resources