I ventured through a long and elaborate path to get to the point where I can build and maintain a Volto-based site with addons and customizations, all accessible via https/TLS. I've made many missteps and found myself in many dead-ends along the way. I do not think I could have avoided some of them, but do not mean that as an indictment of the guidance I found. I started when Plone 6 was just still a beta release and Volto was (and is) still taking shape, so it makes sense that there is not yet a “garden path” to follow. There's such great potential in Plone 6 + Volto that I found it worth the effort to find my way. I’m hoping that by describing what I discovered I can make it easier for others to use the system, so more of us can enjoy and contribute to the system's growth.
-
Using the containers method for a vanilla build running behind a reverse proxy for remote access
The first introduction on the website to running Plone 6 is Containers – Install in the Plone 6 documentation. It provides a simple recipe to use Docker to start the Plone 6 backend and Volto frontend so they can work together and give you a chance to try the system for yourself. I was delighted with how easy it was to do that, and happy to start to get acquainted with using containers via Docker. Operation based on containers quickly became part of my requirements.
Trying it I noticed that I could access my Plone trial site with a browser local to the servers, but not when accessing it remotely. In the process of shaking this problem I learned a lot about how the frontend and backend cooperate. This was also key to my forward progress.
I posted about my efforts, and the thread spells out the details:
@tiberiuichim's suggestion resolved an obstacle so I could start the Volto frontend such that it could be accessed from a remote host. I described how I set things up in this thread followup. (I describe a more useful configuration in the next steps.)
I submitted a documentation issue describing the problem that Tiberiu’s suggestion solved:
-
Implementing TLS in the reverse proxy so I can access my sites via
https
TLS is an inevitable requirement for most of the sites I might build. Looking for instructions led me to the nginx, Frontend, Backend container example – Install – Containers – Examples of Plone 6 using containers documentation.
Arranging to get proper TLS certificates using LetsEncrypt. I then had to resolve involved issues with Cross-Origin Resource Sharing (CORS) restrictions.
For reliable security browser CORS restrictions require that resources like scripts embedded in a page are from the same address as the page itself. “Same address” includes the same port: to respect CORS security the browser can’t allow https pages to run scripts from the same host but a different, non-https port, like requests to the Plone backend server typically on 8080, or the Volto frontend server on port 3000. Yet Volto is designed to embed such requests in pages.
The solution is to encode references to frontend and backend URLs as regular https URLs to the server host and use rewrites in the proxy server (nginx) to detect them and direct the requests to the intended server. Having the redirection happen in the proxy server circumvents the browser’s CORS restrictions without betraying security concerns: the provision is for the specific ports in our services and server - an explicit agreement with ourselves.
Here’s the relevant nginx configuration for requests to the backend:
location ~ /\\+\\+api\\+\\+($|/.*) { rewrite ^/(\\+\\+api\\+\\+\\/?)+($|/.*) /VirtualHostBase/https/$server_name/Plone/++api++/VirtualHostRoot/$2 break; proxy_pass <http://backend>; }
In this community posting I asked for help with the CORS problems:
@sneridagh's suggestions in comment 2 led me to consider how to express the backend and frontend links so that they went to the same host and port as the page (https://host) but the actual frontend or backend port could be discerned by the proxy service, which would use what it detected to direct the request accordingly. This got it mostly working: Comment 3 in that thread
There was one small glitch remaining in this TLS connection. Pages would momentarily contain a “Connection Refused” message when they initially showed, almost immediately replaced by the content. I describe the mostly working configuration and the glitch in comment 4. In comment 5 @tiberiuichim once more resolves things, again clarifying the frontend / backend cooperation sequence. That led me to focus on the
RAZZLE_INTERNAL_API_PATH
setting, and arrive at a fully working configuration, which I lay out fully in comment 6.So now I’m able to interact with my trial Plone 6 installation through Volto behind TLS from a remote browser. Along the way I got familiar with using
docker compose
to coordinate operation of the service containers (proxy, backend, frontend). I’m totally sold on Docker anddocker compose
- they make orchestrate operation of the system components as easy as I can image. The results of all the subsequent steps will be run using this operational framework. -
Using the packages method to build a Volto container image that includes addons of your choosing
As far as I can tell, the GitHub - plone/plone-frontend: Plone frontend Docker images using Node 16. image doesn’t provide a way to specify optional addons from the command line. To include addons we need to build them into a Volto image from packages using cookiecutter: Install Plone from its packages. We can then use that image in the
docker compose
configuration described in step #2.The resulting packages build setup is elaborate.
make help
tells you the available commands. You can include addons in the frontend and backend builds, using their respective subdirectories.While working on this I encountered a Dockerfile syntax error in the
'make build-images
step that has not been fixed as of this writing:The syntax evidently works with
docker buildx
commands but notdocker build
. The fix is to change the Makefile to use the rightdocker buildx
commands (which I didn’t investigate) or to use the Dockerfile syntax which works with the generaldocker build
command. I submitted a pull request for the latter, which is easy for you to use if you need it:When including addons in the frontend you need to be sure to do a
yarn add ...
in thefrontend
subdirectory for each one. That will establish the current addon version as the one that will be used in subsequent builds. When you want to increment to a more recent version of an addon you can do anotheryarn add ...
for that addon. (I don’t know whether doing an unqualifiedyarn add
will update the entries for all your included addons, and would be interested to hear whether or not that is the case.)You can plug the images you build into the
docker-compose.yml
configuration arrived at in step #2 above. After building an image usedocker images
to see the name of the new image, and don’t forget to usedocker image prune
to dispose of intermediate container images produced in the image building process. (If you abort the build process you may need to first remove the residual containers. Look for two-word container names in thedocker container ls
(ordocker ps -a
) listing.)You can now run the system per step 2 with backend and frontend images including addons that you choose.
There is one step further that I needed to learn to be able to fully customize my Volto installation.
-
Using an addons development build to develop a customizations package or other addon.
I did not find a way to incorporate custom Volto code source directly in the packages method described in step #3. (I tried using GitHub repositories as addons but encountered several problems using
yarn
to add GitHub repositories as addons. Some were trivial, but some were clearly not. It’s evident that people are not including addons directly from GitHub repositories or these problems would be shaken out. In any case, the addons development approach I’m about to relate is logistically better overall.)Plone 2022 training documentation includes Volto add-ons development documentation. (This is distinct from the Plone 6 documentation Volto Addons section, which did not lead me anywhere useful.) It guides you through using the
yeoman
GitHub - plone/generator-volto: Volto App Yeoman Generator (@plone/generator-volto
) Volto project generator and@plone/volto
Volto addon generator to establish a Volto frontend project that you can run from source. You can then add your addon and other sources to the project and run them directly from it.To use project framework with the
docker compose
orchestration:- In the directory where you established the
docker-compose.yml
file from step #2- Use
docker compose start
to start the composite system - Then stop the frontend using
docker compose stop frontend
.
- Use
- Back in the generated Volto project directory use
yarn start
to start the project.
The
yarn
-started frontend will run on port 3000, which is where thedocker compose
started nginx proxy will pass frontend traffic. Theyarn
-started frontend will connect to thedocker compose
started backend on port 8080 (or whatever you configured).A very nice feature of this Volto project system is hot reloading of the sources. Any file changes detected in the
src
directory triggers reloads of the Volto code, updating the frontend with code changes you soon as you make as you make them.Once I’ve got an addon developed you can plug the result into the package build of step #3 by publishing the addon as an NPM package. (You can do so at will with a free NPM account. You have to pay for a subscription if you want to publish packages with access restrictions. I can then rebuild my images including the new modules.
Here’s a elementary addon I created which just configures some Volto settings:
@myriadicity/myr-frontend-config
. Visit the addon at npmjs.org to view the code.I should note that I found it necessary to publish the addons in an organization scope in order for
yarn add
in step #3 to work. I may be mistaken about that, but mention it for you to try if you find it’s not working otherwise. You also need to update the version numbers and republish the code in order for subsequentyarn add
s to get the new version. - In the directory where you established the
Wrap-up
I included a lot of the details that I learned and that I feel are essential to understanding what is going on. While hopefully all the details are useful, it helps to get perspective on what are essential three distinct activities:
- Operate the facilities as containers: The
docker compose
operation of the container images- The result of step #2 above.
- Build the facilities as container images: The means to change addons included in the frontend and backend images that are run
- Detailed in step #3.
- Develop and publish Volto addons for incorporation in the frontend image: The means to develop new addons and publish them for inclusion in the container images
- Detailed in step #4.
You can also build backend addons for incorporation in step #3, but that is covered extensively in classic Plone documentation.
I can’t guarantee that the way I’m doing all this is the intended way for the system to be used. Similarly, it may be that other ways of doing things will emerge and take over. But I know that these steps have enabled me to move forward with using Plone 6 + Volto, and I’m hoping that the info will help others do so, too. The more of us that can use and develop the system, the better it will move forward and grow.
Lastly:
- Thanks to everyone who answered my questions and provided guidance along the way, especially @tiberiuichim. It makes a huge difference to know that questions will be addressed when trying to use an elaborate system!
- I welcome suggestions and corrections! I would like to make it as useful as possible. It may be that there are better ways to do what I described, and I would like to learn what those are, as well.