dockernginxssl

ERR_SSL_PROTOCOL_ERROR when the frontend accesses the backend


The frontend opens in https, accesses the backend at my_domain/api/start, but the response is not returned and there is an error in the console:

GET https://my_domain.com:8082/api/start net::ERR_SSL_PROTOCOL_ERROR

Here is my nginx.conf:

server {
    listen 80;
    server_name my_domain.com www.my_domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name my_domain.com www.my_domain.com;

    root /usr/share/nginx/html;
    index index.html;

    ssl_certificate /etc/nginx/ssl/certificate.crt;
    ssl_certificate_key /etc/nginx/ssl/private.key;

    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:HIGH:!aNULL:!MD5;

    # API Backend proxy
    location /api/ {
        proxy_pass http://backend:8082;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }

    error_page 404 /index.html;
}

My compose:

services:
  frontend:
    build:
     context: ./frontend
     args:
      NGINX_CONF: ${NGINX_CONF}
#    network_mode: host
#    depends_on:
#      - backend
    ports:
      - '80:80'
      - "443:443"
    volumes:
      - ./frontend/ssl:/etc/nginx/ssl
    environment:
      - ENVIRONMENT=${ENVIRONMENT}
  backend:
    build:
     context: ./backend
     args:
      CONFIG: ${CONFIG}
    ports:
      - '8082:8082'
      - '8443:8443'
    volumes:
      - ./frontend/ssl:/etc/nginx/ssl
    environment:
      - ENVIRONMENT=${ENVIRONMENT}

networks:
  app-network:
    driver: bridge

curl by http://my_domain:8082/api/start responds normally, without errors I tried so many variants and nothing changes.


Solution

  • GET https://my_domain.com:8082/api/start net::ERR_SSL_PROTOCOL_ERROR

    There is no HTTPS backend on port 8082. There is instead a plain HTTP backend on this port, which is available through the nginx reverse proxy on port 443:

    server {
        listen 443 ssl;
        server_name my_domain.com www.my_domain.com;
        ...
    
        # API Backend proxy
        location /api/ {
            proxy_pass http://backend:8082;
    

    So don't access the backend with https://my_domain.com:8082/api/start, but instead use https://my_domain.com/api/start (default port 443 instead of 8082), so that the access is done through nginx as reverse proxy (which provides HTTPS) instead directly to the backend (which does not provide HTTPS).