@bluedynamics/cdk8s-plone 0.1.10 → 0.1.11

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.
Files changed (37) hide show
  1. package/.claude/claude.md +39 -0
  2. package/.claude/settings.local.json +31 -0
  3. package/.jsii +4 -4
  4. package/README.md +15 -2
  5. package/documentation/sources/how-to/deploy-classic-ui.md +322 -0
  6. package/documentation/sources/how-to/deploy-production-volto.md +319 -0
  7. package/documentation/sources/how-to/index.md +13 -0
  8. package/documentation/sources/reference/api/index.md +29 -0
  9. package/examples/classic-ui/.env.example +19 -0
  10. package/examples/classic-ui/README.md +343 -0
  11. package/examples/classic-ui/__snapshots__/main.test.ts.snap +1242 -0
  12. package/examples/classic-ui/cdk8s.yaml +6 -0
  13. package/examples/classic-ui/config/varnish.tpl.vcl +217 -0
  14. package/examples/classic-ui/ingress.ts +217 -0
  15. package/examples/classic-ui/jest.config.js +11 -0
  16. package/examples/classic-ui/main.test.ts +11 -0
  17. package/examples/classic-ui/main.ts +100 -0
  18. package/examples/classic-ui/package-lock.json +5719 -0
  19. package/examples/classic-ui/package.json +36 -0
  20. package/examples/classic-ui/postgres.bitnami.ts +49 -0
  21. package/examples/classic-ui/postgres.cloudnativepg.ts +63 -0
  22. package/examples/production-volto/.env.example +20 -0
  23. package/examples/production-volto/README.md +295 -0
  24. package/examples/production-volto/__snapshots__/main.test.ts.snap +1412 -0
  25. package/examples/production-volto/cdk8s.yaml +6 -0
  26. package/examples/production-volto/config/varnish.tpl.vcl +297 -0
  27. package/examples/production-volto/ingress.ts +229 -0
  28. package/examples/production-volto/jest.config.js +11 -0
  29. package/examples/production-volto/main.test.ts +11 -0
  30. package/examples/production-volto/main.ts +104 -0
  31. package/examples/production-volto/package-lock.json +5714 -0
  32. package/examples/production-volto/package.json +36 -0
  33. package/examples/production-volto/postgres.bitnami.ts +49 -0
  34. package/examples/production-volto/postgres.cloudnativepg.ts +63 -0
  35. package/lib/httpcache.js +1 -1
  36. package/lib/plone.js +1 -1
  37. package/package.json +3 -3
@@ -0,0 +1,39 @@
1
+ # CDK8S Best Practices
2
+
3
+ ## Naming Convention Rule
4
+
5
+ **NEVER use `metadata.name` in CDK8S constructs.**
6
+
7
+ - CDK8S automatically generates unique names for all Kubernetes resources
8
+ - Always let CDK8S decide the name and reference it via the construct's `name` property
9
+ - Manual names can cause conflicts and break CDK8S's naming conventions
10
+
11
+ ### ❌ Wrong:
12
+ ```typescript
13
+ const db = new cnpg.Cluster(this, 'db', {
14
+ metadata: {
15
+ name: 'my-cluster', // NEVER do this!
16
+ },
17
+ spec: { /* ... */ }
18
+ });
19
+ this.dbServiceName = 'my-cluster-rw'; // Wrong: hard-coded name
20
+ ```
21
+
22
+ ### ✅ Correct:
23
+ ```typescript
24
+ const db = new cnpg.Cluster(this, 'db', {
25
+ metadata: {
26
+ // No name property - let CDK8S generate it
27
+ labels: { /* ... */ }
28
+ },
29
+ spec: { /* ... */ }
30
+ });
31
+ // Reference the generated name
32
+ this.dbServiceName = `${db.name}-rw`;
33
+ ```
34
+
35
+ This ensures:
36
+ - No naming conflicts
37
+ - Proper CDK8S resource tracking
38
+ - Consistent naming across the application
39
+ - Easy refactoring and composition
@@ -0,0 +1,31 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(echo $?)",
5
+ "Bash(find:*)",
6
+ "Bash(gh issue view:*)",
7
+ "Bash(gh pr view:*)",
8
+ "Bash(gh run list:*)",
9
+ "Bash(gh run view:*)",
10
+ "Bash(git add:*)",
11
+ "Bash(git checkout:*)",
12
+ "Bash(git cherry-pick:*)",
13
+ "Bash(git commit:*)",
14
+ "Bash(git log:*)",
15
+ "Bash(git ls-tree:*)",
16
+ "Bash(git push)",
17
+ "Bash(git stash:*)",
18
+ "Bash(make docs:*)",
19
+ "Bash(npm install:*)",
20
+ "Bash(npm run compile:*)",
21
+ "Bash(npm test:*)",
22
+ "Bash(npx projen:*)",
23
+ "Bash(nvm use:*)",
24
+ "Bash(source:*)",
25
+ "Bash(yarn install)",
26
+ "Bash(npm run test-update:*)"
27
+ ],
28
+ "deny": [],
29
+ "ask": []
30
+ }
31
+ }
package/.jsii CHANGED
@@ -7,7 +7,7 @@
7
7
  ]
8
8
  },
9
9
  "dependencies": {
10
- "cdk8s": "^2.70.27",
10
+ "cdk8s": "^2.70.28",
11
11
  "cdk8s-plus-30": "^2.4.10",
12
12
  "constructs": "^10.4.2"
13
13
  },
@@ -108,7 +108,7 @@
108
108
  },
109
109
  "name": "@bluedynamics/cdk8s-plone",
110
110
  "readme": {
111
- "markdown": "# CDK8S Plone\n\n> TypeScript and Python library for deploying Plone CMS to Kubernetes using CDK8S\n\n[![npm version](https://badge.fury.io/js/%40bluedynamics%2Fcdk8s-plone.svg)](https://www.npmjs.com/package/@bluedynamics/cdk8s-plone)\n[![PyPI version](https://badge.fury.io/py/cdk8s-plone.svg)](https://pypi.org/project/cdk8s-plone/)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n\n## Overview\n\ncdk8s-plone provides CDK8S constructs for deploying [Plone CMS](https://plone.org/) on Kubernetes. Define your infrastructure using TypeScript or Python and generate Kubernetes manifests automatically.\n\n**Key Features:**\n- 🚀 Supports Volto (modern React frontend) and Classic UI\n- 📦 High availability with configurable replicas\n- ⚡ Optional Varnish HTTP caching layer\n- 🔧 Fine-grained resource and probe configuration\n- 🌍 Multi-language support (TypeScript/JavaScript and Python)\n- ✅ Type-safe infrastructure as code\n\n## Quick Start\n\n### Installation\n\n**TypeScript/JavaScript:**\n```bash\nnpm install @bluedynamics/cdk8s-plone\n```\n\n**Python:**\n```bash\npip install cdk8s-plone\n```\n\n### Basic Example\n\n```typescript\nimport { App, Chart } from 'cdk8s';\nimport { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';\n\nconst app = new App();\nconst chart = new Chart(app, 'PloneDeployment');\n\nnew Plone(chart, 'my-plone', {\n variant: PloneVariant.VOLTO,\n backend: {\n image: 'plone/plone-backend:6.1.3',\n replicas: 3,\n },\n frontend: {\n image: 'plone/plone-frontend:16.0.0',\n replicas: 2,\n },\n});\n\napp.synth();\n```\n\nGenerate Kubernetes manifests:\n```bash\ncdk8s synth\nkubectl apply -f dist/\n```\n\n## Documentation\n\n**📚 Full documentation:** https://bluedynamics.github.io/cdk8s-plone/\n\n- [Quick Start Tutorial](https://bluedynamics.github.io/cdk8s-plone/tutorials/01-quick-start.html)\n- [Configuration Reference](https://bluedynamics.github.io/cdk8s-plone/reference/configuration-options.html)\n- [Architecture Overview](https://bluedynamics.github.io/cdk8s-plone/explanation/architecture.html)\n- [Complete API Documentation](./API.md)\n\n## Examples\n\nSee the [cdk8s-plone-example](https://github.com/bluedynamics/cdk8s-plone-example) repository for complete working examples.\n\n### Prometheus Metrics\n\nEnable Prometheus ServiceMonitor for metrics collection (requires Prometheus Operator):\n\n```typescript\nnew Plone(chart, 'my-plone', {\n backend: {\n servicemonitor: true,\n metricsPath: '/metrics', // optional, defaults to '/metrics'\n },\n frontend: {\n servicemonitor: true,\n metricsPort: 9090, // optional, defaults to service port\n },\n});\n```\n\n**Note:** You must instrument your Plone backend/frontend to expose metrics at the configured endpoint. For Volto/Node.js frontends, consider using [prom-client](https://www.npmjs.com/package/prom-client) or [express-prometheus-middleware](https://www.npmjs.com/package/express-prometheus-middleware).\n\n## Requirements\n- **kubectl** - [Install kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl)\n- **Node.js 16+** (for TypeScript/JavaScript) - [Install Node.js](https://nodejs.org/)\n- **Python 3.8+** (for Python) - [Install Python](https://www.python.org/)\n- **Kubernetes cluster** (local or cloud)\n\nFor detailed setup instructions, see [Setup Prerequisites](https://bluedynamics.github.io/cdk8s-plone/how-to/setup-prerequisites.html).\n\n## Development\n\nThis project uses [Projen](https://projen.io/) for project management.\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n\n# Update project configuration\n# Edit .projenrc.ts, then run:\nnpx projen\n```\n\nFor detailed development instructions, see [CONTRIBUTING.md](./CONTRIBUTING.md) (if available).\n\n## Resources\n\n- [CDK8S Documentation](https://cdk8s.io/)\n- [Plone CMS](https://plone.org/)\n- [kube-httpcache](https://github.com/mittwald/kube-httpcache) (for HTTP caching)\n- [Example Project](https://github.com/bluedynamics/cdk8s-plone-example)\n\n## License\n\n[Apache 2.0](LICENSE)\n\n## Maintainers\n\nMaintained by [Blue Dynamics Alliance](https://github.com/bluedynamics)\n\n**Author:** Jens W. Klein (jk@kleinundpartner.at)\n"
111
+ "markdown": "# CDK8S Plone\n\n> TypeScript and Python library for deploying Plone CMS to Kubernetes using CDK8S\n\n[![npm version](https://badge.fury.io/js/%40bluedynamics%2Fcdk8s-plone.svg)](https://www.npmjs.com/package/@bluedynamics/cdk8s-plone)\n[![PyPI version](https://badge.fury.io/py/cdk8s-plone.svg)](https://pypi.org/project/cdk8s-plone/)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n\n## Overview\n\ncdk8s-plone provides CDK8S constructs for deploying [Plone CMS](https://plone.org/) on Kubernetes. Define your infrastructure using TypeScript or Python and generate Kubernetes manifests automatically.\n\n**Key Features:**\n- 🚀 Supports Volto (modern React frontend) and Classic UI\n- 📦 High availability with configurable replicas\n- ⚡ Optional Varnish HTTP caching layer\n- 🔧 Fine-grained resource and probe configuration\n- 🌍 Multi-language support (TypeScript/JavaScript and Python)\n- ✅ Type-safe infrastructure as code\n\n## Quick Start\n\n### Installation\n\n**TypeScript/JavaScript:**\n```bash\nnpm install @bluedynamics/cdk8s-plone\n```\n\n**Python:**\n```bash\npip install cdk8s-plone\n```\n\n### Basic Example\n\n```typescript\nimport { App, Chart } from 'cdk8s';\nimport { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';\n\nconst app = new App();\nconst chart = new Chart(app, 'PloneDeployment');\n\nnew Plone(chart, 'my-plone', {\n variant: PloneVariant.VOLTO,\n backend: {\n image: 'plone/plone-backend:6.1.3',\n replicas: 3,\n },\n frontend: {\n image: 'plone/plone-frontend:16.0.0',\n replicas: 2,\n },\n});\n\napp.synth();\n```\n\nGenerate Kubernetes manifests:\n```bash\ncdk8s synth\nkubectl apply -f dist/\n```\n\n## Documentation\n\n**📚 Full documentation:** https://bluedynamics.github.io/cdk8s-plone/\n\n- [Quick Start Tutorial](https://bluedynamics.github.io/cdk8s-plone/tutorials/01-quick-start.html)\n- [Configuration Reference](https://bluedynamics.github.io/cdk8s-plone/reference/configuration-options.html)\n- [Architecture Overview](https://bluedynamics.github.io/cdk8s-plone/explanation/architecture.html)\n- [Complete API Documentation](./API.md)\n\n## Examples\n\nComplete working examples are available in the [`examples/`](examples/) directory:\n\n- **[Production Volto](examples/production-volto/)** - Production-ready Plone 6 deployment with modern UI:\n - Volto frontend (React) + REST API backend\n - PostgreSQL with RelStorage (CloudNativePG or Bitnami)\n - Varnish HTTP caching with kube-httpcache\n - Ingress support (Traefik/Kong) with TLS\n\n- **[Classic UI](examples/classic-ui/)** - Traditional Plone deployment with server-side rendering:\n - Classic UI (traditional Plone interface)\n - PostgreSQL with RelStorage (CloudNativePG or Bitnami)\n - Varnish HTTP caching with kube-httpcache\n - Ingress support (Traefik/Kong) with TLS\n - Simpler architecture (no separate frontend)\n\n### Prometheus Metrics\n\nEnable Prometheus ServiceMonitor for metrics collection (requires Prometheus Operator):\n\n```typescript\nnew Plone(chart, 'my-plone', {\n backend: {\n servicemonitor: true,\n metricsPath: '/metrics', // optional, defaults to '/metrics'\n },\n frontend: {\n servicemonitor: true,\n metricsPort: 9090, // optional, defaults to service port\n },\n});\n```\n\n**Note:** You must instrument your Plone backend/frontend to expose metrics at the configured endpoint. For Volto/Node.js frontends, consider using [prom-client](https://www.npmjs.com/package/prom-client) or [express-prometheus-middleware](https://www.npmjs.com/package/express-prometheus-middleware).\n\n## Requirements\n- **kubectl** - [Install kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl)\n- **Node.js 16+** (for TypeScript/JavaScript) - [Install Node.js](https://nodejs.org/)\n- **Python 3.8+** (for Python) - [Install Python](https://www.python.org/)\n- **Kubernetes cluster** (local or cloud)\n\nFor detailed setup instructions, see [Setup Prerequisites](https://bluedynamics.github.io/cdk8s-plone/how-to/setup-prerequisites.html).\n\n## Development\n\nThis project uses [Projen](https://projen.io/) for project management.\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n\n# Update project configuration\n# Edit .projenrc.ts, then run:\nnpx projen\n```\n\nFor detailed development instructions, see [CONTRIBUTING.md](./CONTRIBUTING.md) (if available).\n\n## Resources\n\n- [CDK8S Documentation](https://cdk8s.io/)\n- [Plone CMS](https://plone.org/)\n- [kube-httpcache](https://github.com/mittwald/kube-httpcache) (for HTTP caching)\n- [CloudNativePG](https://cloudnative-pg.io/) (for PostgreSQL management)\n\n## License\n\n[Apache 2.0](LICENSE)\n\n## Maintainers\n\nMaintained by [Blue Dynamics Alliance](https://github.com/bluedynamics)\n\n**Author:** Jens W. Klein (jk@kleinundpartner.at)\n"
112
112
  },
113
113
  "repository": {
114
114
  "type": "git",
@@ -1314,6 +1314,6 @@
1314
1314
  "symbolId": "src/plone:PloneVariant"
1315
1315
  }
1316
1316
  },
1317
- "version": "0.1.10",
1318
- "fingerprint": "yv5KDYY6NCn6j/9ok2cN64Q9Oj+jMBev8qebF6rwRos="
1317
+ "version": "0.1.11",
1318
+ "fingerprint": "vSBaDJVhNiduiyG/9IONZopUT6TCBilfaudzkMnJ7ec="
1319
1319
  }
package/README.md CHANGED
@@ -73,7 +73,20 @@ kubectl apply -f dist/
73
73
 
74
74
  ## Examples
75
75
 
76
- See the [cdk8s-plone-example](https://github.com/bluedynamics/cdk8s-plone-example) repository for complete working examples.
76
+ Complete working examples are available in the [`examples/`](examples/) directory:
77
+
78
+ - **[Production Volto](examples/production-volto/)** - Production-ready Plone 6 deployment with modern UI:
79
+ - Volto frontend (React) + REST API backend
80
+ - PostgreSQL with RelStorage (CloudNativePG or Bitnami)
81
+ - Varnish HTTP caching with kube-httpcache
82
+ - Ingress support (Traefik/Kong) with TLS
83
+
84
+ - **[Classic UI](examples/classic-ui/)** - Traditional Plone deployment with server-side rendering:
85
+ - Classic UI (traditional Plone interface)
86
+ - PostgreSQL with RelStorage (CloudNativePG or Bitnami)
87
+ - Varnish HTTP caching with kube-httpcache
88
+ - Ingress support (Traefik/Kong) with TLS
89
+ - Simpler architecture (no separate frontend)
77
90
 
78
91
  ### Prometheus Metrics
79
92
 
@@ -128,7 +141,7 @@ For detailed development instructions, see [CONTRIBUTING.md](./CONTRIBUTING.md)
128
141
  - [CDK8S Documentation](https://cdk8s.io/)
129
142
  - [Plone CMS](https://plone.org/)
130
143
  - [kube-httpcache](https://github.com/mittwald/kube-httpcache) (for HTTP caching)
131
- - [Example Project](https://github.com/bluedynamics/cdk8s-plone-example)
144
+ - [CloudNativePG](https://cloudnative-pg.io/) (for PostgreSQL management)
132
145
 
133
146
  ## License
134
147
 
@@ -0,0 +1,322 @@
1
+ # Deploy Classic UI Example
2
+
3
+ This guide shows you how to deploy the Classic UI example to your Kubernetes cluster.
4
+
5
+ ## What You'll Deploy
6
+
7
+ The [Classic UI example](https://github.com/bluedynamics/cdk8s-plone/tree/main/examples/classic-ui) provides traditional Plone with server-side rendering:
8
+
9
+ - **Plone 6.1 Classic UI** (traditional interface, no separate frontend)
10
+ - **PostgreSQL** with RelStorage (CloudNativePG or Bitnami)
11
+ - **Varnish HTTP caching** with kube-httpcache
12
+ - **Ingress** with TLS (Traefik or Kong)
13
+ - **Simpler architecture** (single backend service)
14
+
15
+ ## Classic UI vs Volto
16
+
17
+ | Feature | Classic UI | Volto |
18
+ |---------|-----------|-------|
19
+ | **Architecture** | Single backend | Frontend + Backend |
20
+ | **Rendering** | Server-side | Client-side (React) |
21
+ | **Deployment** | Simpler | More complex |
22
+ | **Best for** | Migrations, intranets | Modern projects |
23
+
24
+ :::{tip}
25
+ Choose Classic UI if you're migrating from older Plone versions or need specific Classic UI add-ons. For new projects, consider [Volto](deploy-production-volto.md).
26
+ :::
27
+
28
+ ## Prerequisites
29
+
30
+ Same as the [Production Volto guide](deploy-production-volto.md#prerequisites), you need:
31
+
32
+ - Ingress controller (Traefik or Kong)
33
+ - cert-manager
34
+ - kube-httpcache operator
35
+ - PostgreSQL operator (CloudNativePG or Bitnami)
36
+
37
+ See [Setup Prerequisites](setup-prerequisites.md) for detailed instructions.
38
+
39
+ ## Step 1: Get the Example
40
+
41
+ ```bash
42
+ git clone https://github.com/bluedynamics/cdk8s-plone.git
43
+ cd cdk8s-plone/examples/classic-ui
44
+ ```
45
+
46
+ ## Step 2: Install Dependencies
47
+
48
+ ```bash
49
+ npm install
50
+ ```
51
+
52
+ ## Step 3: Import CRDs
53
+
54
+ ```bash
55
+ npm run import
56
+ ```
57
+
58
+ ## Step 4: Configure Environment
59
+
60
+ Create `.env` from the example:
61
+
62
+ ```bash
63
+ cp .env.example .env
64
+ ```
65
+
66
+ Edit `.env`:
67
+
68
+ ```bash
69
+ # Your domains
70
+ DOMAIN_CACHED=plone.example.com
71
+ DOMAIN_UNCACHED=plone-test.example.com
72
+ DOMAIN_MAINTENANCE=plone-admin.example.com
73
+
74
+ # Your cert-manager ClusterIssuer
75
+ CLUSTER_ISSUER=letsencrypt-prod
76
+
77
+ # Optional: Custom backend image
78
+ #PLONE_BACKEND_IMAGE=plone/plone-backend:6.1.3
79
+
80
+ # Database: 'bitnami' or 'cloudnativepg'
81
+ DATABASE=cloudnativepg
82
+ ```
83
+
84
+ :::{note}
85
+ Classic UI only needs one image (backend). There's no frontend image configuration.
86
+ :::
87
+
88
+ ## Step 5: Generate Manifests
89
+
90
+ ```bash
91
+ npm run synth
92
+ ```
93
+
94
+ Creates `dist/plone-classic.k8s.yaml` (~27 KB, smaller than Volto's 32 KB).
95
+
96
+ ## Step 6: Review Manifests
97
+
98
+ ```bash
99
+ # Count resources
100
+ grep "^kind:" dist/plone-classic.k8s.yaml | sort | uniq -c
101
+
102
+ # Dry run
103
+ kubectl apply --dry-run=client -f dist/plone-classic.k8s.yaml
104
+ ```
105
+
106
+ ## Step 7: Deploy
107
+
108
+ ```bash
109
+ kubectl apply -f dist/plone-classic.k8s.yaml
110
+ ```
111
+
112
+ Or to a specific namespace:
113
+
114
+ ```bash
115
+ kubectl apply -f dist/plone-classic.k8s.yaml -n plone
116
+ ```
117
+
118
+ ## Step 8: Monitor Deployment
119
+
120
+ ```bash
121
+ # Watch pods
122
+ kubectl get pods -l app.kubernetes.io/part-of=plone -w
123
+
124
+ # Wait for ready
125
+ kubectl wait --for=condition=ready pod \
126
+ -l app.kubernetes.io/part-of=plone \
127
+ --timeout=300s
128
+ ```
129
+
130
+ :::{note}
131
+ Classic UI deploys fewer pods than Volto (no frontend pods).
132
+ :::
133
+
134
+ ## Step 9: Verify Services
135
+
136
+ ```bash
137
+ kubectl get svc -l app.kubernetes.io/part-of=plone
138
+ ```
139
+
140
+ You should see:
141
+ - `plone-backend` (Classic UI service)
142
+ - `plone-httpcache` (Varnish cache)
143
+ - Database service
144
+
145
+ ## Step 10: Check Ingress
146
+
147
+ ```bash
148
+ kubectl get ingress
149
+ kubectl get certificate
150
+ ```
151
+
152
+ ## Step 11: Access Your Site
153
+
154
+ Once DNS and TLS are ready:
155
+
156
+ - **Public (cached)**: https://plone.example.com
157
+ - **Testing (uncached)**: https://plone-test.example.com
158
+ - **Maintenance**: https://plone-admin.example.com
159
+
160
+ ### Create Plone Site
161
+
162
+ 1. Access maintenance domain: https://plone-admin.example.com
163
+ 2. Click "Create a new Plone site"
164
+ 3. Configure:
165
+ - **Site ID**: `Plone`
166
+ - **Title**: Your site name
167
+ - **Language**: Select language
168
+ - **Add-ons**: Choose Classic UI add-ons
169
+ 4. Click "Create Plone Site"
170
+
171
+ ## Key Differences from Volto
172
+
173
+ ### Architecture
174
+
175
+ Classic UI routing is simpler - all traffic goes to the backend:
176
+
177
+ ```
178
+ Traffic → Ingress → Varnish → Plone Backend (Classic UI)
179
+ ```
180
+
181
+ Compared to Volto:
182
+
183
+ ```
184
+ Traffic → Ingress → {Varnish → Frontend, Backend}
185
+ ```
186
+
187
+ ### Ingress Routes
188
+
189
+ Classic UI uses virtual host rewriting for direct backend access:
190
+
191
+ - **Cached**: Routes through Varnish to backend
192
+ - **Uncached**: Direct to backend with VirtualHostBase rewrite
193
+ - **Maintenance**: Direct backend access with VirtualHostRoot
194
+
195
+ ### No Frontend Service
196
+
197
+ The manifest doesn't include:
198
+ - Frontend deployment
199
+ - Frontend service
200
+ - Frontend-to-backend internal routing
201
+
202
+ This makes the deployment ~15% smaller and simpler to manage.
203
+
204
+ ## Troubleshooting
205
+
206
+ ### Backend Not Starting
207
+
208
+ Check backend logs:
209
+
210
+ ```bash
211
+ kubectl logs -l app.kubernetes.io/name=plone-backend -f
212
+ ```
213
+
214
+ Common issues:
215
+ - Database connection failures
216
+ - Memory limits too low
217
+ - Image pull errors
218
+
219
+ ### Classic UI Interface Not Loading
220
+
221
+ 1. Check if backend pods are running:
222
+ ```bash
223
+ kubectl get pods -l app.kubernetes.io/name=plone-backend
224
+ ```
225
+
226
+ 2. Verify virtual host rewriting in ingress:
227
+ ```bash
228
+ kubectl describe ingress
229
+ ```
230
+
231
+ 3. Check Varnish routing:
232
+ ```bash
233
+ kubectl logs -l app.kubernetes.io/name=plone-httpcache
234
+ ```
235
+
236
+ ### Add-on Compatibility
237
+
238
+ Some add-ons are Volto-specific. For Classic UI:
239
+ - Use Classic UI themes (not Volto themes)
240
+ - Check add-on compatibility with Plone 6 Classic UI
241
+ - Avoid Volto-specific frontend add-ons
242
+
243
+ ## Migrating to Volto
244
+
245
+ If you want to migrate from Classic UI to Volto later:
246
+
247
+ 1. Keep your backend deployment (same configuration)
248
+ 2. Add Volto frontend from the [Volto example](deploy-production-volto.md)
249
+ 3. Update ingress to route to frontend
250
+ 4. Both UIs can run simultaneously during migration
251
+
252
+ See the [Production Volto deployment guide](deploy-production-volto.md) for details.
253
+
254
+ ## Customization
255
+
256
+ ### Backend Configuration
257
+
258
+ Edit `main.ts` to customize:
259
+
260
+ ```typescript
261
+ const plone = new Plone(this, 'plone', {
262
+ variant: PloneVariant.CLASSICUI,
263
+ backend: {
264
+ image: 'plone/plone-backend:6.1.3',
265
+ replicas: 2,
266
+ limitMemory: '1Gi',
267
+ limitCpu: '1000m',
268
+ environment: env,
269
+ },
270
+ })
271
+ ```
272
+
273
+ ### Varnish Caching
274
+
275
+ Edit `config/varnish.tpl.vcl` for caching rules specific to Classic UI.
276
+
277
+ Classic UI VCL is simpler than Volto's - all traffic routes to one backend.
278
+
279
+ ## Scaling
280
+
281
+ Scale backend replicas:
282
+
283
+ ```typescript
284
+ backend: {
285
+ replicas: 3, // Increase for higher traffic
286
+ }
287
+ ```
288
+
289
+ Then:
290
+ ```bash
291
+ npm run synth
292
+ kubectl apply -f dist/plone-classic.k8s.yaml
293
+ ```
294
+
295
+ ## Performance
296
+
297
+ Classic UI performance characteristics:
298
+
299
+ - **Server-side rendering** can be slower than Volto's client-side
300
+ - **Varnish caching** is critical for performance
301
+ - **Database** is the main bottleneck (use CloudNativePG for HA)
302
+ - **Fewer HTTP requests** than Volto (no separate frontend API calls)
303
+
304
+ ## Cleanup
305
+
306
+ ```bash
307
+ kubectl delete -f dist/plone-classic.k8s.yaml
308
+ ```
309
+
310
+ ## Next Steps
311
+
312
+ - Add [Prometheus monitoring](../reference/configuration-options.md#monitoring)
313
+ - Configure [CloudNativePG backups](https://cloudnative-pg.io/documentation/)
314
+ - Customize [Classic UI theme](https://6.docs.plone.org/classic-ui/theming.html)
315
+ - Set up [content migration](https://6.docs.plone.org/install/upgrade-guide.html)
316
+
317
+ ## See Also
318
+
319
+ - [Deploy Production Volto](deploy-production-volto.md) - For modern React UI
320
+ - [Setup Prerequisites](setup-prerequisites.md) - Cluster requirements
321
+ - [Configuration Options](../reference/configuration-options.md) - API reference
322
+ - [Plone 6 Classic UI Documentation](https://6.docs.plone.org/classic-ui/)