Issue with deploying Plone 6 on Plesk server

I'm currently trying to deploy Plone 6 (with a Volto frontend) using Docker on a Debian server running Plesk as a POC.
I know that this is probably far from any recommended setup, but I would like to stick to Plesk since it is what my company used so far and it would be a great convenience for multiple reasons.

My current setup looks like this:
Docker containers for Plone 6, Volto, PostgreSQL and nginx webserver.
In Plesk I used the Docker proxy setting to forward to the dockerized nginx webserver.

Most of it is based on the Plone 6 cookiecutter template with a few customizations to fit my requirements.
Here's my current docker-compose.yml:

version: "3"
services:

  webserver:
    image: nginx
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - herme-backend
      - hermedemo-ch-frontend
    ports:
      - "8000:80"

  hermedemo-ch-frontend:
    build:
      context: ./hermedemo-ch
    environment:
      RAZZLE_INTERNAL_API_PATH: http://herme-backend:8080/hermedemo-ch
    ports:
    - "3001:3000"
    depends_on:
      - herme-backend

  herme-backend:
    build:
      context: ./herme-backend
    environment:
      ADDITIONAL_PROFILES: "herme_backend:default,herme_backend:initial"
      RELSTORAGE_DSN: "dbname='x' user='x' host='db' password='x'"
    ports:
    - "8080:8080"
    depends_on:
      - db

  db:
    image: postgres
    environment:
      POSTGRES_USER: x
      POSTGRES_PASSWORD: x
      POSTGRES_DB: x
    volumes:
    - data:/var/lib/postgresql/data

volumes:
  data: {}

And here's my current default.conf for the dockerized nginx (based on this):

upstream backend {
  server herme-backend:8080;
}
upstream frontend {
  server hermedemo-ch-frontend:3000;
}

server {
  listen 80;
  server_name hermedemo.ch;

  client_max_body_size 1G;

  access_log /dev/stdout;
  error_log /dev/stdout;

  # [seamless mode] Recomended as default configuration, using seamless mode new plone.rest traversal
  # yarn build && yarn start:prod
  location ~ /\+\+api\+\+($|/.*) {
      rewrite ^/(\+\+api\+\+\/?)+($|/.*) /VirtualHostBase/http/$server_name/hermedemo-ch/++api++/VirtualHostRoot/$1 break;
      proxy_pass https://backend;
  }

  location ~ / {
      location ~* \.(js|jsx|css|less|swf|eot|ttf|otf|woff|woff2)$ {
          add_header Cache-Control "public";
          expires +1y;
          proxy_pass https://frontend;
      }
      location ~* static.*\.(ico|jpg|jpeg|png|gif|svg)$ {
          add_header Cache-Control "public";
          expires +1y;
          proxy_pass https://frontend;
      }

      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;
      proxy_redirect http:// https://;
      proxy_pass https://frontend;
  }
}

I first tried to run it without a dockerized webserver and just set the proxy directly to the Volto frontend, since Plesk already provides its own nginx. While this does work, the issue with it is that Volto appends :null to the root of every URL as seen here:

:null root URLs

Then I added the nginx webserver to the Docker stack, which also works but then a CORS mixed content issue appears because the Volto app is making calls to the RestAPI via http while running on https.

Mixed Content Errors

I already found this thread where a simliar issue was mentioned, but I did not manage to get the solution from that to work in my case.

Since most guides also tell me to stay away from dealing with CORS issues, I would very much like to avoid that. I already tried setting add_header Access-Control-Allow-Origin *; anyway, but it didn't make a difference.

So my questions are:

  • Is there any way to make this even work with Plesk?
  • What's up with the :null in the URLs, any way to prevent that from happening?
  • Is the dockerized nginx neccesary to make it work?
  • Are there any mistakes in my docker-compose or nginx configs that I missed?

Thanks in advance for your help :blue_heart:

Forgot to add in my post, used versions are:

Volto 16.20.4
Plone 6.0.4
plone.restapi 8.37.0
CMF 2.7.0
Zope 5.8.1
Python 3.11.3

I just tried using the config provided by the example for nginx, Frontend, Backend, PostgreSQL provided by the Plone 6 docs.

Even when using the official Plone images, I still get the exact same results.

If I set the docker proxy to the nginx webserver, I get mixed content errors.
If I set it to the Volto frontend, it puts :null into the root of every URL on the page.

By now my guess is, the nginx provided by Plesk does something weird while redirecting to the Docker container that causes Volto to fail somewhere and break the URL generation.

I was finally able to solve the issue :tada:

Still can't fully explain what exactly the cause of the problem was, but using the information found in the Volto Docs I set RAZZLE_PROXY_REWRITE_TARGET = ... to my desired value and now my deployment works.

I also found out, that the :none in the URL root was coming from plone.restapi itself when accessing it over Volto in seamless mode. So my best guess would be that Volto got handed some wrong information by the Plesk nginx webserver and seamless mode handed that over to the RestAPI.
Somehow, using the same rewrite rule in a dockerized nginx webserver did not solve anything, but setting the env variable in the docker compose file did.

Anyway, it works now without me having to deal with CORS :partying_face: