Reputation: 5455
I'm having no luck putting a bare bones nginx reverse proxy in front of my java/tomcat app, which works fine on port 8080 . My browser gets back an empty response, and I see no logging or errors on the servers.
This is my nginx Dockerfile:
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 10040
CMD ["nginx"]
and my nginx.conf from nginx -T
$ docker run -p 10040:8080 --name rproxy --rm we1p2xxxxxxx.xxx.xx.com:11095/myapp-rproxy nginx -T
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
daemon off;
error_log /dev/stdout info;
worker_processes 1;
events { worker_connections 1024; }
http {
access_log /dev/stdout;
sendfile on;
upstream docker-myapp {
server localhost:8080;
}
server {
listen 10040;
location / {
proxy_pass http://docker-myapp;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
When I call http://localhost:10040/ from a browser, I get nothing back - an empty response. Not even a response status.
Nothing is logged either - no error, no access log, both of which I have redirected to /dev/stdout
This is the start-up logging output from nginx:
$ docker run -p 10040:8080 --name rproxy --rm we1pxxxxxxxx.xxx.xxx.com:11095/myapp-rproxy nginx-debug
2017/11/29 14:17:06 [notice] 1#1: using the "epoll" event method
2017/11/29 14:17:06 [notice] 1#1: nginx/1.13.7
2017/11/29 14:17:06 [notice] 1#1: built by gcc 6.3.0 20170516 (Debian 6.3.0-18)
2017/11/29 14:17:06 [notice] 1#1: OS: Linux 4.9.49-moby
2017/11/29 14:17:06 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2017/11/29 14:17:06 [notice] 1#1: start worker processes
2017/11/29 14:17:06 [notice] 1#1: start worker process 7
I'm still trying to find out how to get more info from the logging - for instance, the port number it's listening on. Cygwin netstat
doesn't show anything listening on the 10040 port - although I've got EXPOSE 10040
in the Dockerfile.
This is docker ps
:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03d17ec349f7 we1pxxxxxxxx.xxx.xxx.com:11095/myapp-rproxy "nginx" 52 seconds ago Up 51 seconds 80/tcp, 10040/tcp, 0.0.0.0:10040->8080/tcp rproxy
eaf3ed033908 we1pxxxxxxxx.xxx.xxx.com:11095/myapp "/bin/sh -c 'java ..." 2 hours ago Up 2 hours 0.0.0.0:8080->8080/tcp myapp
This is what happens when I use curl
:
$ curl -i http://localhost:8080
HTTP/1.1 401
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="xx.xx.xx.COM"
Content-Length: 0
Date: Wed, 29 Nov 2017 15:57:38 GMT
$ curl -i http://localhost:10040
curl: (52) Empty reply from server
$
I'm using docker 17.09.0-ce-win33 on Windows 10, with cygwin.
Any hope, world?
[UPDATE 2017-11-30] Ports gotcha
Simple mistake pointed out by Alexander Altshuler in his answer - I was attaching nginx to 10040 inside the docker container already, so by trying to map 10040 to 80 with the command line -p 10040:80
parameter was blocking my requests - from which a couple of questions arise:
where should I see an error? Surely my curl request should have timed out with no ports listening?
why is the docker ps
PORTS
field showing 80/tcp
? Surely that's not open (curl
connection times out)
now with docker running it with -p 10040:10040
, I see this:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b6379d40d0c2 we1pxxxxxxxx.xxx.xxx.com:11095/myapp "/bin/sh -c 'java ..." 2 minutes ago Up 2 minutes 0.0.0.0:8080->8080/tcp myapp
d3d5feb9e63f we1pxxxxxxxx.xxx.xxx.com:11095/myapp-rproxy "nginx" 20 minutes ago Up 20 minutes 80/tcp, 0.0.0.0:10040->10040/tcp rproxy
and doing curl
I get this:
$ curl http://localhost:10040
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.13.7</center>
</body>
</html>
and NGINX spits out:
2017/11/30 10:07:32 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost:10040"
2017/11/30 10:07:32 [warn] 5#5: *1 upstream server temporarily disabled while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost:10040"
2017/11/30 10:07:32 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost:10040"
2017/11/30 10:07:32 [warn] 5#5: *1 upstream server temporarily disabled while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost:10040"
172.17.0.1 - - [30/Nov/2017:10:07:32 +0000] "GET / HTTP/1.1" 502 173 "-" "curl/7.56.1"
2017/11/30 10:07:32 [info] 5#5: *1 client 172.17.0.1 closed keepalive connection
Obviously there is still something rotten in the state of Denmark, but now I'm getting some logging I'm confident I'll sort this one out.
Upvotes: 0
Views: 7758
Reputation: 5455
Posted the solution first here:
Using a user-defined bridge network:
docker network create -d bridge myapp-net
And then I launch the containers, attaching them to the myapp-net
:
docker run -p 8080:8080 --network=myapp-net --name myapp --rm myregistry:11095/myapp
docker run -p 10040:443 --network=myapp-net --name rproxy --rm myregistry:11095/myapp-rproxy
Caveat: I don't yet understand why the default docker bridge network won't work despite reading the docker docs
Upvotes: 0
Reputation: 3064
The command to run docker coniatner should start with
docker run -p 10040:10040 ...
Update:
why is the docker ps PORTS field showing 80/tcp? Surely that's not open (curl connection times out)
I can imagine only one reason - you did provide docker run -p 80 ...
Why nginx responds with 502 Bad Gateway is clear:
you configured nginx to connect to localhost:8080, but from within container your backend run on external host.
The usual practice here - create user defined network:
docker network create --driver bridge mynetwork
docker run --network=isolated_nw -p 10040:8080 --name rproxy ...
docker run --network=isolated_nw --name myapp ...
Nginx config should looks like below:
daemon off;
error_log /dev/stdout info;
worker_processes 1;
events { worker_connections 1024; }
http {
# use docker embedded DNS server to resolve myapp host name
resolver 127.0.0.11;
access_log /dev/stdout;
sendfile on;
upstream docker-myapp {
server myapp:8080; # !!!
}
server {
listen 10040;
location / {
proxy_pass http://docker-myapp;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
Upvotes: 1