Deploy Blicca example#

This guide shows you how to deploy the Blicca example to your Kubernetes cluster.

Blicca is the new name for what Plone formerly called “Classic UI”.

What you’ll deploy#

The Blicca example provides Plone with server-side rendering:

  • Plone 6.1 Blicca (backend renders the UI, no separate frontend)

  • PostgreSQL with RelStorage (plain PostgreSQL or CloudNativePG)

  • Varnish HTTP caching with kube-httpcache

  • Ingress with TLS (Traefik or Kong)

  • Simpler architecture (single backend service)

Blicca vs Volto#

Feature

Blicca

Volto

Architecture

Single backend

Frontend + Backend

Rendering

Server-side

Client-side (React)

Deployment

Simpler

More complex

Best for

Single-service setups, migrations

API-first projects, SPA frontends

Tip

Choose Blicca if you want a single backend service without a separate frontend, or if you need Blicca-specific add-ons. For the React single-page frontend approach, consider Volto.

Prerequisites#

Same as the Prerequisites in the Volto guide, you need:

  • Ingress controller (Traefik or Kong)

  • cert-manager

  • kube-httpcache operator

  • PostgreSQL: plain single-instance (default, no operator) or the CloudNativePG operator

See Setup Prerequisites for detailed instructions.

Step 1: Get the example#

git clone https://github.com/bluedynamics/cdk8s-plone.git
cd cdk8s-plone/examples/blicca

Step 2: Install dependencies#

npm install

Step 3: Import CRDs#

npm run import

Step 4: Configure environment#

Create .env from the example:

cp .env.example .env

Edit .env:

# Your domains
DOMAIN_CACHED=plone.example.com
DOMAIN_UNCACHED=plone-test.example.com
DOMAIN_MAINTENANCE=plone-admin.example.com

# Your cert-manager ClusterIssuer
CLUSTER_ISSUER=letsencrypt-prod

# Optional: Custom backend image
#PLONE_BACKEND_IMAGE=plone/plone-backend:6.1.3

# Database: 'plain' or 'cloudnativepg'
DATABASE=cloudnativepg

Note

Blicca only needs one image (backend). There’s no frontend image configuration.

Step 5: Generate manifests#

npm run synth

Creates dist/plone-blicca.k8s.yaml (~27 KB, smaller than Volto’s 32 KB).

Step 6: Review manifests#

# Count resources
grep "^kind:" dist/plone-blicca.k8s.yaml | sort | uniq -c

# Dry run
kubectl apply --dry-run=client -f dist/plone-blicca.k8s.yaml

Step 7: Deploy#

kubectl apply -f dist/plone-blicca.k8s.yaml

Or to a specific namespace:

kubectl apply -f dist/plone-blicca.k8s.yaml -n plone

Step 8: Monitor deployment#

# Watch pods
kubectl get pods -l app.kubernetes.io/part-of=plone -w

# Wait for ready
kubectl wait --for=condition=ready pod \
  -l app.kubernetes.io/part-of=plone \
  --timeout=300s

Note

Blicca deploys fewer pods than Volto (no frontend pods).

Step 9: Verify services#

kubectl get svc -l app.kubernetes.io/part-of=plone

You should see:

  • plone-backend (Blicca service)

  • plone-httpcache (Varnish cache)

  • Database service

Step 10: Check ingress#

kubectl get ingress
kubectl get certificate

Step 11: Access your site#

Once DNS and TLS are ready:

  • Public (cached): https://plone.example.com

  • Testing (uncached): https://plone-test.example.com

  • Maintenance: https://plone-admin.example.com

Create Plone site#

  1. Access maintenance domain: https://plone-admin.example.com

  2. Click “Create a new Plone site”

  3. Configure:

    • Site ID: Plone

    • Title: Your site name

    • Language: Select language

    • Add-ons: Choose Blicca add-ons

  4. Click “Create Plone Site”

Key differences from Volto#

Architecture#

Blicca routing is simpler - all traffic goes to the backend:

Traffic → Ingress → Varnish → Plone Backend (Blicca)

Compared to Volto:

Traffic → Ingress → {Varnish → Frontend, Backend}

Ingress routes#

Blicca uses virtual host rewriting for direct backend access:

  • Cached: Routes through Varnish to backend

  • Uncached: Direct to backend with VirtualHostBase rewrite

  • Maintenance: Direct backend access with VirtualHostRoot

No frontend service#

The manifest doesn’t include:

  • Frontend deployment

  • Frontend service

  • Frontend-to-backend internal routing

This makes the deployment ~15% smaller and simpler to manage.

Troubleshooting#

Backend not starting#

Check backend logs:

kubectl logs -l app.kubernetes.io/name=plone-backend -f

Common issues:

  • Database connection failures

  • Memory limits too low

  • Image pull errors

Blicca interface not loading#

  1. Check if backend pods are running:

    kubectl get pods -l app.kubernetes.io/name=plone-backend
    
  2. Verify virtual host rewriting in ingress:

    kubectl describe ingress
    
  3. Check Varnish routing:

    kubectl logs -l app.kubernetes.io/name=plone-httpcache
    

Add-on compatibility#

Some add-ons are Volto-specific. For Blicca:

  • Use Blicca themes (not Volto themes)

  • Check add-on compatibility with Plone 6 Blicca

  • Avoid Volto-specific frontend add-ons

Migrating to Volto#

If you want to migrate from Blicca to Volto later:

  1. Keep your backend deployment (same configuration)

  2. Add Volto frontend from the Volto example

  3. Update ingress to route to frontend

  4. Both UIs can run simultaneously during migration

See the Volto deployment guide for details.

Customization#

Backend configuration#

Edit main.ts to customize:

const plone = new Plone(this, 'plone', {
  variant: PloneVariant.BLICCA,
  backend: {
    image: 'plone/plone-backend:6.1.3',
    replicas: 2,
    limitMemory: '1Gi',
    limitCpu: '1000m',
    environment: env,
  },
})

Varnish caching#

Edit config/varnish.tpl.vcl for caching rules specific to Blicca.

Blicca VCL is simpler than Volto’s - all traffic routes to one backend.

Scaling#

Scale backend replicas:

backend: {
  replicas: 3,  // Increase for higher traffic
}

Then:

npm run synth
kubectl apply -f dist/plone-blicca.k8s.yaml

Performance#

Blicca performance characteristics:

  • Server-side rendering moves rendering work to the backend, so Varnish caching matters

  • Varnish caching is critical for performance

  • Database is the main bottleneck (use CloudNativePG for HA)

  • Fewer HTTP requests than Volto (no separate frontend API calls)

Cleanup#

kubectl delete -f dist/plone-blicca.k8s.yaml

Next steps#

See also#