My goal is to have 2 docker containers:
- nginx container (based on nginx:latest) to work as reverse proxy
- container with static website (based on nginx:alpine)
Later I will add 1+ .net core backend services (not important for now). Currently when I try to access my webserver using public ip address, I get 502 Bad gateway. Here is my current configuration:
docker-compose.yaml
version: '3'
services:
reverse-proxy:
image: nginx:latest
container_name: reverse_proxy
depends_on:
- static-website
volumes:
- ./reverse_proxy/nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:80
static-website:
image: sm-static-website
build:
context: ./website
container_name: sm_static_website
ports:
- "8080:80"
nginx.conf for reverse-proxy:
worker_processes auto;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 1024;
}
http {
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name x.x.x.x; # my_public_ip
location / {
proxy_pass http://sm_static_website:8080;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
Dockerfile for static website:
FROM nginx:alpine
WORKDIR /html
COPY . /var/www/html
EXPOSE 8080
From my website container I can see that nginx is running / listening on 80:
netstat -tulpn | grep LISTEN
tcp 0 0 127.0.0.11:41389 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro
tcp 0 0 :::80 :::* LISTE 1/nginx: master pro
From my server I can see that both remote_proxy and website containers are listening to 80/8080, respectively:
netstat -tulpn | grep LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 13936/docker-proxy
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 13797/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 13942/docker-proxy
tcp6 0 0 :::8080 :::* LISTEN 13804/docker-proxy
ps -aux on server returns:
root 13936 0.0 0.0 1075140 3580 ? Sl 00:24 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.18.0.3 -container-port 80
root 13797 0.0 0.0 1148872 3624 ? Sl 00:24 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.18.0.2 -container-port 80
Website container's log shows no error, worker processes are running. However, reverse proxy log shows:
2022/05/20 01:20:29 [error] 31#31: *1 connect() failed (111: Connection refused) while connecting to upstream, client: x.x.x.x, server: x.x.x.x, request: "GET / HTTP/1.1", upstream: "http://172.19.0.2:8080/", host: "x.x.x.x"
Any ideas what I am doing wrong? If I remove volumes: line from docker-compose.yml, then I get the default nginx page from the reverse-proxy container. This indicates that it is listening properly, accepting the request, but does not redirect it to website container.
Best Answer
The
port
directive in docker-compose defines which port is exposed to the outside. Your reverse proxy container can access the services in inside thestatic-website
directly when they are linked together, so you don't use the exposed port here.Since your website inside the container
static-website
is listening on port 80 you need to use that instead of the exposed ports.First you need to link the containers together, to do that you add to the
reverse-proxy
block:Your
proxy_pass
directive should be:If you don't want to actually expose the
static-website
container to the outside you can remove theports
directive there.So the
docker-compose.yml
should look like this:TBH: I never found it useful to use the
container_name
directive, I'm not sure if you have to use the defined container_namesm_static_website
or juststatic-website
in thelinks
and in theproxy_pass
directives. If you leave it out it would be juststatic-website
.