This is a standard Plone-buildout of the company
Latest commit fdf82ee Jul 17, 2018


The Starzel Buildout

This is a standard Plone-buildout of the company

Main features

  • It extends to config- and version-files on github shared by all projects that use the same version of Plone.
  • It allows to update a project simply by changing the version it extends.
  • It allows to update all projects of one version by changing remote files (very useful for HotFixes).
  • It is minimal work to setup a new project.
  • It has presets for development, testing, staging and production.
  • It has all the nice development-helpers we use.


This contains the project settings (name, addons, checkouts etc.).

For each environment (development, production, test) there is a separate local_*.cfg-file. You create a symlink called local.cfg to one of these files depending on your environment. Each of the files includes the remote base.cfg that is hosted on github like this:

extends =

This example refers to the tag 5.1 of this buildout that uses Plone 5.1 To use a different Plone-version simply change that to point to a different tag.


This remote file conatains most of the commonly used logic used for prodcution. It also includes two version-files that are also hosted on github:

Here you pinn versions to overwrite or extend the hosted pinned_versions.cfg. These eggs are usually pinned for a reason and are usually not safe to be upgraded.
Here you overwrite and extend the hosted floating_versions.cfg. These eggs should usually be safe to be upgraded. ./bin/checkversions floating_versions_project.cfg will check pypi if there are newer releases for your pinned eggs.


We support the following version of Plone:

To use this buildout with a version of Plone that is currently in development (a.k.a. the Coredev) please use:

Please note that new features are not introduced to old versions.

Tags for development-versions (alpha, beta and rc) will exists but will be removed after the final release of that version.


$ git clone SOME_PROJECT

Remove all files that are not needed for a project but are only used for the buildout itself.

$ rm -rf linkto README.rst README.txt .travis.yml secret.cfg_tmpl VERSION.txt local_coredev.cfg CHANGES.rst

If you're not developing the buildout itself you want a create a new git repo.

$ rm -rf .git && git init

Add a file that contains a passwort. Do not use admin as a password in production!

$ echo -e "[buildout]\nlogin = admin\npassword = admin" > secret.cfg

Symlink to the file that best fits you local environment. At first that is usually development. Later you can use production or test. This buildout only uses local.cfg and ignores all local_*.cfg.

$ ln -s local_develop.cfg local.cfg

Build Plone

$ virtualenv-2.7 .
$ ./bin/pip install -r requirements.txt
$ ./bin/buildout

Configuring a project

buildout.cfg contains the general project settings. Here you configure the name of the project, the eggs, source-checkouts and languages Plone will use.

Use in development

Symlink to the development-config:

$ ln -s local_develop.cfg local.cfg

The development-setup will build a simple instance with some useful tools (see below). The setup assumes that zeo, varnish and loadbalancing are only configured on production.

Use in production

Symlink to the production-config:

$ ln -s local_production.cfg local.cfg

A average project could use this stack pipeline:

nginx > varnish > nginx (for load-balancing) > at least 2 zeoclients > zeoserver

In local_production.cfg select the parts you really need.

parts +=

Also modify templates/supervisord.conf to have supervisor manage the parts you want to use.

Server stack

Frontend webserver (Nginx)

The first Nginx manages the virtualhost, does url rewrites if needed and terminates the SSL (needs to be done before varnish).

A full demo-config with ssl and redirects can be found in this repo in /templates/demo_nginx.conf.

A minimal config without ssl can be found in the project.

More information can also be found in the PloneDocs

Cache (Varnish)

After nginx we use varnish to cache the site. You can activate it like this:

# comment out what you need
parts += # Choose one!

Take a look in linkto/base.cfg for the varnish4-config part, there are several switches to configure.

It is best practice to install varnish from your distribution repository. If this is not possible you can build it, see the section below.

If you use the system-varnish only need the [varnish4-config] part, it will generate the config (vcl) for you. In /etc/varnish/default.vcl include the generated vcl:

vcl 4.0;

include "<path to your buildout>/etc/varnish4.vcl";

A systemctl restart varnish should activate the new config. To use one varnish installation with serveral vhosts, see the Varnish with multiple sites section below.

Loadbalancer (Nginx)

Another Nginx spreads the requests to several Zeoclients, here is a minimal config. In production you can look at the project

# starzel (zeoclients)
upstream starzel_zeoclients {

The ip_hash option is needed for multiple Zeoclients, more information can be found in this issue

The ip and port has to be the same as the settings for the zeoclients in then part [bindips] and [ports].

Varnish with multiple sites

The generated varnish config works with a single vhost, for multiple sites/domains we need a custom varnish config. This configuration is not yet build into the buildout script/template, we need to do the changes manually in a copy of a varnish config file (just copy the varnis4.vcl over to /etc/varnish and include it in default.vcl).

In the varnish4.vcl we need to add the additional backend, note the different loadbalancer port.

backend 001 {
   .host = "localhost";
   .port = "8091";
   .connect_timeout = 0.4s;
   .first_byte_timeout = 300s;
   .between_bytes_timeout  = 60s;

backend 002 {
   .host = "localhost";
   .port = "8081";
   .connect_timeout = 0.4s;
   .first_byte_timeout = 300s;
   .between_bytes_timeout  = 60s;

In sub vcl_recv we remove the backend (set req.backend_hint = backend_000;) and add this switch:

if ( == "my_host") {
    set req.backend_hint = 001;
else {
    set req.backend_hint = 002;

This does the vhost routing to the different backends. "my_host" is the upstream name of the cache, see the config of project. The Varnish config can be tested with this command: varnishd -C -f /etc/varnish/default.vcl

Build varnish

If you need to build varnish (e.g. because your system does not ship with version 4), you need to add varnish-build:

# comment out what you need
parts +=

recipe = plone.recipe.varnish:build
url =
varnish_version = 4.0

The varnish4 part generates a start script, this can be used together with supervisord.

Use for test-instances

Create a copy of local_production.cfg called local_test.cfg and modify it according to your needs.


If test runs on the same server as production:

In this case you need a different name for the project on test. Otherwise one will overwrite the database of the other. Because of this the name of the project must not be set in buildout.cfg but in the local_*.cfg-files.


Debugging and Development

All eggs of your buildout will be symlinked to in parts/packages.
Run ./bin/zopepy to have a python-prompt with all eggs of your buildout in its python-path.
Run ./bin/checkversions floating_versions_project.cfg to check if your pinned eggs are up-to-date.
This part uses to prepare for codeintel-integration (useful for users of Sublime Text).
The part stacktrace-script adds a bash-script ./bin/ that will print the current stacktrace to stdout. Useful to find out what Plone is doing when it's busy.
This installs a pre-commit-hook that runs the codeanalysis-tests from plone.recipe.codeanalysis.
This part adds bobtemplates.plone to simplify the creation of new addons.
Run tests for your test-eggs
Generate coverage-reports for your test-eggs in parts/test/.


Restrict loaded languages
By default only german ('de') is loaded on startup. In your buildout.cfg you can override the loaded languages using language = de en fr. This setting also affects the languages used in the i18nize-xxx part. (see
Show differences of the po files against what is currently in git. This script uses podiff that filters out a lot of noise like creation dates and line numbers. So this output is much more usable. Use this script in jenkins together with i18nize-all to make sure that you po files are up to date.

Modify the commented-out part i18nize-xxx to get a script that runs i18ndude fro an egg. Here is an example for the egg adding a script ./bin/i18nize-site.

recipe = collective.recipe.template
input = ${buildout:directory}/
output = ${buildout:bin-directory}/i18nize-site
mode = 775
dollar = $
domain =
packagepath = ${buildout:directory}/src/
languages = ${buildout:languages}
This runs all i18nize commands for a package.


Setup for gitlab-ci and jenkins
Configure your ci-system to run the script ./ This will configure and run the whole buildout.


Change the settings for maxram to have memmon restart an instance when it uses up to much memory.
Sentry logging
Configure zeoclients to send tracebacks to Sentry in local_production.cfg by uncommenting it and adding a dsn. You also need to enable the egg raven. Repeat for each zeoclient.


This buildout automatically includes the correct Hotfixes for the version of Plone you use. E.g. the extends-file for Plone 5.0.6 pulls in the file which in turn contains the pinns and eggs for all HotFixes for that version.

By having the hotfixes-files in the master-branch we can easily update Hotfixes for each version without having to move any tags. The same day a Hotfix is published the corresponding extends-files will be updated. You simply have to rerun buildout and restart your site to include them.


local.cfg and secret.cfg must never be versioned. The file .gitignore in this buildout already prevent this.

It might feels weird that buildout.cfg loads local.cfg, but this avoids some weird behavior of buildouts extends-feature.

To have different supervisor-configurations for test-servers by adding a file templates/supervisord-test.conf and referencing it in local_test.cfg:

    input= ${buildout:directory}/templates/supervisord-test.conf