Plone 6 Docker: pip only vs. buildout

We have to upgrade a Plone project from Plone version 5.2 to version 6. We have to use Classic UI in Plone 6 and have to run the project using Docker.

In Plone 5 Docker is based on buildout, in Plone 6 Docker is based on pip: GitHub - plone/plone-backend: Plone backend Docker images using Python 3 and pip..

I am aware of the installation methods (Buildout, pip etc):

I am aware of the differences between pip and Buildout:

I am aware of the note:
"There is a big change for Plone 6 under the covers: Plone no longer uses the venerated (or, on occasion, the cursed) buildout tool ... Plone is now installed using Python’s standard pip tool, the package installer for Python, which provides a consistent installation of Plone’s dependencies every time it is run." (Step-by-step: Using Docker to Set Up Plone 6).

My question is:
Does the fact that there is no Plone 6 Docker buildout version mean that installing via pip is the recommended way?
Or are there plans to provide a Plone 6 Docker buildout version?

To put it another way:
It's not about Docker, but about the specific project requirements, which could lead to either pip or Buildout and thus to a custom Buildout based Docker?

Thank you!

If you've docker, install using docker. If you mean addons, you have to build your own image with the addons. The dockerfile can be:

# syntax=docker/dockerfile:1
ARG PYTHON_VERSION=3.11
ARG PLONE_VERSION
FROM plone/server-builder:${PLONE_VERSION} as builder

# Remove Volto support from builder image
RUN /app/bin/pip uninstall -y plone.volto

# install our addons
# TODO compact the commands
RUN /app/bin/pip install addon1 addon2 addon3
# add a local src module to test it
RUN mkdir -p /app/src/mymodule/
COPY mymodule/ /app/src/mymodule/
RUN /app/bin/pip install -e /app/src/mymodule
FROM plone/server-prod-config:${PLONE_VERSION}

LABEL maintainer="Plone Community <dev@plone.org>" \
      org.label-schema.name="plone-classicui" \
      org.label-schema.description="Plone $PLONE_VERSION Classic UI image using Python $PYTHON_VERSION" \
      org.label-schema.vendor="Plone Foundation"

# Use /app as the workdir
WORKDIR /app

# Copy /app from builder
COPY --from=builder --chown=500:500 /app /app

# Link /data (the exposed volume) into /app/var
RUN ln -s /data /app/var

# Setup default type for site creation to be classic
ENV TYPE=classic

and the compose (with varnish, use the vcl from plone.recipe.varnish):

version: "3"
services:

  webserver:
    image: nginx
    restart: unless-stopped
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - backend
    ports:
    - "80:80"

  backend:
    image: mydockerimage:latest
    command: bash
    tty: true
    restart: unless-stopped
#    volumes:
#      - ./src:/app/src
    environment:
      ZEO_ADDRESS: db:8100
#      DEVELOP: src/mymodule
#      ADDONS: mymodule
    ports:
    - "8080-8083:8080"
    depends_on:
      - db

  db:
    image: plone/plone-zeo:latest
    restart: always
    volumes:
      - data:/data
    ports:
    - "8100:8100"

  varnishs:
    image: varnish:stable
    restart: always
    volumes:
      - ./varnish/varnish.vcl:/etc/varnish/default.vcl:ro
    tmpfs: /var/lib/varnish/varnishd:exec
    ports:
      - 8090:80
    environment:
      - VARNISH_SIZE:VARNISH_SIZE=2G
    container_name: varnishs
    depends_on:
      - backend

volumes:
  data: {}

and the nginx:

upstream backend {
  server varnishs:80;
}

server {
  listen 80  default_server;
  server_name  plone.localhost;
  client_max_body_size 30M;

  location ~ / {
      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;
      if (!-f $request_filename) {
        rewrite ^/(.*)$ /VirtualHostBase/http/plone.localhost:80/Plone/VirtualHostRoot/$1 break;
        proxy_pass http://backend;
      }
  }

}

Above, the dockerfile is using pip to install addons in the docker image.

Thank you!
In your example you are going with pip based installation. Do you see reasons to go with buildout as in Docker Plone 5.2?

consider that using uv instead of pip will lower image creation time to few seconds.

I would use buildout (or cookieplone) for local development and pip/uv to build the docker images.

$ du -hs .
88K	.
$ time uv pip install Plone 
Resolved 243 packages in 2.16s
Downloaded 172 packages in 3.55s
Installed 243 packages in 336ms
[...]
real	0m6,210s
user	0m3,444s
sys	0m3,197s

$ du -hs .
288M	.

6 seconds.

Ok, i see, development environment using buildout/cookieplone and deployment/productive environment using pip/uv based Docker - and thank you for bringing up uv

@maha If you would like an example of a Plone 6.1 ClassicUI setup with docker, you can check the repo where we generate and deploy the classic.demo.plone.org website. It is in the classic subdirectory:

1 Like

@fredvd Thank you! Also in this example Docker is based on pip and not on buildout. I have never seen any example of Plone 6 Docker based on buildout. Do you see any reasons/advantages to run Plone 6 (with Classic UI) using Docker based on buildout? In particular in production environments?

From https://6.docs.plone.org/conceptual-guides/compare-buildout-pip.html:

Buildout

  • May have problems resolving dependencies when a new pip or setuptools version is released.

That said, no install method handled Plone's use of the deprecated pkg_resources module well, but it serves as an example of how fun it is to resolve. See PLIP Replace pkg_resources in normal code · Issue #4126 · plone/Products.CMFPlone · GitHub for the current status.

There will be no official Plone 6 containers using buildout.

The community is trying to move from buildout to python-wide solutions like pip (and perhaps now uv), so do not expect any official buildout-based-docker-containers for Plone 6.

If you want to keep working with Buildout and Docker, you will have to build the base containers or the project containers yourself.

Having said that, Plone 6 still works with buildout, we have several Plone 6 based installations using buildout. The configuration is the same as we are using for Plone 6, just exchange the corresponding versions file to point to the Plone 6 one.

But for the new Plone 6 deployments using docker, we have been using projects generated using cookieplone.

And not only for Volto projects, also for Classic projects: just ignore (or delete!) everything under the frontend folder.

@erral Thanks for the clarification, very helpfull!

For Classic-UI projects, an update to cookieplone is being worked on that generates a correct layout where the volto frontend part is not generated. Similar options for different deployment targets are in development. Then you don’t need to delete/remove those unneeded parts.