Score:1

connect() failed (111: Connection refused) while connecting to upstream with static website

cn flag

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.

Score:0
in flag

The port directive in docker-compose defines which port is exposed to the outside. Your reverse proxy container can access the services in inside the static-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:

links:
  - static-website

Your proxy_pass directive should be:

proxy_pass              http://sm_static_website;

If you don't want to actually expose the static-website container to the outside you can remove the ports directive there.

So the docker-compose.yml should look like this:

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
    links:
      - sm_static_website
  static-website:
    image: sm-static-website
    build:
      context: ./website
    container_name: sm_static_website

TBH: I never found it useful to use the container_name directive, I'm not sure if you have to use the defined container_name sm_static_website or just static-website in the links and in the proxy_pass directives. If you leave it out it would be just static-website.

cn flag
Thanks Gerald, changing to port 80 worked. First time dealing with linux and coker, so that is why this newbie question. P.S. Links uses <service-name>, so
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.