This question already has answers here:
Nodejs port with docker is unreachable
(1 answer)
Deploying a minimal flask app in docker - server connection issues
(8 answers)
Closed last year.
In simple hello world app in Node.js the port forwarding seems not to be working. When I am inside container and I run curl, I get correct response. Anyway from the main os I get empty reply from server.
Command docker container exec -it vigorous_knuth curl 127.0.0.1:80 produces Hello World
Command curl 127.0.0.1:80 produces curl: (52) Empty reply from server
OS: MacOs 12.1
Docker: Docker version 20.10.12, build e91ed57
Dockerfile:
FROM node
WORKDIR /code
COPY . .
ENV PORT 80
EXPOSE $PORT
RUN npm install curl
CMD ["node", "app.js", "&"]
App:
const http = require('http');
const hostname = '127.0.0.1';
const port = 80;
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}/`);
});
Command:
docker run -p 80:80 site:0.0.16
Related
I am trying to implement Varnish for a small small node js server
(index.js)
const port = 80;
require("http").createServer((req, res) => {
res.write(new Date().toISOString());
res.end();
}).listen(port, () => {
console.log(`http://127.0.0.1:${port}/`);
})
(default.vcl)
vcl 4.1;
backend default {
.host = "127.0.0.1";
.port = "80";
}
(CMD)
//now I run docker with following commands
docker run --name varnish -p 8080:80 -e VARNISH_SIZE=2G varnish:stable
docker cp default.vcl varnish:/etc/varnish
(Followed By restart container)
But All i see is following error:
Error 503 Backend fetch failed
Backend fetch failed
Guru Meditation:
XID: 31
Varnish cache server
You have a problem in your varnish configuration. You have set:
backend default {
.host = "127.0.0.1";
.port = "80";
}
But 127.0.0.1 (or localhost) means "this container", and your backend is not running inside the same container as Varnish. If your node.js server is running on your host, you probably want to do something like this:
vcl 4.1;
backend default {
.host = "host.docker.internal";
.port = "80";
}
And then start the container like this:
docker run --name varnish -p 8080:80 --add-host=host.docker.internal:host-gateway -e VARNISH_SIZE=2G varnish:stable
This maps the hostname host.docker.internal to mean "the host on which Docker is running".
If your node.js is running in another container, the solution is going to look a little different.
I have this Dockerfile:
FROM nginx:latest
COPY devops/nginx_proxy.conf /etc/nginx/conf.d/default.conf
EXPOSE 8080
and a devops/nginx_proxy.conf:
server {
listen 8080;
client_max_body_size 32M;
underscores_in_headers on;
}
Running the Dockerfile with docker run -p 8080:80 test and then testing with curl http://localhost/, I see this error:
curl: (7) Failed to connect to localhost port 80: Connection refused
Even more curious, curl http://localhost:8080/ returns this:
curl: (52) Empty reply from server
Why am I getting these errors?
With Docker you can bind containers ports to host ports using the -p option.
General rule
docker run -p HOST_PORT:CONTAINER_PORT
Bind container 8080 port to the 80 of the host
docker run -p 80:8080 test
Ports which are not bound to the host (i.e., -p 80:80 instead of -p 127.0.0.1:80:80) are accessible from the outside
Bind the port limiting the access to localhost
docker run -p 127.0.0.1:80:8080 test
I have a Go server which something like that. Router is Gorilla MUX
var port string
if port = os.Getenv("PORT"); port == "" {
port = "3000"
}
srv := &http.Server{
Handler: router,
Addr: "localhost:" + port,
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
fmt.Println("Server is running on port " + port)
log.Fatal(srv.ListenAndServe())
Dockerfile is
# Build Go Server
FROM golang:1.14 AS go-build
WORKDIR /app/server
COPY cmd/ ./cmd
COPY internal/ ./internal
COPY go.mod ./
COPY go.sum ./
RUN go build ./cmd/main.go
CMD ["./main"]
I got successful a build. I ran it with following command
docker run -p 3000:3000 baaf0159d0cd
And I got following output. Server is running
Server is running on port 3000
But when I tried to send request with curl I got empty response
>curl localhost:3000
curl: (52) Empty reply from server
Why is server not responding properly? I have another routes which I did not put here and they are not responding correctly too. I am on MacOS by the way.
Don't use localhost (basically an alias to 127.0.0.1) as your server address within a Docker container. If you do this only 'localhost' (i.e. any service within the Docker container's network) can reach it.
Drop the hostname to ensure it can be accessed outside the container:
// Addr: "localhost:" + port, // unreachable outside container
Addr: ":" + port, // i.e. ":3000" - is accessible outside the container
I have configured my router to expose http 80 on my local machine ip address:
ie '192.168.0.79', and exposed both inbound and outbound ip address, including allowing through firewall. For the purpose of this example lets say its "200.200.200.200"
I have a node server running locally on this same ip address which works and I can see 'hello world' when I visit my exposed ip address, eg: 200.200.200.200 on my web browser. This works.
import yargs from 'yargs';
import express from 'express';
const app = express();
const argv = yargs.argv;
const host = argv.host ;
const port = argv.port;
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(port, host, function() {
console.log('listening on ', host, ':', port);
});
when I stop the node server and instead run a docker container on the same ip address as follows:
docker run -p 192.168.0.79:80:8080 -p 50000:50000 --name myjenkins -v %cd%/jenkins:/var/jenkins_home jenkins/jenkins
I can see this locally on my machine, but when trying to access it from external webbrowser, eg: "200.200.200.200" it simply returns - HTTP ERROR 504
Is there something else I need to expose via the docker container to make this visible online?
I'm having the same issue with an nginx image. So i'm convinced there is something missing in my docker arguments.
Dockerfile
FROM nginx:alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY dist /usr/share/nginx/html/dist
COPY nginx/default.conf /etc/nginx/conf.d/
docker build -t nginx_image .
docker run -p 192.168.0.79:80:8080 nginx_image
Sounds like a return route issue. Log onto your docker container and see if you can ping 8.8.8.8. Also run netstat -r and see what the default route is. It should be the internal IP address of your firewall.
ok so on much exhaustive research it seems there might be a problem with windows exposing these containers. Or it might be something more advanced regarding proxying this container to the outside.
My solution. Create a node server that proxys to the localhost on my machine.
step 1 - get my ip address for this particular desktop computer on the ethernet
start > cmd
ipconfig
Ethernet adapter Ethernet 4 (Yours will be different. Which ever is connected to the internet):
...
IPv4 Address. . . . . . . . . . . : 192.168.0.79
step 2 - configure router, sky or other, to expose this ip to the internet
visit 192.168.0.2
user: admin
pass: sky
Advanced > Lan IP Setup > LAN TCP/IP Setup
LAN TCP/IP Setuphelp
IP Address:
192. 168. 0. 1
IP Subnet Mask:
255. 255. 255. 0
TICK - Use Router as DHCP Serverhelp
Starting IP Address:
192. 168. 0. 2
Ending IP Address:
192. 168. 0. 254
Address Reservation > Add
cmd
ip address: 192.168.0.79
Mac adress: (This number will look something like 4c:a2:e0 etc.... - can by got by going to a website and typing whats my ip)
Device Name: (Right click my computer > properties) MYCOMPUTERNAME
Security > Firewall Rules > Outbound services > Edit
Service: http: tcp 80
action: allow always
access from: any
0 0 0 0
Security > Firewall Rules > Inbound services > Edit
Service: http: tcp 80
action: allow always
Destination IPv4 LAN address: 192.168.0.79
access from: any
step 3 - create a docker container (ie jenkins), that will default to localhost, and expose the port on something other than 80, ie 81. (We need 80, to be exposed via our router)
Create docker container on localhost:81
docker run -p 81:8080 -p 50000:50000 --name myjenkins -v %cd%/jenkins:/var/jenkins_home jenkins/jenkins
step 4 - Create a node server or equivalent that will proxy the exposed ip address to this localhost
Create a proxy server that redirects 192.168.0.79 to localhost:81
import express from 'express';
import httpProxy from 'http-proxy';
const app = express();
const host = '192.168.0.79' ;
const port = '80';
const apiProxy = httpProxy.createProxyServer();
app.all('/*', (req, res) => {
console.log('redirecting to docker container - http://localhost:81');
apiProxy.web(req, res, {target: 'http://localhost:81'});
});
app.listen(port, host, function() {
console.log('listening on ', host, ':', port);
});
step 5 - type into a webbrowser - whats my ip
ipv4 will by something like 30.132.323.11
Now type this into a webbrowser and you should see your docker container exposed via the node server proxy.
getting this error while curl the application ip
curl (56) Recv failure: Connection reset by peer - when hitting docker container
Do a small check by running:
docker run --network host -d <image>
if curl works well with this setting, please make sure that:
You're mapping the host port to the container's port correctly:
docker run -p host_port:container_port <image>
Your service application (running in the container) is running on localhost or 0.0.0.0 and not something like 127.0.0.1
I GOT the same error
umesh#ubuntu:~/projects1$ curl -i localhost:49161
curl: (56) Recv failure: Connection reset by peer
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
in my case it was due wrong port no
|---MY Projects--my working folder
--------|Dockerfile ---port defined 8080
--------|index.js-----port defined 3000
--------|package.json
then i was running ::::
docker run -p 49160:8080 -d umesh1/node-web-app1
so as the application was running in port 3000 in index.js it was not able to connect to the application got the error as u were getting
So TO SOLVE THE PROBLEM
deleted the last container/image that was created my worong port
just change the port no of INDEX.JS
|---MY Projects--my working folder
--------|Dockerfile ---port defined 8080
--------|index.js-----port defined 8080
--------|package.json
then build the new image
docker build -t umesh1/node-web-app1 .
running the image in daemon mode with exposed port
docker run -p 49160:8080 -d umesh1/node-web-app1
THUS MY APPLICATION WAS RUNNING without any error listing on port 49161
I have same when bind to port that is not lissened by any service inside container.
So check -p option
-p 9200:9265
-p <port in container>:<port in host os to be binded to>