%20ist%20beim%20Verbinden%20mit%20Upstream%20fehlgeschlagen%20(111%3A%20Verbindung%20abgelehnt)%2C%20Client%3A%20192.168.128.1%2C%20Server%3A%20hello-1.local.png)
Ich versuche, SSL in meiner Django-, Docker- und Nginx-Umgebung einzurichten. Allerdings ist mir dieser Fehler begegnet:
*19 connect() ist fehlgeschlagen (111: Verbindung abgelehnt) beim Verbinden mit Upstream, Client: 192.168.128.1, Server: hello-1.local, Anfrage: „GET / HTTP/1.1“, Upstream: „https://192.168.128.4:443/“, Host: „hello-1.local“
Meine Nginx-Konfiguration:
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
Im Browser erhalte ich die Fehlermeldung „502 Bad Gateway“ und ohne SSL läuft die Website einwandfrei. Was könnte das Problem sein?
Antwort1
Was ist also der Upstream?
Der Upstream wird hier definiert:
upstream web {
ip_hash;
server web:443;
}
Mein erster Eindruck davon ist, dass Nginx keine ordnungsgemäße Verbindung zum Upstream-Server mit dem Namen herstellen kann web
.
Dies kann mehrere Gründe haben:
- Ihr Nginx kann nicht lösen
web
- Der Webserver, auf dem ausgeführt wird,
web
stellt kein HTTPS/Port 443 bereit - Der Webserver verwendet
web
kein gültiges und vertrauenswürdiges Zertifikat für den Hostnamenweb
Werfen Sie einen Blick auf Ihre docker-compose.yml:
- Die Anwendung
web
ist auf Port 8000 verfügbar, Sie möchten aber eine Verbindung zu Port 443 in Nginx herstellen und verwenden dabei (vermutlich) auch das falsche Protokoll.
Die Lösung wäre also, Ihre Upstream-Konfiguration in nginx.conf wie folgt zu ändern:
upstream web {
ip_hash;
server web:8000;
}
und der Standortblock wie folgt (https --> http):
location / {
proxy_pass http://web/;
}
Bezüglich SSL/TLS mit Proxys/Upstreams: Bitte werfen Sie einen Blick in die Nginx-Dokumente dazu:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify
Antwort2
Ich habe ein ähnliches Setup in meiner Webanwendung, wo Nginx ein Reverse-Proxy für Dockerized Django und React ist. Ich verwende auch ein selbstsigniertes Zertifikat für SSL in der lokalen Entwicklung.
Ich hatte Schwierigkeiten, weil React (Next.js) Daten von Djangos REST-API abruft – aber einige Anfragen kommen vom Server, während andere vom Client kommen. Serverbasierte Anfragen konnten http://backend:8000
(den Docker-Dienstnamen und den freigegebenen Port) verwenden, aber clientbasierte Anfragen mussten durch https://example.local
.
Wenn jemand hier nicht weiterkommt und Swagger UI (z. B. drf-yasg) verwendet, war dies meine Achillesferse – Sie MÜSSEN die OpenAPI „DEFAULT_API_URL“ konfigurieren. Wenn Sie ein selbstsigniertes SSL-Zertifikat mit haben example.local
, sollten Sie dies als Ihre Swagger-URL einrichten https://example.local
. Mit drf-yasg
ist hier meine 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,
}
Zusätzlich musste ich dies in meiner Next.js-Konfiguration anpassen ( next.config.js
):
const nextConfig = {
...
assetPrefix: 'https://example.local',
...
}
Schließlich sieht meine Nginx-Konfiguration folgendermaßen aus:
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;
}