dockernginxdocker-composejbpm

Nginx reverse proxy (with TLS) to jBPM Business-Central doesn't work as expected


So my setup is simple. I'm using docker compose to spin up a DB, jBPM and a reverse proxy Nginx service so I can add custom domain and TLS to the equation here.

Docker-compose.yml

version: '3.8'

services:
  mysql:
    image: mysql:5.7
    volumes:
    - mysql_data:/var/lib/mysql
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: pass
      MYSQL_DATABASE: jbpm
      MYSQL_USER: user
      MYSQL_PASSWORD: pass
    
      
      
  jbpm:
    image: jboss/jbpm-server-full
    container_name: jbpm
    environment:
      - DB_DRIVER=mysql
      - DB_HOST=mysql
      - DB_PORT=3306
      - DB_NAME=jbpm
      - DB_USER=user
      - DB_PASSWORD=pass
    ports:
    - 8080:8080
    depends_on:
    - mysql
    

  swag:
    image: lscr.io/linuxserver/swag:latest
    container_name: swag
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - URL=my.domain.com
      - VALIDATION=http
    volumes:
      - /localuser/jbpm/config:/config
    ports:
      - 443:443
      - 80:80 #optional
    restart: unless-stopped
    depends_on:
    - jbpm
    
volumes:
  mysql_data:
    driver: local

And here is my site's my.domain.com.conf file that I have put inside /localuser/jbpm/config/nginx/site-confs/

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name my.domain.com;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    location / {
        return 301 /business-central/;
    }

    location /business-central/ {

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app jbpm;
        set $upstream_port 8080;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
        
        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;
        proxy_set_header Accept-Encoding *;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection “upgrade”;


    }
 
}

server {
    listen 80;
    server_name my.domain.com;

    location / {
        return 301 https://$host$request_uri;
    }

    location ~ /.well-known/acme-challenge {
        allow all;
    }
}

The problem that I'm getting is that after login when browsing https://my.domain.com/ I the app shows loading and then I receive a blank page, while if I browse like this http://[IP]:8080/ I receive everything.

That shows it's a problem of the reverse-proxy conf in conjunction with jBPM and Wildfly I guess.

PS: I'm able to browse the app with IP and internal port on purpose (it's exposed) so I can see scenarios like this.


Solution

  • Here is an example where business-central can be accessed through nginx.
    Nginx works with https here. Communication nginx --> business-central is done over http.
    It turns out business-central makes use of Server Side Events and these need to be configured accordingly in nginx.

    Here is the configuration:

    compose.yml

    version: '3.8'
    
    services:
      mysql:
        image: mysql:5.7
        volumes:
        - mysql_data:/var/lib/mysql
        container_name: mysql
        environment:
          MYSQL_ROOT_PASSWORD: pass
          MYSQL_DATABASE: jbpm
          MYSQL_USER: user
          MYSQL_PASSWORD: pass
          
          
      jbpm:
        image: jboss/jbpm-server-full
        container_name: jbpm
        environment:
          - DB_DRIVER=mysql
          - DB_HOST=mysql
          - DB_PORT=3306
          - DB_NAME=jbpm
          - DB_USER=user
          - DB_PASSWORD=pass
        ports:
        - 8080:8080
        depends_on:
        - mysql
        
    
      nginx:
        image: nginx:latest
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf
          - ./certs:/etc/nginx/ssl
        depends_on:
          - nginx-certs-generation
    
        
      nginx-certs-generation:
        image: alpine:latest
        command: >
          sh -c "
          if [ ! -f /certs/selfsigned.crt ]; then 
            apk add --no-cache openssl && 
            openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /certs/selfsigned.key -out /certs/selfsigned.crt -subj '/CN=${NGINX_DOMAIN_NAME}';
          else 
            echo 'Certificate already exists, skipping generation.';
          fi"
        volumes:
          - ./certs:/certs
    
    
    volumes:
      mysql_data:
        driver: local
    

    nginx.conf:

    worker_processes 1;
    events {
        worker_connections 1024;
    }
    http {
        upstream jbpm {
            server jbpm:8080;
        }
    
        server {
            listen 80;
            location / {
                return 301 https://$host$request_uri;
            }
        }
    
        server {
            listen 443 ssl;
    
            ssl_certificate /etc/nginx/ssl/selfsigned.crt;
            ssl_certificate_key /etc/nginx/ssl/selfsigned.key;
            ssl_protocols TLSv1.2 TLSv1.3;
            ssl_ciphers HIGH:!aNULL:!MD5;
    
            location /business-central/ {
                proxy_pass http://jbpm/business-central/;
                proxy_set_header Host $host;
                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;
    
                # config for SSE
                proxy_set_header Connection '';
                proxy_http_version 1.1;
                chunked_transfer_encoding off;
                proxy_buffering off;
                proxy_cache off;
    
    
                # Increase the timeouts for long-lived connections
                proxy_connect_timeout 3600s;
                proxy_send_timeout 3600s;
                proxy_read_timeout 3600s;
                send_timeout 3600s;
            }
        }
    }