I am trying to do something relatively simple with Plone 6 using the Volto frontend. I want to migrate my personal website, currently running on old Plone installation (4.2!), and like where Volto is heading. I don’t necessarily need full developer capabilities, but do need to run it behind TLS/SSL and be able to add and change addons. At this point I am unable to tell whether the instructions for installing Plone 6 using containers (for instance the nginx, Frontend, Backend container example) is sufficient to deploy behind nginx configured for TLS/SSL.
Specifically, I see that the Frontend section of the Plone 6 dev docs has its own Deploying section, including Simple deployment – Frontend – Deploying which has suggestions about nginx TLS configuration, but I can’t tell how to implement those suggestions.
I have an nginx + TLS/SSL configuration working with static content
When I try to access the frontend behind nginx TLS I am blocked by CORS mixed content restrictions. In the browser console:
Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '<URL>'. This request has been blocked; the content must be served over HTTPS
I don't think that addresses the problem. I believe the CORS mixed content error is due to javascript requests on the https page that the browser received trying to reach non-https ports, specifically 8080. Here's one of the links that are failing, as revealed by the browser dev-tools network report:
Changing the rewrite rule you mentioned doesn't help with that – I still get the request for 8080 on the resulting page.
I guess what I need to find out is how to change the address that the frontend requests are making use a particular path rather than a port, and then translate that path (with the rewrite rule) to reach out to the port.
Looking through the plone/plone-frontend list of configuration variables, it looks like the RAZZLE_INTERNAL_API_PATH environment variable is the one I want.
Yes! After rebuilding the containers with RAZZLE_INTERNAL_API_PATH set to a path like http://backend/something_distinct/... I no longer get the mixed content error! I think I found what I'm looking for. Now I will need to adjust the rewrite rule to unmangle that and proxy_pass the request to the backend.
I'll look at the references you sent to see if they provide insights about doing that. Thanks for taking the time to help!
[In a subsequent message I posted a new version of the configuration described in this message that solves the problem described here.]
Ok! I’ve got a Plone 6.0.0rc1 site fully operational behind https/TLS, though there’s one minor glitch left with which I could use help. I’m including below a variation of the configuration I’m using, based on the nginx, Frontend, Backend container example, because others might find it useful (I would have!), plus it will make it easy for those in the know to guide me in addressing the remaining problem.
The problem is a momentary “Connection Refused” message in the content area of pages when I visit them using an external link. By “momentary” I mean that the proper content replaces the “Connection Refused” message almost immediately after that message is displayed. This does not otherwise occur, eg when navigating from page to page using links on the site.
I expect this is related to Volto’s two-stage page loading process. Unfortunately, I am not clear about the specifics of that process nor found a concise explanation and haven’t made any headway trying debug my configuration. I suspect that someone familiar with the process will quickly recognize the cause. If you do, I would appreciate it very much if you would steer me in the right direction!
Here’s my setup. It’s directly derived from nginx, Frontend, Backend container example, with the addition of LetsEncrypt certs established in the host file system and brought to the docker-composed nginx instance using data volumes. I also use data volumes for the backend storage for easy external access, for persistence and migration.
Here’s my adapted docker-compose.yml file. The crucial difference is the setting for RAZZLE_INTERNAL_API_PATH. I suspect that the problem I mention above is because I haven’t got this setting quite right, but as I said everything else does work. (I also changed the backend version to Plone 6.0.0rc1. Docker compose makes it extremely easy to update stuff!)
I’m using data volumes to share the LetsEncrypt installed and updated certs with the containerized nginx install. I will need to tweak the LetsEncrypt renewed-cert procedure to restart that containerized nginx install, using something like cd dockercompose-dir && docker compose restart webserver.
During initial docker composition of the “Plone Volto site: Plone” a banner message includes “THIS IS NOT MEANT TO BE USED IN PRODUCTION”. I would like to know more about why that is, and whether I should rethink basing my site’s install on all this. The page referenced with a link includes this warning: We advise against using this feature on production environments., (in reference to a docker run command), but isn’t particularly illuminating.
The "connection refused" message is from the Server Side Rendering. The problem is like this:
Volto nodejs server wants to generate an HTML for your browser to load. It tries to connect to Plone and fetch the content, so that the generated HTML is already showing you the proper content.
Now your browser will load the generated HTML and then execute the Javascript that is Volto running in your browser. That Javascript will connect to the Plone backend and it will load and redisplay the content. This process is called hydration.
So, what happens is that you briefly see the HTML produced by the server, then the client-side app loads. For some reason the server is unable to connect to the Plone backend.
Thanks for the explanation! Evidently RAZZLE_INTERNAL_API_PATH specifies how the frontend connects with the backend for that initial step that you describe. I looked back at the frontend docker run command on the Containers overview page and the value used there for RAZZLE_INTERNAL_API_PATH, http://backend:8080/Plone, was the solution. (Setting RAZZLE_API_PATH according to that comand breaks things, however.) My bare-bones Plone 6 installation, using the Volto frontend, is now fully operational behind TLS. Yay!!
I'm going to reiterate the configuration, with that setting corrected.
This configuration directly descends from nginx, Frontend, Backend container example, with the addition of LetsEncrypt certs established in the host file system and brought to the docker-composed nginx instance using data volumes. I also use data volumes for the backend storage for easy external access, for persistence and migration.
Note that the configuration depends on backend and frontend being defined as the host where the backend and frontend ports are established. I set them in my hosts file, so the localhost line in my /etc/hosts file looks like: 127.0.0.1 localhost backend frontend
I’m using data volumes to share the LetsEncrypt installed and updated certs with the containerized nginx install. I will need to tweak the LetsEncrypt renewed-cert procedure to restart that containerized nginx install, using something like cd dockercompose-dir && docker compose restart webserver.
During initial docker composition of the “Plone Volto site: Plone” a banner message includes “THIS IS NOT MEANT TO BE USED IN PRODUCTION”. I would like to know more about why that is, and whether I should rethink basing my site’s install on all this. The page referenced with a link includes this warning: We advise against using this feature on production environments., (in reference to a docker run command), but isn’t particularly illuminating.