Configuration guide#

This guide shows the most common ways to configure cdk8s-plone, grouped by task, with copy-pasteable examples.

Important

For the complete and authoritative list of every construct, option, type, default value, and whether it is required, see the API reference. That reference is generated from the TypeScript source, so it never drifts. This guide is hand-written orientation and deliberately does not repeat the full option tables.

Constructs at a glance#

Plone

Deploys the Plone backend and, for the Volto variant, the React frontend, plus their services and (optionally) a PodDisruptionBudget and ServiceMonitor. This is the entry point.

PloneHttpcache

Adds a Varnish caching layer through the mittwald kube-httpcache Helm chart. Self-contained: it needs no operator in the cluster.

PloneVinylCache

Adds a Varnish caching layer through the cloud-vinyl operator. Requires the operator to be installed in the cluster.

To choose between the two cache constructs, read Architecture overview.

Choose a frontend variant#

The Plone construct deploys one of two frontends, selected with variant:

import { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';

// Volto: React single-page frontend talking to the REST API backend (default).
new Plone(chart, 'plone', {
  variant: PloneVariant.VOLTO,
  backend: {},
  frontend: {},
});

// Blicca: the backend renders the UI server-side, so there is no separate frontend.
new Plone(chart, 'plone', {
  variant: PloneVariant.BLICCA,
  backend: {},
});

Note

PloneVariant.CLASSICUI is a deprecated alias for PloneVariant.BLICCA, kept for backward compatibility. It keeps its legacy value ('classicui'), so existing configuration keeps working unchanged. The alias will be removed in a future major release.

For the conceptual difference between the variants, see Deployment variants.

Configure the backend and frontend#

Both backend and frontend take the same options (PloneBaseOptions). The examples below cover the common groups. See the API reference for every field, its type, and its default.

Images and replicas#

backend: {
  image: 'plone/plone-backend:6.1.3',
  replicas: 3,
  imagePullPolicy: 'Always',
}

Resource requests and limits#

backend: {
  requestCpu: '500m',
  limitCpu: '2',
  requestMemory: '512Mi',
  limitMemory: '2Gi',
}

High availability#

A PodDisruptionBudget is created automatically when replicas is 2 or more, or when you set minAvailable or maxUnavailable explicitly. Both accept an absolute number or a percentage string such as "50%".

backend: {
  replicas: 5,
  minAvailable: 3, // keep at least 3 pods available during voluntary disruptions
}

Probes#

Readiness probes are enabled by default; liveness probes are disabled by default.

frontend: {
  readinessEnabled: true,
  readinessInitialDelaySeconds: 10,
  livenessEnabled: true, // opt in; useful for the frontend
  livenessInitialDelaySeconds: 30,
}

Service#

Configure the generated Kubernetes Service through the grouped service option. Curated fields cover the common cases; service.overrides is an escape hatch for any other ServiceSpec field and has the highest precedence.

backend: {
  service: {
    type: 'LoadBalancer',
    trafficDistribution: 'PreferClose',
    loadBalancerSourceRanges: ['10.0.0.0/8'],
    annotations: {
      'external-dns.alpha.kubernetes.io/hostname': 'backend.example.com',
    },
    overrides: {
      ipFamilyPolicy: 'PreferDualStack',
    },
  },
}

Note

The top-level serviceAnnotations option is deprecated. Use service.annotations instead.

Environment variables#

Pass environment variables with the cdk8s-plus Env API, including values sourced from a Secret.

import { Env } from 'cdk8s-plus-30';

backend: {
  environment: {
    variables: {
      RELSTORAGE_DSN: Env.fromSecret(dbSecret, 'dsn'),
    },
  },
}

Annotations, scheduling, security, and monitoring#

These groups each have a dedicated how-to guide:

Add a cache#

import { PloneHttpcache } from '@bluedynamics/cdk8s-plone';

// Self-contained Varnish via the kube-httpcache Helm chart.
new PloneHttpcache(chart, 'cache', {
  plone: ploneInstance,
  existingSecret: 'varnish-secret',
  replicas: 2,
});
import { PloneVinylCache } from '@bluedynamics/cdk8s-plone';

// Operator-managed Varnish via the cloud-vinyl operator.
const cache = new PloneVinylCache(chart, 'cache', {
  plone: ploneInstance,
  storage: [{ name: 's0', type: 'malloc', size: '1500M' }],
  monitoring: true,
});

Important

PloneVinylCache without an explicit storage entry runs varnishd with its stock default (~100 MB malloc) regardless of the container memory limit. Size malloc storage below the pod’s memory limit to leave headroom for varnishd overhead.

For the full walk-through, including custom VCL snippets and shard-director tuning, see Deploy with cloud-vinyl cache.

Complete example#

import { App, Chart } from 'cdk8s';
import { Plone, PloneVariant, PloneHttpcache } from '@bluedynamics/cdk8s-plone';
import { Env } from 'cdk8s-plus-30';

const app = new App();
const chart = new Chart(app, 'PloneDeployment');

const plone = new Plone(chart, 'my-plone', {
  siteId: 'MySite',
  variant: PloneVariant.VOLTO,
  imagePullSecrets: ['registry-secret'],
  backend: {
    image: 'plone/plone-backend:6.1.3',
    replicas: 3,
    requestCpu: '500m',
    limitCpu: '2',
    requestMemory: '512Mi',
    limitMemory: '2Gi',
    minAvailable: 2,
    environment: {
      variables: {
        SITE: Env.value('MySite'),
      },
    },
  },
  frontend: {
    image: 'plone/plone-frontend:16.0.0',
    replicas: 2,
    livenessEnabled: true,
  },
});

new PloneHttpcache(chart, 'cache', {
  plone: plone,
  existingSecret: 'varnish-secret',
  replicas: 2,
  servicemonitor: true,
});

app.synth();

See also#