Nginx connect()在连接到上游时失败(111:连接被拒绝),客户端:192.168.128.1,服务器:hello-1.local

Nginx connect()在连接到上游时失败(111:连接被拒绝),客户端:192.168.128.1,服务器:hello-1.local

我正在尝试在 django + docker + nginx 环境中设置 ssl。但是我遇到了这个错误:

*19 connect() 连接到上游时失败(111:连接被拒绝),客户端:192.168.128.1,服务器:hello-1.local,请求:“GET / HTTP/1.1”,上游:“https://192.168.128.4:443/”,主机:“hello-1.local”

我的 Nginx 配置:

client_max_body_size 10M;

upstream web {  
  ip_hash;
  server web:443;
}

server {
    listen 80;
    server_name hello-1.local;
    return 301 https://$host$request_uri;
}

server {    
    
    location /static/ {    
        autoindex on;    
        alias /src/static/; 
    }

    location /media/ {
        autoindex on;
        alias /src/media/;
    }

``

    location / {
        proxy_pass https://web/;
    }
    
    listen 443 ssl;
    server_name hello-1.local;
    ssl_certificate /etc/certs/hello-1.local.crt;
    ssl_certificate_key /etc/certs/hello-1.local.key;
    
} 

docker-compose.yml:

version: "3"

volumes:
  local_postgres_data: {}
  local_postgres_data_backups: {}

services:
  nginx:
    image: nginx:alpine
    container_name: nz01
    ports:
      - 443:443
      - 80:80
    volumes:
      - ./src:/src
      - ./config/nginx:/etc/nginx/conf.d
      - ./config/certs:/etc/certs
    depends_on:
      - web
    networks:
      - djangonetwork
  web:
    build:
      context: .
      dockerfile: compose/django/Dockerfile
    container_name: dz01
    depends_on:
      - db
    volumes:
      - ./src:/src
    expose:
      - 8000
    links:
      - redis
    env_file:
      - ./.envs/.django
    networks:
      - djangonetwork
  db:
    build:
      context: .
      dockerfile: compose/postgres/Dockerfile
    container_name: pz01
    env_file:
      - ./.envs/.postgres
    volumes:
      - local_postgres_data:/var/lib/postgresql/data
      - local_postgres_data_backups:/backups
    networks:
      - djangonetwork
  redis:
    image: redis:alpine
    container_name: rz01
    ports:
      - "6379:6379"
    networks:
      - djangonetwork

networks:
  djangonetwork:
    driver: bridge

在浏览器中,我收到 502 Bad Gateway 错误,并且没有 SSL,网站运行良好。可能是什么问题?

答案1

那么上游是什么?

上游定义如下:

upstream web {  
  ip_hash;
  server web:443;
}

我对此的第一印象是,Nginx 无法正确连接到名为的上游服务器web

这可能有多种原因:

  • 你的 Nginx 无法解析web
  • 正在运行的 Web 服务器web未提供 https/port 443 服务
  • 运行的 Web 服务器web未使用有效且受信任的主机名证书web

看一下你的docker-compose.yml:

  • 应用程序web暴露在端口 8000 上,但你想连接到 Nginx 中的端口 443,也使用了错误的协议(我猜)

因此解决方案是像这样更改 nginx.conf 中的上游配置:

upstream web {  
  ip_hash;
  server web:8000;
}

并且位置块如下(https --> http):

location / {
    proxy_pass http://web/;
}

关于代理/上游的 SSL/TLS:请查看 Nginx 文档中的相关内容:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify

答案2

我的 Web 应用程序中也有类似的设置,其中 Nginx 是 Dockerized Django 和 React 的反向代理。我在本地开发中也使用自签名证书进行 SSL。

我遇到了困难,因为 React (Next.js) 正在从 Django 的 REST API 获取数据——但有些请求来自服务器,而其他请求来自客户端。基于服务器的请求可以使用http://backend:8000(Docker 服务名称和公开端口),但基于客户端的请求需要经过https://example.local

如果有人遇到这个问题并使用 Swagger UI(即 drf-yasg),这就是我的致命弱点——您需要配置 OpenAPI“DEFAULT_API_URL”。如果您有自签名 SSL 证书example.local,则应将其设置https://example.local为您的 Swagger URL。使用drf-yasg,这是我的settings.py

# Swagger
ENDPOINT_DOMAIN = "https://example.com"
if DEBUG:
    ENDPOINT_DOMAIN = "https://example.local"
SWAGGER_SETTINGS = {
    'SECURITY_DEFINITIONS': {
        'basic': {
            'type': 'basic'
        }
    },
    'DEFAULT_API_URL': ENDPOINT_DOMAIN,
}

此外,我必须在我的 Next.js 配置中匹配这一点(next.config.js):

const nextConfig = {
  ...
  assetPrefix: 'https://example.local',
  ...
}

最后,我的 Nginx 配置如下:

server {
  listen 80;
  listen [::]:80;

  server_name example.local;
  return 302 https://example.local$request_uri;
}

# Main server directive
server {
  http2               on;

  listen 443          default ssl;
  listen [::]:443     default ssl;

  ssl_certificate     /etc/nginx/certs/example.test.crt;
  ssl_certificate_key /etc/nginx/certs/example.test.key;

  root                /app;
  server_name         example.local;

  charset utf-8;

  gzip on;
  gzip_disable "msie6";
  gzip_comp_level 6;
  gzip_min_length 1100;
  gzip_buffers 16 8k;
  gzip_proxied any;
  gzip_types
    text/plain
    text/css
    text/js
    text/xml
    text/javascript
    application/javascript
    application/json
    application/xml
    application/rss+xml
    image/svg+xml;

  # Setup frontend requests to use port 3000
  location @frontend {
    internal;
    root       /app/frontend/;
    proxy_pass http://frontend:3000;

    proxy_redirect off;
    proxy_set_header Host              $host;
    proxy_set_header X-Forwarded-For   $remote_addr;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-NginX-Proxy     true;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Url-Scheme      $scheme;
  }

  # Setup backend requests to use port 8000
  location @backend {
    proxy_pass http://backend:8000;

    proxy_redirect off;
    proxy_ssl_verify off;
    proxy_set_header Host              $host;
    proxy_set_header X-Forwarded-For   $remote_addr;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-NginX-Proxy     true;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Url-Scheme      $scheme;
  }

  # Frontend =============================================
  location / {
    try_files $uri @frontend;
  }

  location ~ ^/assets/(.*)$ {
    root      /app/frontend/public/;
    try_files $uri @frontend;
  }

  location ~ ^/favicon(.*)$ {
    root      /app/frontend/public/assets/favicon/;
    try_files $uri @frontend;
  }

  location ~ ^/_next/(.*)$ {
    root      /app/frontend/;
    try_files $uri @frontend;
  }

  location /_next/webpack-hmr {
    root      /app/frontend/;
    try_files $uri @frontend;

    # Websockets
    proxy_http_version 1.1;
    proxy_set_header   Connection "upgrade";
    proxy_set_header   Upgrade $http_upgrade;
  }

  location /404 {
    try_files $uri @frontend;
  }


  # Backend ===============================================
  location ~ ^/swagger(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/redoc(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/admin(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/api(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/webmention(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/rss(.*)$ {
    try_files $uri @backend;
  }

  location /sitemap.xml {
    try_files $uri @backend;
  }

  location ~ ^/static/(.*)$ {
    root      /app/backend/;
    try_files $uri @backend;

    autoindex on;
  }

  location ~ ^/uploads/(.*)$ {
    root      /app/backend/;
    try_files $uri @backend;
  }

  location /(500|502|503|504) {
    try_files $uri @backend;
  }

  # Error handling
  error_page 404 /404;
  error_page 500 502 503 504 /500;
}

相关内容