@bluedynamics/cdk8s-plone 0.1.40 → 0.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +294 -28
- package/API.md +225 -10
- package/CLAUDE.md +1 -1
- package/README.md +4 -4
- package/docs/superpowers/plans/2026-06-12-configurable-service-spec.md +608 -0
- package/docs/superpowers/specs/2026-06-12-configurable-service-spec-design.md +192 -0
- package/documentation/sources/explanation/architecture.md +7 -6
- package/documentation/sources/explanation/features.md +9 -7
- package/documentation/sources/how-to/{deploy-classic-ui.md → deploy-blicca.md} +43 -39
- package/documentation/sources/how-to/deploy-production-volto.md +1 -1
- package/documentation/sources/how-to/index.md +1 -1
- package/documentation/sources/reference/api/index.md +1 -1
- package/documentation/sources/reference/configuration-options.md +55 -11
- package/documentation/sources/tutorials/01-quick-start.md +1 -1
- package/examples/{classic-ui → blicca}/README.md +24 -25
- package/examples/{classic-ui → blicca}/__snapshots__/main.test.ts.snap +3 -3
- package/examples/{classic-ui → blicca}/config/varnish.tpl.vcl +1 -1
- package/examples/{classic-ui → blicca}/main.test.ts +3 -3
- package/examples/{classic-ui → blicca}/main.ts +6 -6
- package/examples/{classic-ui → blicca}/package.json +2 -2
- package/lib/httpcache.js +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -1
- package/lib/plone.d.ts +23 -5
- package/lib/plone.js +22 -8
- package/lib/service.d.ts +81 -0
- package/lib/service.js +24 -6
- package/lib/vinylcache.js +1 -1
- package/package.json +1 -1
- /package/examples/{classic-ui → blicca}/.env.example +0 -0
- /package/examples/{classic-ui → blicca}/cdk8s.yaml +0 -0
- /package/examples/{classic-ui → blicca}/ingress.ts +0 -0
- /package/examples/{classic-ui → blicca}/jest.config.js +0 -0
- /package/examples/{classic-ui → blicca}/postgres.bitnami.ts +0 -0
- /package/examples/{classic-ui → blicca}/postgres.cloudnativepg.ts +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Design: Generisch steuerbare Service-Resourcen
|
|
2
|
+
|
|
3
|
+
**Datum:** 2026-06-12
|
|
4
|
+
**Branch:** `feat/configurable-service-spec`
|
|
5
|
+
**Status:** Approved (Design)
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
Die von cdk8s-plone generierten Kubernetes-`Service`-Resourcen sind schlecht
|
|
10
|
+
steuerbar. Konkreter Anlass: Es soll `spec.trafficDistribution` gesetzt werden
|
|
11
|
+
können — das geht aktuell nicht. Generell ist die `Service`-Spec faktisch
|
|
12
|
+
hartcodiert: In [`src/service.ts`](../../../src/service.ts) baut `PloneService`
|
|
13
|
+
über das rohe `k8s.KubeService` nur `spec.ports` + `spec.selector`. Alle anderen
|
|
14
|
+
Felder (`type`, `sessionAffinity`, `externalTrafficPolicy`,
|
|
15
|
+
`internalTrafficPolicy`, `publishNotReadyAddresses`, `loadBalancerClass`,
|
|
16
|
+
`trafficDistribution`, …) sind nicht durchgereicht.
|
|
17
|
+
|
|
18
|
+
Zusätzlich ist das Plumbing nicht wartbar: Nach oben (in
|
|
19
|
+
[`src/plone.ts`](../../../src/plone.ts)) wird pro Feld einzeln geplumbt — aktuell
|
|
20
|
+
nur `serviceAnnotations`. Jedes neue Feld bräuchte Änderungen an mehreren Stellen.
|
|
21
|
+
|
|
22
|
+
## Ziel
|
|
23
|
+
|
|
24
|
+
Service-Spec-Felder konfigurierbar machen — möglichst generisch, mit wenig
|
|
25
|
+
Pflegeaufwand pro Feld, JSII-/Python-kompatibel, ohne Breaking Change.
|
|
26
|
+
|
|
27
|
+
## Designentscheidungen (bestätigt)
|
|
28
|
+
|
|
29
|
+
- **Hybrid-Ansatz:** Kuratierte typisierte Props für die häufigen Felder PLUS
|
|
30
|
+
ein generischer Escape-Hatch für alles Übrige.
|
|
31
|
+
- **Gruppiertes Plumbing:** Ein einziges `service`-Objekt in `PloneBaseOptions`
|
|
32
|
+
statt flacher Einzel-Props. Neue Felder ändern nur den Config-Typ.
|
|
33
|
+
- **`overrides`-Präzedenz:** `overrides` darf *alles* überschreiben (auch
|
|
34
|
+
`ports`/`selector`) — volle Kontrolle für Power-User, dokumentiert.
|
|
35
|
+
|
|
36
|
+
## Lösung
|
|
37
|
+
|
|
38
|
+
### 1. Neuer Config-Typ `PloneServiceSpec` (in `src/service.ts`)
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
export interface PloneServiceSpec {
|
|
42
|
+
// Kuratierte, häufig gebrauchte Felder (alle optional, typisiert, dokumentiert):
|
|
43
|
+
readonly type?: string; // ClusterIP | NodePort | LoadBalancer | ExternalName
|
|
44
|
+
readonly trafficDistribution?: string; // z.B. 'PreferClose'
|
|
45
|
+
readonly sessionAffinity?: string; // 'ClientIP' | 'None'
|
|
46
|
+
readonly externalTrafficPolicy?: string; // 'Cluster' | 'Local'
|
|
47
|
+
readonly internalTrafficPolicy?: string; // 'Cluster' | 'Local'
|
|
48
|
+
readonly publishNotReadyAddresses?: boolean;
|
|
49
|
+
readonly loadBalancerClass?: string;
|
|
50
|
+
readonly loadBalancerSourceRanges?: string[];
|
|
51
|
+
readonly annotations?: { [name: string]: string }; // ersetzt serviceAnnotations
|
|
52
|
+
readonly labels?: { [name: string]: string };
|
|
53
|
+
|
|
54
|
+
// Escape-Hatch für alles Übrige (ipFamilyPolicy, clusterIP, ...):
|
|
55
|
+
readonly overrides?: { [key: string]: any };
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Der `overrides`-Typ ist ein freiform-Record `{ [key: string]: any }` — deckt
|
|
60
|
+
jedes aktuelle und künftige k8s-Service-Feld ab, ohne dass Code angefasst werden
|
|
61
|
+
muss.
|
|
62
|
+
|
|
63
|
+
> **JSII-Constraint (entdeckt bei der Umsetzung):** Ursprünglich war
|
|
64
|
+
> `overrides?: k8s.ServiceSpec` geplant. JSII lehnt das ab
|
|
65
|
+
> (`JSII3000: Exported APIs cannot use un-exported type`), weil die generierten
|
|
66
|
+
> Typen aus `src/imports/k8s.ts` nicht Teil der JSII-Assembly sind. Den gesamten
|
|
67
|
+
> k8s-Import zu re-exportieren würde die öffentliche API mit der kompletten
|
|
68
|
+
> Kubernetes-API zumüllen. Ein freiform-Record ist die idiomatische, voll
|
|
69
|
+
> JSII-/Python-fähige (Python: `dict`) Lösung für einen generischen Escape-Hatch
|
|
70
|
+
> und bleibt „für alles" offen. Die kuratierten Felder bleiben typisiert.
|
|
71
|
+
|
|
72
|
+
### 2. `PloneServiceOptions` erweitern
|
|
73
|
+
|
|
74
|
+
`PloneServiceOptions` (das interne Interface von `PloneService`) bekommt ein
|
|
75
|
+
optionales `spec?: PloneServiceSpec`. Die bestehenden Pflichtfelder
|
|
76
|
+
(`targetPort`, `selectorLabel`, `portName`) bleiben unverändert. Das bestehende
|
|
77
|
+
`annotations` und `labels` auf `PloneServiceOptions` bleiben erhalten
|
|
78
|
+
(construct-managed Defaults), werden aber mit den Werten aus `spec` zusammen-
|
|
79
|
+
geführt (siehe Merge-Regeln).
|
|
80
|
+
|
|
81
|
+
### 3. Merge-Reihenfolge in `PloneService`
|
|
82
|
+
|
|
83
|
+
Vorhersagbar, shallow (ServiceSpec-Felder sind weitgehend flach):
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
finalSpec = { ...generatedBase, ...curatedFields, ...overrides }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Präzedenz steigend:
|
|
90
|
+
|
|
91
|
+
1. **Construct-Basis:** `ports`, `selector` (aus `targetPort`/`portName`/`selectorLabel`).
|
|
92
|
+
2. **Kuratierte Felder:** alle gesetzten Felder aus `spec` (außer `annotations`,
|
|
93
|
+
`labels`, `overrides`).
|
|
94
|
+
3. **`overrides`:** `k8s.ServiceSpec`-Partial — höchste Präzedenz, überschreibt
|
|
95
|
+
auch `ports`/`selector`. Dokumentiert als „at your own risk".
|
|
96
|
+
|
|
97
|
+
`annotations` und `labels` aus `spec` fließen in `metadata` (nicht in `spec`):
|
|
98
|
+
- `metadata.labels = { ...spec.labels, ...constructManagedLabels }`
|
|
99
|
+
(construct-managed `part-of`/`managed-by` gewinnen — wie bisher).
|
|
100
|
+
- `metadata.annotations = { ...serviceAnnotations (deprecated), ...spec.annotations }`
|
|
101
|
+
(neue `spec.annotations` gewinnen bei Konflikt).
|
|
102
|
+
|
|
103
|
+
### 4. Plumbing: ein Punkt in `PloneBaseOptions` (`src/plone.ts`)
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
/**
|
|
107
|
+
* Service configuration (type, trafficDistribution, sessionAffinity,
|
|
108
|
+
* annotations, raw spec overrides, ...). Applies to the component's Service.
|
|
109
|
+
*/
|
|
110
|
+
readonly service?: PloneServiceSpec;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @deprecated use `service.annotations` instead
|
|
114
|
+
*/
|
|
115
|
+
readonly serviceAnnotations?: { [name: string]: string };
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`backend`/`frontend` erben beide aus `PloneBaseOptions`, daher gilt die
|
|
119
|
+
`service`-Config automatisch für beide Services an genau einer Stelle.
|
|
120
|
+
|
|
121
|
+
In `plone.ts` (Backend-Service ~Z. 468, Frontend-Service ~Z. 570) wird
|
|
122
|
+
`spec` durchgereicht und die deprecated `serviceAnnotations` weiter unterstützt:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
new PloneService(backendDeployment, 'service', {
|
|
126
|
+
// ... unverändert: labels, targetPort, selectorLabel, portName ...
|
|
127
|
+
spec: {
|
|
128
|
+
...backend.service,
|
|
129
|
+
annotations: { ...backend.serviceAnnotations, ...backend.service?.annotations },
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 5. Backward-Compatibility
|
|
135
|
+
|
|
136
|
+
`serviceAnnotations` bleibt funktionsfähig, wird als `@deprecated` markiert und
|
|
137
|
+
mit `service.annotations` zusammengeführt (neue Variante gewinnt). Kein Breaking
|
|
138
|
+
Change. Bestehende Snapshots ohne `service` bleiben unverändert (alle neuen
|
|
139
|
+
Felder sind optional, ungesetzt → keine Spec-Änderung).
|
|
140
|
+
|
|
141
|
+
### 6. Tests (`test/service.test.ts`)
|
|
142
|
+
|
|
143
|
+
Neue Snapshot-/Assertion-Fälle:
|
|
144
|
+
|
|
145
|
+
- `trafficDistribution: 'PreferClose'` → erscheint in `spec`.
|
|
146
|
+
- `type: 'LoadBalancer'` + `loadBalancerSourceRanges` → erscheinen in `spec`.
|
|
147
|
+
- `sessionAffinity` / `externalTrafficPolicy` gesetzt.
|
|
148
|
+
- `overrides` (z.B. `ipFamilyPolicy`) → erscheint in `spec`.
|
|
149
|
+
- Präzedenz: `overrides` schlägt kuratiertes Feld (z.B. beide setzen `type`,
|
|
150
|
+
`overrides` gewinnt).
|
|
151
|
+
- Backward-Compat: nur `serviceAnnotations` gesetzt → unverändertes Verhalten;
|
|
152
|
+
`serviceAnnotations` + `service.annotations` → korrekt gemergt.
|
|
153
|
+
|
|
154
|
+
Snapshots aktualisieren via `npx projen test -- -u`.
|
|
155
|
+
|
|
156
|
+
### 7. Dokumentation
|
|
157
|
+
|
|
158
|
+
Beim Schreiben/Editieren der Doku den Skill **`plone-doc-style:author`**
|
|
159
|
+
verwenden (Diataxis-Quadranten-Zuordnung, MyST-Markup, Style-Enforcement),
|
|
160
|
+
soweit es sinnvoll ist — d.h. für die handgeschriebenen Seiten unter
|
|
161
|
+
`documentation/sources/` (Reference + How-to). Nicht für auto-generierte
|
|
162
|
+
Artefakte (`API.md`).
|
|
163
|
+
|
|
164
|
+
- **`API.md`** ist auto-generiert (`npx projen docgen`) — kein manuelles Edit,
|
|
165
|
+
aber nach Implementierung neu generieren.
|
|
166
|
+
- **`documentation/sources/reference/configuration-options.md`:** Den Abschnitt
|
|
167
|
+
„Annotations" (~Z. 200) zu einem Abschnitt „Service" erweitern bzw. einen
|
|
168
|
+
neuen Abschnitt für `PloneServiceSpec` ergänzen: Tabelle der kuratierten
|
|
169
|
+
Felder + `overrides`, mit Beispiel (`trafficDistribution`, `LoadBalancer`).
|
|
170
|
+
`serviceAnnotations` als deprecated kennzeichnen und auf `service.annotations`
|
|
171
|
+
verweisen.
|
|
172
|
+
- **`documentation/sources/how-to/`:** In `deploy-production-volto.md` ein
|
|
173
|
+
kurzes Beispiel ergänzen (z.B. `trafficDistribution: 'PreferClose'` für
|
|
174
|
+
topologie-nahes Routing), falls thematisch passend.
|
|
175
|
+
- Doku-Build prüfen: `cd documentation && make docs`.
|
|
176
|
+
|
|
177
|
+
## Betroffene Dateien
|
|
178
|
+
|
|
179
|
+
- `src/service.ts` — neuer `PloneServiceSpec`-Typ, erweiterte `PloneServiceOptions`, Merge-Logik.
|
|
180
|
+
- `src/plone.ts` — `service`-Prop in `PloneBaseOptions`, Plumbing in Backend/Frontend, `serviceAnnotations` deprecaten.
|
|
181
|
+
- `test/service.test.ts` (+ Snapshots) — neue Testfälle.
|
|
182
|
+
- `documentation/sources/reference/configuration-options.md` — Service-Config dokumentieren.
|
|
183
|
+
- `documentation/sources/how-to/deploy-production-volto.md` — optionales Beispiel.
|
|
184
|
+
- `API.md` — regenerieren via `npx projen docgen`.
|
|
185
|
+
|
|
186
|
+
## Nicht im Scope (YAGNI)
|
|
187
|
+
|
|
188
|
+
- Multi-Port-Services (mehrere `ports`-Einträge) — über `overrides` möglich,
|
|
189
|
+
aber kein kuratiertes Feature.
|
|
190
|
+
- Eigene Validierung der Enum-Strings (`type`, `sessionAffinity`, …) — k8s
|
|
191
|
+
validiert serverseitig; wir bilden die Strings 1:1 ab.
|
|
192
|
+
- Separate Service-Configs pro Service jenseits von backend/frontend.
|
|
@@ -21,19 +21,20 @@ cdk8s-plone provides CDK8S constructs for deploying Plone CMS on Kubernetes. The
|
|
|
21
21
|
|
|
22
22
|
cdk8s-plone supports two deployment variants:
|
|
23
23
|
|
|
24
|
-
**Volto (
|
|
24
|
+
**Volto (React single-page frontend)**
|
|
25
25
|
- React-based frontend (Volto)
|
|
26
26
|
- REST API backend (Plone)
|
|
27
27
|
- Separate services for frontend and backend
|
|
28
|
-
- Modern user experience
|
|
29
28
|
- Headless CMS architecture
|
|
30
29
|
|
|
31
|
-
**
|
|
32
|
-
-
|
|
30
|
+
**Blicca (server-side rendered)**
|
|
31
|
+
- The Plone backend renders the UI and serves HTML directly
|
|
33
32
|
- Single integrated service
|
|
34
|
-
- Traditional Plone experience
|
|
35
33
|
- Simpler deployment model
|
|
36
34
|
|
|
35
|
+
Blicca is the new name for the variant Plone formerly called "Classic UI".
|
|
36
|
+
Both approaches are equally current; they differ in where rendering happens, not in how modern they are.
|
|
37
|
+
|
|
37
38
|
### High availability
|
|
38
39
|
|
|
39
40
|
**Replica Management**
|
|
@@ -251,7 +252,7 @@ For a typical Volto deployment, cdk8s-plone creates:
|
|
|
251
252
|
- Better resource utilization
|
|
252
253
|
- Clear separation of concerns
|
|
253
254
|
|
|
254
|
-
**When to use
|
|
255
|
+
**When to use Blicca:**
|
|
255
256
|
- Simpler deployment model
|
|
256
257
|
- Lower resource requirements
|
|
257
258
|
- Legacy integrations
|
|
@@ -19,17 +19,19 @@ Complete overview of cdk8s-plone features and capabilities.
|
|
|
19
19
|
|
|
20
20
|
cdk8s-plone supports two deployment modes to match your requirements:
|
|
21
21
|
|
|
22
|
-
**Volto (
|
|
23
|
-
-
|
|
22
|
+
**Volto (React single-page frontend)**
|
|
23
|
+
- React-based user interface
|
|
24
24
|
- Headless CMS architecture
|
|
25
25
|
- Separate frontend and backend services
|
|
26
|
-
- Best for:
|
|
26
|
+
- Best for: API-first architectures, SPA frontends
|
|
27
27
|
|
|
28
|
-
**
|
|
29
|
-
-
|
|
28
|
+
**Blicca (server-side rendered Plone)**
|
|
29
|
+
- The Plone backend renders the UI and serves HTML directly
|
|
30
30
|
- Integrated single-service deployment
|
|
31
|
-
-
|
|
32
|
-
|
|
31
|
+
- Best for: single-service setups, legacy migrations, existing add-ons
|
|
32
|
+
|
|
33
|
+
Blicca is the new name for the variant Plone formerly called "Classic UI".
|
|
34
|
+
Both are equally current; they differ in their rendering approach.
|
|
33
35
|
|
|
34
36
|
See {doc}`architecture` for a deeper architectural comparison of the two variants.
|
|
35
37
|
|
|
@@ -1,37 +1,40 @@
|
|
|
1
1
|
---
|
|
2
2
|
myst:
|
|
3
3
|
html_meta:
|
|
4
|
-
"description": "Deploy the
|
|
5
|
-
"property=og:description": "Deploy the
|
|
6
|
-
"property=og:title": "Deploy
|
|
7
|
-
"keywords": "Plone, cdk8s, Kubernetes, Classic UI, PostgreSQL, Varnish, ingress"
|
|
4
|
+
"description": "Deploy the Blicca example: server-side rendered Plone with PostgreSQL, Varnish caching, and ingress with TLS."
|
|
5
|
+
"property=og:description": "Deploy the Blicca example: server-side rendered Plone with PostgreSQL, Varnish caching, and ingress with TLS."
|
|
6
|
+
"property=og:title": "Deploy Blicca example"
|
|
7
|
+
"keywords": "Plone, cdk8s, Kubernetes, Blicca, Classic UI, PostgreSQL, Varnish, ingress"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Deploy
|
|
10
|
+
# Deploy Blicca example
|
|
11
11
|
|
|
12
|
-
This guide shows you how to deploy the
|
|
12
|
+
This guide shows you how to deploy the Blicca example to your Kubernetes cluster.
|
|
13
|
+
|
|
14
|
+
Blicca is the new name for what Plone formerly called "Classic UI".
|
|
13
15
|
|
|
14
16
|
## What you'll deploy
|
|
15
17
|
|
|
16
|
-
The [
|
|
18
|
+
The [Blicca example](https://github.com/bluedynamics/cdk8s-plone/tree/main/examples/blicca) provides Plone with server-side rendering:
|
|
17
19
|
|
|
18
|
-
- **Plone 6.1
|
|
20
|
+
- **Plone 6.1 Blicca** (backend renders the UI, no separate frontend)
|
|
19
21
|
- **PostgreSQL** with RelStorage (CloudNativePG or Bitnami)
|
|
20
22
|
- **Varnish HTTP caching** with kube-httpcache
|
|
21
23
|
- **Ingress** with TLS (Traefik or Kong)
|
|
22
24
|
- **Simpler architecture** (single backend service)
|
|
23
25
|
|
|
24
|
-
##
|
|
26
|
+
## Blicca vs Volto
|
|
25
27
|
|
|
26
|
-
| Feature |
|
|
28
|
+
| Feature | Blicca | Volto |
|
|
27
29
|
|---------|-----------|-------|
|
|
28
30
|
| **Architecture** | Single backend | Frontend + Backend |
|
|
29
31
|
| **Rendering** | Server-side | Client-side (React) |
|
|
30
32
|
| **Deployment** | Simpler | More complex |
|
|
31
|
-
| **Best for** |
|
|
33
|
+
| **Best for** | Single-service setups, migrations | API-first projects, SPA frontends |
|
|
32
34
|
|
|
33
35
|
:::{tip}
|
|
34
|
-
Choose
|
|
36
|
+
Choose Blicca if you want a single backend service without a separate frontend, or if you need Blicca-specific add-ons.
|
|
37
|
+
For the React single-page frontend approach, consider [Volto](deploy-production-volto.md).
|
|
35
38
|
:::
|
|
36
39
|
|
|
37
40
|
## Prerequisites
|
|
@@ -49,7 +52,7 @@ See [Setup Prerequisites](setup-prerequisites.md) for detailed instructions.
|
|
|
49
52
|
|
|
50
53
|
```shell
|
|
51
54
|
git clone https://github.com/bluedynamics/cdk8s-plone.git
|
|
52
|
-
cd cdk8s-plone/examples/
|
|
55
|
+
cd cdk8s-plone/examples/blicca
|
|
53
56
|
```
|
|
54
57
|
|
|
55
58
|
## Step 2: Install dependencies
|
|
@@ -91,7 +94,8 @@ DATABASE=cloudnativepg
|
|
|
91
94
|
```
|
|
92
95
|
|
|
93
96
|
:::{note}
|
|
94
|
-
|
|
97
|
+
Blicca only needs one image (backend).
|
|
98
|
+
There's no frontend image configuration.
|
|
95
99
|
:::
|
|
96
100
|
|
|
97
101
|
## Step 5: Generate manifests
|
|
@@ -100,28 +104,28 @@ Classic UI only needs one image (backend). There's no frontend image configurati
|
|
|
100
104
|
npm run synth
|
|
101
105
|
```
|
|
102
106
|
|
|
103
|
-
Creates `dist/plone-
|
|
107
|
+
Creates `dist/plone-blicca.k8s.yaml` (~27 KB, smaller than Volto's 32 KB).
|
|
104
108
|
|
|
105
109
|
## Step 6: Review manifests
|
|
106
110
|
|
|
107
111
|
```shell
|
|
108
112
|
# Count resources
|
|
109
|
-
grep "^kind:" dist/plone-
|
|
113
|
+
grep "^kind:" dist/plone-blicca.k8s.yaml | sort | uniq -c
|
|
110
114
|
|
|
111
115
|
# Dry run
|
|
112
|
-
kubectl apply --dry-run=client -f dist/plone-
|
|
116
|
+
kubectl apply --dry-run=client -f dist/plone-blicca.k8s.yaml
|
|
113
117
|
```
|
|
114
118
|
|
|
115
119
|
## Step 7: Deploy
|
|
116
120
|
|
|
117
121
|
```shell
|
|
118
|
-
kubectl apply -f dist/plone-
|
|
122
|
+
kubectl apply -f dist/plone-blicca.k8s.yaml
|
|
119
123
|
```
|
|
120
124
|
|
|
121
125
|
Or to a specific namespace:
|
|
122
126
|
|
|
123
127
|
```shell
|
|
124
|
-
kubectl apply -f dist/plone-
|
|
128
|
+
kubectl apply -f dist/plone-blicca.k8s.yaml -n plone
|
|
125
129
|
```
|
|
126
130
|
|
|
127
131
|
## Step 8: Monitor deployment
|
|
@@ -137,7 +141,7 @@ kubectl wait --for=condition=ready pod \
|
|
|
137
141
|
```
|
|
138
142
|
|
|
139
143
|
:::{note}
|
|
140
|
-
|
|
144
|
+
Blicca deploys fewer pods than Volto (no frontend pods).
|
|
141
145
|
:::
|
|
142
146
|
|
|
143
147
|
## Step 9: Verify services
|
|
@@ -147,7 +151,7 @@ kubectl get svc -l app.kubernetes.io/part-of=plone
|
|
|
147
151
|
```
|
|
148
152
|
|
|
149
153
|
You should see:
|
|
150
|
-
- `plone-backend` (
|
|
154
|
+
- `plone-backend` (Blicca service)
|
|
151
155
|
- `plone-httpcache` (Varnish cache)
|
|
152
156
|
- Database service
|
|
153
157
|
|
|
@@ -174,17 +178,17 @@ Once DNS and TLS are ready:
|
|
|
174
178
|
- **Site ID**: `Plone`
|
|
175
179
|
- **Title**: Your site name
|
|
176
180
|
- **Language**: Select language
|
|
177
|
-
- **Add-ons**: Choose
|
|
181
|
+
- **Add-ons**: Choose Blicca add-ons
|
|
178
182
|
4. Click "Create Plone Site"
|
|
179
183
|
|
|
180
184
|
## Key differences from Volto
|
|
181
185
|
|
|
182
186
|
### Architecture
|
|
183
187
|
|
|
184
|
-
|
|
188
|
+
Blicca routing is simpler - all traffic goes to the backend:
|
|
185
189
|
|
|
186
190
|
```
|
|
187
|
-
Traffic → Ingress → Varnish → Plone Backend (
|
|
191
|
+
Traffic → Ingress → Varnish → Plone Backend (Blicca)
|
|
188
192
|
```
|
|
189
193
|
|
|
190
194
|
Compared to Volto:
|
|
@@ -195,7 +199,7 @@ Traffic → Ingress → {Varnish → Frontend, Backend}
|
|
|
195
199
|
|
|
196
200
|
### Ingress routes
|
|
197
201
|
|
|
198
|
-
|
|
202
|
+
Blicca uses virtual host rewriting for direct backend access:
|
|
199
203
|
|
|
200
204
|
- **Cached**: Routes through Varnish to backend
|
|
201
205
|
- **Uncached**: Direct to backend with VirtualHostBase rewrite
|
|
@@ -225,7 +229,7 @@ Common issues:
|
|
|
225
229
|
- Memory limits too low
|
|
226
230
|
- Image pull errors
|
|
227
231
|
|
|
228
|
-
###
|
|
232
|
+
### Blicca interface not loading
|
|
229
233
|
|
|
230
234
|
1. Check if backend pods are running:
|
|
231
235
|
```shell
|
|
@@ -244,14 +248,14 @@ Common issues:
|
|
|
244
248
|
|
|
245
249
|
### Add-on compatibility
|
|
246
250
|
|
|
247
|
-
Some add-ons are Volto-specific. For
|
|
248
|
-
- Use
|
|
249
|
-
- Check add-on compatibility with Plone 6
|
|
251
|
+
Some add-ons are Volto-specific. For Blicca:
|
|
252
|
+
- Use Blicca themes (not Volto themes)
|
|
253
|
+
- Check add-on compatibility with Plone 6 Blicca
|
|
250
254
|
- Avoid Volto-specific frontend add-ons
|
|
251
255
|
|
|
252
256
|
## Migrating to Volto
|
|
253
257
|
|
|
254
|
-
If you want to migrate from
|
|
258
|
+
If you want to migrate from Blicca to Volto later:
|
|
255
259
|
|
|
256
260
|
1. Keep your backend deployment (same configuration)
|
|
257
261
|
2. Add Volto frontend from the [Volto example](deploy-production-volto.md)
|
|
@@ -268,7 +272,7 @@ Edit `main.ts` to customize:
|
|
|
268
272
|
|
|
269
273
|
```typescript
|
|
270
274
|
const plone = new Plone(this, 'plone', {
|
|
271
|
-
variant: PloneVariant.
|
|
275
|
+
variant: PloneVariant.BLICCA,
|
|
272
276
|
backend: {
|
|
273
277
|
image: 'plone/plone-backend:6.1.3',
|
|
274
278
|
replicas: 2,
|
|
@@ -281,9 +285,9 @@ const plone = new Plone(this, 'plone', {
|
|
|
281
285
|
|
|
282
286
|
### Varnish caching
|
|
283
287
|
|
|
284
|
-
Edit `config/varnish.tpl.vcl` for caching rules specific to
|
|
288
|
+
Edit `config/varnish.tpl.vcl` for caching rules specific to Blicca.
|
|
285
289
|
|
|
286
|
-
|
|
290
|
+
Blicca VCL is simpler than Volto's - all traffic routes to one backend.
|
|
287
291
|
|
|
288
292
|
## Scaling
|
|
289
293
|
|
|
@@ -298,14 +302,14 @@ backend: {
|
|
|
298
302
|
Then:
|
|
299
303
|
```shell
|
|
300
304
|
npm run synth
|
|
301
|
-
kubectl apply -f dist/plone-
|
|
305
|
+
kubectl apply -f dist/plone-blicca.k8s.yaml
|
|
302
306
|
```
|
|
303
307
|
|
|
304
308
|
## Performance
|
|
305
309
|
|
|
306
|
-
|
|
310
|
+
Blicca performance characteristics:
|
|
307
311
|
|
|
308
|
-
- **Server-side rendering**
|
|
312
|
+
- **Server-side rendering** moves rendering work to the backend, so Varnish caching matters
|
|
309
313
|
- **Varnish caching** is critical for performance
|
|
310
314
|
- **Database** is the main bottleneck (use CloudNativePG for HA)
|
|
311
315
|
- **Fewer HTTP requests** than Volto (no separate frontend API calls)
|
|
@@ -313,18 +317,18 @@ Classic UI performance characteristics:
|
|
|
313
317
|
## Cleanup
|
|
314
318
|
|
|
315
319
|
```shell
|
|
316
|
-
kubectl delete -f dist/plone-
|
|
320
|
+
kubectl delete -f dist/plone-blicca.k8s.yaml
|
|
317
321
|
```
|
|
318
322
|
|
|
319
323
|
## Next steps
|
|
320
324
|
|
|
321
325
|
- Follow {doc}`enable-prometheus-monitoring` to add Prometheus monitoring.
|
|
322
326
|
- Configure [CloudNativePG backups](https://cloudnative-pg.io/documentation/).
|
|
323
|
-
- Customize the
|
|
327
|
+
- Customize the theme through the [Plone 6 Classic UI documentation](https://6.docs.plone.org/classic-ui/) (upstream docs; Blicca is the new name for Classic UI).
|
|
324
328
|
|
|
325
329
|
## See also
|
|
326
330
|
|
|
327
|
-
- {doc}`deploy-production-volto` — For the
|
|
331
|
+
- {doc}`deploy-production-volto` — For the React single-page frontend.
|
|
328
332
|
- {doc}`setup-prerequisites` — Cluster requirements.
|
|
329
333
|
- {doc}`/reference/configuration-options` — API reference.
|
|
330
334
|
- [Plone 6 Classic UI documentation](https://6.docs.plone.org/classic-ui/)
|
|
@@ -324,6 +324,6 @@ kubectl delete -f dist/plone-example.k8s.yaml
|
|
|
324
324
|
|
|
325
325
|
## See also
|
|
326
326
|
|
|
327
|
-
- {doc}`deploy-
|
|
327
|
+
- {doc}`deploy-blicca` — For the server-side rendered Plone UI.
|
|
328
328
|
- {doc}`setup-prerequisites` — Detailed cluster setup.
|
|
329
329
|
- {doc}`/reference/configuration-options` — API reference.
|
|
@@ -15,7 +15,7 @@ Complete API reference for cdk8s-plone constructs, generated from TypeScript sou
|
|
|
15
15
|
|
|
16
16
|
The cdk8s-plone library provides the following main constructs:
|
|
17
17
|
|
|
18
|
-
- **Plone**: Main construct for deploying Plone CMS with support for both Volto (React frontend) and
|
|
18
|
+
- **Plone**: Main construct for deploying Plone CMS with support for both Volto (React frontend) and Blicca (server-side rendered) variants
|
|
19
19
|
- **PloneHttpcache**: HTTP caching layer using Varnish for improved performance
|
|
20
20
|
|
|
21
21
|
## Language support
|
|
@@ -16,13 +16,13 @@ Complete reference for all configuration options in cdk8s-plone.
|
|
|
16
16
|
### `Plone`
|
|
17
17
|
|
|
18
18
|
Main construct for deploying Plone CMS. Supports two variants:
|
|
19
|
-
- **VOLTO**:
|
|
20
|
-
- **
|
|
19
|
+
- **VOLTO**: React single-page frontend talking to the REST API backend (default)
|
|
20
|
+
- **BLICCA**: the Plone backend renders the UI server-side and serves HTML directly
|
|
21
21
|
|
|
22
22
|
**Properties:**
|
|
23
23
|
- `backendServiceName` - Name of the backend Kubernetes service
|
|
24
24
|
- `frontendServiceName` - Name of the frontend service (VOLTO only)
|
|
25
|
-
- `variant` - Deployment variant (VOLTO or
|
|
25
|
+
- `variant` - Deployment variant (VOLTO or BLICCA)
|
|
26
26
|
- `siteId` - Plone site ID in ZODB (default: 'Plone')
|
|
27
27
|
|
|
28
28
|
**Example:**
|
|
@@ -75,7 +75,7 @@ Main configuration interface for the Plone construct.
|
|
|
75
75
|
|----------|------|----------|---------|-------------|
|
|
76
76
|
| `version` | `string` | No | - | Version of your project |
|
|
77
77
|
| `siteId` | `string` | No | `'Plone'` | Plone site ID in ZODB |
|
|
78
|
-
| `variant` | `PloneVariant` | No | `VOLTO` | Deployment variant (VOLTO or
|
|
78
|
+
| `variant` | `PloneVariant` | No | `VOLTO` | Deployment variant (VOLTO or BLICCA) |
|
|
79
79
|
| `backend` | `PloneBaseOptions` | Yes | - | Backend configuration |
|
|
80
80
|
| `frontend` | `PloneBaseOptions` | Conditional | - | Frontend configuration (required for VOLTO) |
|
|
81
81
|
| `imagePullSecrets` | `string[]` | No | - | Image pull secrets for private registries |
|
|
@@ -212,7 +212,7 @@ frontend: {
|
|
|
212
212
|
|----------|------|-------------|
|
|
213
213
|
| `annotations` | `Record<string, string>` | Deployment metadata annotations |
|
|
214
214
|
| `podAnnotations` | `Record<string, string>` | Pod template annotations (e.g., for Prometheus) |
|
|
215
|
-
| `serviceAnnotations` | `Record<string, string>` | Service annotations (e.g., for external-dns) |
|
|
215
|
+
| `serviceAnnotations` | `Record<string, string>` | **Deprecated.** Use `service.annotations` instead. Service annotations (e.g., for external-dns) |
|
|
216
216
|
|
|
217
217
|
**Example:**
|
|
218
218
|
```typescript
|
|
@@ -228,6 +228,44 @@ backend: {
|
|
|
228
228
|
}
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
+
#### Service
|
|
232
|
+
|
|
233
|
+
Configure the generated Kubernetes `Service` through the grouped `service` option.
|
|
234
|
+
The `service` option is available on both `backend` and `frontend`.
|
|
235
|
+
Curated fields cover the common cases.
|
|
236
|
+
The `overrides` field is an escape hatch for any other `ServiceSpec` field, and it has the highest precedence.
|
|
237
|
+
|
|
238
|
+
| Property | Type | Description |
|
|
239
|
+
|----------|------|-------------|
|
|
240
|
+
| `service.type` | `string` | Service type: `ClusterIP` (default), `NodePort`, `LoadBalancer`, or `ExternalName` |
|
|
241
|
+
| `service.trafficDistribution` | `string` | Traffic distribution preference, for example `PreferClose` |
|
|
242
|
+
| `service.sessionAffinity` | `string` | Session affinity: `ClientIP` or `None` |
|
|
243
|
+
| `service.externalTrafficPolicy` | `string` | External traffic policy: `Cluster` or `Local` |
|
|
244
|
+
| `service.internalTrafficPolicy` | `string` | Internal traffic policy: `Cluster` or `Local` |
|
|
245
|
+
| `service.publishNotReadyAddresses` | `boolean` | Publish not-ready addresses |
|
|
246
|
+
| `service.loadBalancerClass` | `string` | Load balancer implementation class |
|
|
247
|
+
| `service.loadBalancerSourceRanges` | `string[]` | Allowed source IP ranges for a `LoadBalancer` service |
|
|
248
|
+
| `service.annotations` | `Record<string, string>` | Service metadata annotations (replaces `serviceAnnotations`) |
|
|
249
|
+
| `service.labels` | `Record<string, string>` | Extra Service metadata labels |
|
|
250
|
+
| `service.overrides` | `Record<string, any>` | Raw `ServiceSpec` overrides as a free-form map, with the highest precedence |
|
|
251
|
+
|
|
252
|
+
**Example:**
|
|
253
|
+
```typescript
|
|
254
|
+
backend: {
|
|
255
|
+
service: {
|
|
256
|
+
type: 'LoadBalancer',
|
|
257
|
+
trafficDistribution: 'PreferClose',
|
|
258
|
+
loadBalancerSourceRanges: ['10.0.0.0/8'],
|
|
259
|
+
annotations: {
|
|
260
|
+
'external-dns.alpha.kubernetes.io/hostname': 'backend.example.com',
|
|
261
|
+
},
|
|
262
|
+
overrides: {
|
|
263
|
+
ipFamilyPolicy: 'PreferDualStack',
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
231
269
|
(monitoring)=
|
|
232
270
|
|
|
233
271
|
#### Prometheus monitoring
|
|
@@ -543,18 +581,24 @@ Defines the deployment variant:
|
|
|
543
581
|
|
|
544
582
|
| Value | Description |
|
|
545
583
|
|-------|-------------|
|
|
546
|
-
| `PloneVariant.VOLTO` |
|
|
547
|
-
| `PloneVariant.
|
|
584
|
+
| `PloneVariant.VOLTO` | React single-page frontend talking to the REST API backend (default) |
|
|
585
|
+
| `PloneVariant.BLICCA` | The Plone backend renders the UI server-side and serves HTML directly |
|
|
586
|
+
| `PloneVariant.CLASSICUI` | Deprecated alias for `PloneVariant.BLICCA`, kept for backward compatibility |
|
|
587
|
+
|
|
588
|
+
`BLICCA` is the new name for the former `CLASSICUI` variant.
|
|
589
|
+
Both select the same backend-only deployment.
|
|
590
|
+
`CLASSICUI` keeps its legacy value (`'classicui'`), so existing configuration using `CLASSICUI` or that literal keeps working unchanged.
|
|
591
|
+
The `CLASSICUI` alias will be removed in a future major release.
|
|
548
592
|
|
|
549
593
|
**Example:**
|
|
550
594
|
```typescript
|
|
551
595
|
import { PloneVariant } from '@bluedynamics/cdk8s-plone';
|
|
552
596
|
|
|
553
|
-
// Volto (
|
|
597
|
+
// Volto (React single-page frontend)
|
|
554
598
|
variant: PloneVariant.VOLTO
|
|
555
599
|
|
|
556
|
-
//
|
|
557
|
-
variant: PloneVariant.
|
|
600
|
+
// Blicca (server-side rendered)
|
|
601
|
+
variant: PloneVariant.BLICCA
|
|
558
602
|
```
|
|
559
603
|
|
|
560
604
|
---
|
|
@@ -625,7 +669,7 @@ app.synth();
|
|
|
625
669
|
|
|
626
670
|
- {doc}`/tutorials/01-quick-start` — Get started guide
|
|
627
671
|
- {doc}`/how-to/deploy-production-volto` — Production-ready Volto deployment
|
|
628
|
-
- {doc}`/how-to/deploy-
|
|
672
|
+
- {doc}`/how-to/deploy-blicca` — Blicca deployment
|
|
629
673
|
- {doc}`/how-to/deploy-with-vinyl-cache` — `PloneVinylCache` walk-through
|
|
630
674
|
- {doc}`/how-to/enable-prometheus-monitoring` — Wire up `ServiceMonitor`
|
|
631
675
|
- {doc}`/how-to/configure-security-context` — Harden backend and frontend pods
|
|
@@ -147,7 +147,7 @@ Now that you have a basic Plone deployment:
|
|
|
147
147
|
|
|
148
148
|
- **Configure resources**: See {doc}`/reference/configuration-options` for CPU and memory options.
|
|
149
149
|
- **Add monitoring**: Follow {doc}`/how-to/enable-prometheus-monitoring`.
|
|
150
|
-
- **Explore variants**: Read about Volto and
|
|
150
|
+
- **Explore variants**: Read about Volto and Blicca in {doc}`/explanation/features`.
|
|
151
151
|
- **Harden pods**: Apply {doc}`/how-to/configure-security-context`.
|
|
152
152
|
|
|
153
153
|
## Troubleshooting
|