Skip to content

502 Bad Gateway & Upstream connection refused #2378

@ethanbeyer

Description

@ethanbeyer

Quick Overview

I use Nginx Proxy for local web development. It allows me to create "pretty URLs" for the different apps and websites I'm working on. I've had a running Nginx Proxy for the better part of a year, but recently needed to add a new virtualhost, and since then I cannot get Nginx Proxy to load anything other than 502 Bad Gateway.

As far as I can tell, I have configured these different containers correctly, but I continually see these errors in the nginx-proxy's logs:

2024-01-24 10:25:11 nginx.1     | whoami.local 192.168.65.1 - - [24/Jan/2024:15:25:11 +0000] "GET / HTTP/1.1" 502 157 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0" "172.18.0.3:8400"
2024-01-24 10:25:11 nginx.1     | 2024/01/24 15:25:11 [error] 25#25: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.65.1, server: whoami.local, request: "GET / HTTP/1.1", upstream: "http://172.18.0.3:8400/", host: "whoami.local"

Can someone point out where I've gone wrong? Configs attached.

Configs

Nginx Proxy docker-compose.yml:

version: '3'

services:
  proxy:
    image: nginxproxy/nginx-proxy:1.4
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    networks:
      - nginx-proxy
    restart: always

networks:
  nginx-proxy:
    name: local-dev
    driver: bridge

Test Whoami docker-compose.yml:

version: '3'

services:

  whoami:
    image: jwilder/whoami
    expose:
      - "8400"
    environment:
      - VIRTUAL_HOST=whoami.local
      - VIRTUAL_PORT=8400
    networks:
      - local-dev

networks:
  local-dev:
    external: true

Local hosts file:

127.0.0.1    whoami.local

Generated Nginx Configs from nginx-proxy Container

# nginx-proxy version : 1.4.0-71-gd46881f
# Networks available to the container running docker-gen (which are assumed to
# match the networks available to the container running nginx):
#     local-dev
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
    default $http_x_forwarded_proto;
    '' $scheme;
}
map $http_x_forwarded_host $proxy_x_forwarded_host {
    default $http_x_forwarded_host;
    '' $host;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
    default $http_x_forwarded_port;
    '' $server_port;
}
# If the request from the downstream client has an "Upgrade:" header (set to any
# non-empty value), pass "Connection: upgrade" to the upstream (backend) server.
# Otherwise, the value for the "Connection" header depends on whether the user
# has enabled keepalive to the upstream server.
map $http_upgrade $proxy_connection {
    default upgrade;
    '' $proxy_connection_noupgrade;
}
map $upstream_keepalive $proxy_connection_noupgrade {
    # Preserve nginx's default behavior (send "Connection: close").
    default close;
    # Use an empty string to cancel nginx's default behavior.
    true '';
}
# Abuse the map directive (see <https://stackoverflow.com/q/14433309>) to ensure
# that $upstream_keepalive is always defined.  This is necessary because:
#   - The $proxy_connection variable is indirectly derived from
#     $upstream_keepalive, so $upstream_keepalive must be defined whenever
#     $proxy_connection is resolved.
#   - The $proxy_connection variable is used in a proxy_set_header directive in
#     the http block, so it is always fully resolved for every request -- even
#     those where proxy_pass is not used (e.g., unknown virtual host).
map "" $upstream_keepalive {
    # The value here should not matter because it should always be overridden in
    # a location block (see the "location" template) for all requests where the
    # value actually matters.
    default false;
}
# Apply fix for very long server names
server_names_hash_bucket_size 128;
# Default dhparam
ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
# Set appropriate X-Forwarded-Ssl header based on $proxy_x_forwarded_proto
map $proxy_x_forwarded_proto $proxy_x_forwarded_ssl {
    default off;
    https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr"';
access_log off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305';
    ssl_prefer_server_ciphers off;
error_log /dev/stderr;
resolver 127.0.0.11;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_host;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
proxy_set_header X-Original-URI $request_uri;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
server {
    server_name _; # This is just an invalid value which will never trigger on a real hostname.
    server_tokens off;
    access_log /var/log/nginx/access.log vhost;
    http2 on;
    listen 80;
    listen 443 ssl;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    # No default.crt certificate found for this vhost, so force nginx to emit a
    # TLS error if the client connects via https.
    ssl_ciphers aNULL;
    set $empty "";
    ssl_certificate data:$empty;
    ssl_certificate_key data:$empty;
    if ($https) {
        return 444;
    }
    return 503;
}
# whoami.local/
upstream whoami.local {
    # Container: test-whoami-1
    #     networks:
    #         local-dev (reachable)
    #     IP address: 172.18.0.3
    #     exposed ports: 8000/tcp 8400/tcp
    #     default port: 80
    #     using port: 8400
    server 172.18.0.3:8400;
}
server {
    server_name whoami.local;
    access_log /var/log/nginx/access.log vhost;
    http2 on;
    listen 80 ;
    listen 443 ssl ;
    # No certificate found for this vhost, so force nginx to emit a TLS error if
    # the client connects via https.
    ssl_ciphers aNULL;
    set $empty "";
    ssl_certificate data:$empty;
    ssl_certificate_key data:$empty;
    if ($https) {
        return 444;
    }
    location / {
        proxy_pass http://whoami.local;
        set $upstream_keepalive false;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions