@bluedynamics/cdk8s-plone 0.1.42 → 0.1.44
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 +26 -25
- package/API.md +6 -2
- package/README.md +3 -3
- package/documentation/sources/conf.py +55 -29
- package/documentation/sources/explanation/architecture.md +14 -16
- package/documentation/sources/explanation/cdk8s-workflow.md +66 -0
- package/documentation/sources/explanation/index.md +1 -27
- package/documentation/sources/how-to/backup-and-restore.md +107 -0
- package/documentation/sources/how-to/configure-env-and-secrets.md +184 -0
- package/documentation/sources/how-to/configure-ingress-tls.md +108 -0
- package/documentation/sources/how-to/configure-security-context.md +0 -5
- package/documentation/sources/how-to/deploy-blicca.md +8 -8
- package/documentation/sources/how-to/{deploy-production-volto.md → deploy-volto.md} +20 -25
- package/documentation/sources/how-to/deploy-with-httpcache.md +224 -0
- package/documentation/sources/how-to/deploy-with-vinyl-cache.md +0 -5
- package/documentation/sources/how-to/enable-prometheus-monitoring.md +4 -5
- package/documentation/sources/how-to/index.md +15 -8
- package/documentation/sources/how-to/scale-and-high-availability.md +122 -0
- package/documentation/sources/how-to/schedule-pods.md +0 -5
- package/documentation/sources/how-to/troubleshooting.md +113 -0
- package/documentation/sources/how-to/upgrade-and-rollout.md +89 -0
- package/documentation/sources/index.md +3 -11
- package/documentation/sources/reference/api/index.md +6 -4
- package/documentation/sources/reference/configuration-options.md +85 -516
- package/documentation/sources/reference/index.md +16 -43
- package/documentation/sources/tutorials/01-quick-start.md +1 -1
- package/documentation/sources/tutorials/index.md +7 -11
- package/examples/blicca/.env.example +3 -2
- package/examples/blicca/README.md +21 -24
- package/examples/blicca/__snapshots__/main.test.ts.snap +138 -345
- package/examples/blicca/main.test.ts +7 -0
- package/examples/blicca/main.ts +8 -7
- package/examples/blicca/postgres.plain.ts +115 -0
- package/examples/blicca/tsconfig.json +33 -0
- package/examples/{production-volto → volto}/.env.example +3 -2
- package/examples/{production-volto → volto}/README.md +20 -23
- package/examples/{production-volto → volto}/__snapshots__/main.test.ts.snap +139 -345
- package/examples/{production-volto → volto}/main.test.ts +7 -0
- package/examples/{production-volto → volto}/main.ts +8 -7
- package/examples/{production-volto → volto}/package.json +1 -1
- package/examples/volto/postgres.plain.ts +115 -0
- package/examples/volto/tsconfig.json +33 -0
- package/lib/deployment.js +36 -3
- package/lib/httpcache.js +42 -6
- package/lib/imports/k8s.js +1075 -1073
- package/lib/imports/monitoring.coreos.com.js +10 -8
- package/lib/imports/vinyl.bluedynamics.eu.d.ts +4011 -53
- package/lib/imports/vinyl.bluedynamics.eu.js +1791 -159
- package/lib/pdb.js +35 -2
- package/lib/plone.js +54 -5
- package/lib/service.js +44 -2
- package/lib/vinylcache.d.ts +3 -1
- package/lib/vinylcache.js +43 -6
- package/package.json +10 -12
- package/documentation/sources/_static/brand-theme.css +0 -685
- package/documentation/sources/_static/custom-icons.css +0 -123
- package/documentation/sources/_static/fonts/hack/Hack-Regular.woff2 +0 -0
- package/documentation/sources/_static/fonts/orbitron/Orbitron-Black.woff2 +0 -11
- package/documentation/sources/_static/fonts/orbitron/Orbitron-Bold.woff2 +0 -11
- package/documentation/sources/_static/fonts/orbitron/Orbitron-Regular.woff2 +0 -0
- package/documentation/sources/_static/fonts/rajdhani/Rajdhani-Bold.woff2 +0 -11
- package/documentation/sources/_static/fonts/rajdhani/Rajdhani-Medium.woff2 +0 -11
- package/documentation/sources/_static/fonts/rajdhani/Rajdhani-Regular.woff2 +0 -11
- package/documentation/sources/_static/fonts/rajdhani/Rajdhani-SemiBold.woff2 +0 -11
- package/documentation/sources/_static/kup6s-icon-explanation.svg +0 -32
- package/documentation/sources/_static/kup6s-icon-howto.svg +0 -34
- package/documentation/sources/_static/kup6s-icon-reference.svg +0 -34
- package/documentation/sources/_static/kup6s-icon-tutorials.svg +0 -30
- package/documentation/sources/_static/logo-fix.js +0 -12
- package/documentation/sources/reference/api/.gitkeep +0 -1
- package/examples/blicca/postgres.bitnami.ts +0 -49
- package/examples/production-volto/postgres.bitnami.ts +0 -49
- /package/documentation/sources/_static/{kup6s-icon-plone.svg → logo.svg} +0 -0
- /package/examples/{production-volto → volto}/cdk8s.yaml +0 -0
- /package/examples/{production-volto → volto}/config/varnish.tpl.vcl +0 -0
- /package/examples/{production-volto → volto}/ingress.ts +0 -0
- /package/examples/{production-volto → volto}/jest.config.js +0 -0
- /package/examples/{production-volto → volto}/postgres.cloudnativepg.ts +0 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
myst:
|
|
3
|
+
html_meta:
|
|
4
|
+
"description": "Configure environment variables and secrets on Plone backend and frontend pods with cdk8s-plone using the cdk8s-plus Env API."
|
|
5
|
+
"property=og:description": "Configure environment variables and secrets on Plone backend and frontend pods with cdk8s-plone using the cdk8s-plus Env API."
|
|
6
|
+
"property=og:title": "Configure environment variables and secrets"
|
|
7
|
+
"keywords": "Plone, cdk8s, Kubernetes, environment variables, secrets, ConfigMap, imagePullSecrets, Env"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Configure environment variables and secrets
|
|
11
|
+
|
|
12
|
+
This guide shows you how to set environment variables on Plone backend and frontend pods and how to source sensitive values from Kubernetes Secrets and ConfigMaps.
|
|
13
|
+
Use it to inject a RelStorage DSN, an admin password, or any runtime configuration without baking values into the image.
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- A working Plone deployment using `cdk8s-plone`.
|
|
18
|
+
- Familiarity with the cdk8s-plus `Env` API and the `EnvValue` helpers it provides.
|
|
19
|
+
- `kubectl` access to the target namespace for creating Secrets and ConfigMaps.
|
|
20
|
+
|
|
21
|
+
## Set a plain environment variable on the backend
|
|
22
|
+
|
|
23
|
+
Pass an `environment` object to `backend`.
|
|
24
|
+
Build each value with `Env.value` for a literal string.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';
|
|
28
|
+
import { Env } from 'cdk8s-plus-30';
|
|
29
|
+
|
|
30
|
+
new Plone(chart, 'plone', {
|
|
31
|
+
variant: PloneVariant.VOLTO,
|
|
32
|
+
backend: {
|
|
33
|
+
image: 'plone/plone-backend:6.1.3',
|
|
34
|
+
environment: {
|
|
35
|
+
variables: {
|
|
36
|
+
PLONE_TIMEZONE: Env.value('Europe/Vienna'),
|
|
37
|
+
ZSERVER_THREADS: Env.value('4'),
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The `environment` option is typed as the cdk8s-plus `Env` construct.
|
|
45
|
+
Its `variables` map takes an `EnvValue` for every entry, so always wrap raw strings in `Env.value`.
|
|
46
|
+
|
|
47
|
+
## Reference a value from a Secret
|
|
48
|
+
|
|
49
|
+
Store sensitive values such as a RelStorage DSN or an admin password in a Kubernetes Secret, then reference them with `Env.fromSecret`.
|
|
50
|
+
|
|
51
|
+
First create the Secret in the cluster.
|
|
52
|
+
|
|
53
|
+
```shell
|
|
54
|
+
kubectl create secret generic plone-backend-secrets \
|
|
55
|
+
--namespace <namespace> \
|
|
56
|
+
--from-literal=relstorage-dsn='dbname=plone host=db user=plone password=s3cret' \
|
|
57
|
+
--from-literal=admin-password='change-me'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Reference the existing Secret by name, then read individual keys from it.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';
|
|
64
|
+
import { Env, Secret } from 'cdk8s-plus-30';
|
|
65
|
+
|
|
66
|
+
const backendSecret = Secret.fromSecretName(
|
|
67
|
+
chart,
|
|
68
|
+
'backend-secret',
|
|
69
|
+
'plone-backend-secrets',
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
new Plone(chart, 'plone', {
|
|
73
|
+
variant: PloneVariant.VOLTO,
|
|
74
|
+
backend: {
|
|
75
|
+
image: 'plone/plone-backend:6.1.3',
|
|
76
|
+
environment: {
|
|
77
|
+
variables: {
|
|
78
|
+
RELSTORAGE_DSN: Env.fromSecret(backendSecret, 'relstorage-dsn'),
|
|
79
|
+
ADMIN_PASSWORD: Env.fromSecret(backendSecret, 'admin-password'),
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`Env.fromSecret` renders a `secretKeyRef` in the pod template, so the value never appears in plain text in the synthesized manifest.
|
|
87
|
+
|
|
88
|
+
## Reference a value from a ConfigMap
|
|
89
|
+
|
|
90
|
+
For non-sensitive configuration that you manage separately from the chart, read keys from a ConfigMap with `Env.fromConfigMap`.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { Env, ConfigMap } from 'cdk8s-plus-30';
|
|
94
|
+
|
|
95
|
+
const settings = ConfigMap.fromConfigMapName(
|
|
96
|
+
chart,
|
|
97
|
+
'settings',
|
|
98
|
+
'plone-settings',
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// inside backend.environment.variables:
|
|
102
|
+
// LOG_LEVEL: Env.fromConfigMap(settings, 'log-level'),
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Set variables on the frontend
|
|
106
|
+
|
|
107
|
+
The frontend accepts the same `environment` option as the backend.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';
|
|
111
|
+
import { Env } from 'cdk8s-plus-30';
|
|
112
|
+
|
|
113
|
+
new Plone(chart, 'plone', {
|
|
114
|
+
variant: PloneVariant.VOLTO,
|
|
115
|
+
frontend: {
|
|
116
|
+
image: 'plone/plone-frontend:16.0.0',
|
|
117
|
+
environment: {
|
|
118
|
+
variables: {
|
|
119
|
+
RAZZLE_API_PATH: Env.value('https://plone.example.com/++api++'),
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The Volto frontend automatically injects `RAZZLE_INTERNAL_API_PATH` when you do not set it.
|
|
127
|
+
Override it through `environment` only when your service topology requires a non-default internal address.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
frontend: {
|
|
131
|
+
image: 'plone/plone-frontend:16.0.0',
|
|
132
|
+
environment: {
|
|
133
|
+
variables: {
|
|
134
|
+
RAZZLE_INTERNAL_API_PATH: Env.value('http://plone-backend:8080/Plone'),
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Pull from a private registry
|
|
141
|
+
|
|
142
|
+
Image registry credentials are not environment variables.
|
|
143
|
+
List the names of existing pull secrets in the top-level `imagePullSecrets` option.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
new Plone(chart, 'plone', {
|
|
147
|
+
variant: PloneVariant.VOLTO,
|
|
148
|
+
imagePullSecrets: ['my-registry-credentials'],
|
|
149
|
+
backend: {
|
|
150
|
+
image: 'registry.example.com/plone-backend:6.1.3',
|
|
151
|
+
},
|
|
152
|
+
frontend: {
|
|
153
|
+
image: 'registry.example.com/plone-frontend:16.0.0',
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Create the pull secret beforehand with `kubectl create secret docker-registry <name>`.
|
|
159
|
+
|
|
160
|
+
## Verify
|
|
161
|
+
|
|
162
|
+
Synthesize the manifests and inspect the rendered Deployment for the expected entries.
|
|
163
|
+
|
|
164
|
+
```shell
|
|
165
|
+
cdk8s synth
|
|
166
|
+
|
|
167
|
+
# Confirm literal values and secret references appear on the backend container
|
|
168
|
+
grep -A 3 'RELSTORAGE_DSN' dist/*.yaml
|
|
169
|
+
grep -B 1 -A 4 'secretKeyRef' dist/*.yaml
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
A `secretKeyRef` block in the output confirms the value resolves at runtime from the Secret rather than being stored in the manifest.
|
|
173
|
+
After applying, check that the variables reach the container.
|
|
174
|
+
|
|
175
|
+
```shell
|
|
176
|
+
kubectl apply -f dist/
|
|
177
|
+
kubectl exec -n <namespace> deployment/<plone-backend-deployment> -- env | grep RELSTORAGE_DSN
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## See also
|
|
181
|
+
|
|
182
|
+
- {doc}`/reference/api/index` — full construct and option reference.
|
|
183
|
+
- {doc}`/reference/configuration-options` — guide to `environment` and `imagePullSecrets`.
|
|
184
|
+
- {doc}`/how-to/configure-security-context` — harden the pods that run with these variables.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
myst:
|
|
3
|
+
html_meta:
|
|
4
|
+
"description": "Expose a cdk8s-plone deployment with a Kubernetes Ingress and TLS certificates from cert-manager."
|
|
5
|
+
"property=og:description": "Expose a cdk8s-plone deployment with a Kubernetes Ingress and TLS certificates from cert-manager."
|
|
6
|
+
"property=og:title": "Configure ingress and TLS"
|
|
7
|
+
"keywords": "Plone, cdk8s, Kubernetes, ingress, TLS, cert-manager, Traefik, Volto"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Configure ingress and TLS
|
|
11
|
+
|
|
12
|
+
This guide shows you how to expose a Plone deployment to the internet with a Kubernetes Ingress and TLS certificates from cert-manager.
|
|
13
|
+
|
|
14
|
+
`cdk8s-plone` does not create ingress resources.
|
|
15
|
+
It creates the Services you route to, and you add the ingress yourself.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- A working Plone deployment created with `cdk8s-plone`.
|
|
20
|
+
- An ingress controller in the cluster, such as [Traefik](https://doc.traefik.io/traefik/) or [ingress-nginx](https://kubernetes.github.io/ingress-nginx/).
|
|
21
|
+
- [cert-manager](https://cert-manager.io/) installed, with a `ClusterIssuer` for your certificate authority.
|
|
22
|
+
- DNS records for your domains pointing at the ingress controller.
|
|
23
|
+
|
|
24
|
+
## Identify the services to route to
|
|
25
|
+
|
|
26
|
+
The constructs expose the Service names you need as read-only members:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
const plone = new Plone(chart, 'plone', {
|
|
30
|
+
backend: { image: 'plone/plone-backend:6.1.3' },
|
|
31
|
+
frontend: { image: 'plone/plone-frontend:16.0.0' },
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const backendService = plone.backendServiceName; // backend REST API, port 8080
|
|
35
|
+
const frontendService = plone.frontendServiceName; // Volto frontend, port 3000 (Volto only)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Both Services name their port `http`, so reference them by that name in an Ingress.
|
|
39
|
+
For the Blicca variant there is no frontend Service; route public traffic to the backend instead.
|
|
40
|
+
When you run a cache, route public traffic to the cache Service from {doc}`/how-to/deploy-with-httpcache` or {doc}`/how-to/deploy-with-vinyl-cache`.
|
|
41
|
+
|
|
42
|
+
## Add an Ingress with TLS
|
|
43
|
+
|
|
44
|
+
Apply an Ingress that routes your domain to the frontend Service and requests a certificate through cert-manager.
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
apiVersion: networking.k8s.io/v1
|
|
48
|
+
kind: Ingress
|
|
49
|
+
metadata:
|
|
50
|
+
name: plone
|
|
51
|
+
annotations:
|
|
52
|
+
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
53
|
+
spec:
|
|
54
|
+
tls:
|
|
55
|
+
- hosts:
|
|
56
|
+
- plone.example.com
|
|
57
|
+
secretName: plone-tls
|
|
58
|
+
rules:
|
|
59
|
+
- host: plone.example.com
|
|
60
|
+
http:
|
|
61
|
+
paths:
|
|
62
|
+
- path: /
|
|
63
|
+
pathType: Prefix
|
|
64
|
+
backend:
|
|
65
|
+
service:
|
|
66
|
+
name: <frontendServiceName>
|
|
67
|
+
port:
|
|
68
|
+
name: http
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
cert-manager watches the `tls` block and the `cluster-issuer` annotation, issues the certificate, and stores it in the `plone-tls` Secret.
|
|
72
|
+
|
|
73
|
+
## Route a cache, an API, and a maintenance domain
|
|
74
|
+
|
|
75
|
+
A production setup commonly uses three domains:
|
|
76
|
+
|
|
77
|
+
- a public domain that points at the Varnish cache Service,
|
|
78
|
+
- an uncached domain that points at the frontend Service for testing,
|
|
79
|
+
- a maintenance domain that points at the backend Service for the Plone control panel.
|
|
80
|
+
|
|
81
|
+
Add one `host` rule per domain, each with its own `tls` entry, pointing at the matching Service.
|
|
82
|
+
|
|
83
|
+
```{tip}
|
|
84
|
+
The [volto example](https://github.com/bluedynamics/cdk8s-plone/tree/main/examples/volto) implements this three-domain pattern with Traefik `IngressRoute` resources in `ingress.ts`.
|
|
85
|
+
Use it as a complete, tested reference, including the Kong and Traefik variants.
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Verify
|
|
89
|
+
|
|
90
|
+
Confirm the ingress and certificate exist and resolve:
|
|
91
|
+
|
|
92
|
+
```shell
|
|
93
|
+
kubectl get ingress -n <namespace>
|
|
94
|
+
kubectl get certificate -n <namespace>
|
|
95
|
+
kubectl describe certificate plone-tls -n <namespace>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Once the certificate is `Ready`, request the site over HTTPS:
|
|
99
|
+
|
|
100
|
+
```shell
|
|
101
|
+
curl -sI https://plone.example.com/
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## See also
|
|
105
|
+
|
|
106
|
+
- {doc}`/how-to/deploy-with-httpcache` — route public traffic through Varnish.
|
|
107
|
+
- {doc}`/how-to/deploy-volto` — a full deployment that includes ingress and TLS.
|
|
108
|
+
- {doc}`/reference/api/index` — `backendServiceName` and `frontendServiceName` reference.
|
|
@@ -7,11 +7,6 @@ myst:
|
|
|
7
7
|
"keywords": "Plone, cdk8s, Kubernetes, security context, Pod Security Standards, hardening"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
```{image} ../_static/kup6s-icon-howto.svg
|
|
11
|
-
:align: center
|
|
12
|
-
:class: section-icon-large
|
|
13
|
-
```
|
|
14
|
-
|
|
15
10
|
# Configure security context
|
|
16
11
|
|
|
17
12
|
<div class="page-metadata">
|
|
@@ -18,7 +18,7 @@ Blicca is the new name for what Plone formerly called "Classic UI".
|
|
|
18
18
|
The [Blicca example](https://github.com/bluedynamics/cdk8s-plone/tree/main/examples/blicca) provides Plone with server-side rendering:
|
|
19
19
|
|
|
20
20
|
- **Plone 6.1 Blicca** (backend renders the UI, no separate frontend)
|
|
21
|
-
- **PostgreSQL** with RelStorage (
|
|
21
|
+
- **PostgreSQL** with RelStorage (plain PostgreSQL or CloudNativePG)
|
|
22
22
|
- **Varnish HTTP caching** with kube-httpcache
|
|
23
23
|
- **Ingress** with TLS (Traefik or Kong)
|
|
24
24
|
- **Simpler architecture** (single backend service)
|
|
@@ -34,17 +34,17 @@ The [Blicca example](https://github.com/bluedynamics/cdk8s-plone/tree/main/examp
|
|
|
34
34
|
|
|
35
35
|
:::{tip}
|
|
36
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-
|
|
37
|
+
For the React single-page frontend approach, consider [Volto](deploy-volto.md).
|
|
38
38
|
:::
|
|
39
39
|
|
|
40
40
|
## Prerequisites
|
|
41
41
|
|
|
42
|
-
Same as the {ref}`
|
|
42
|
+
Same as the {ref}`volto-prerequisites` in the Volto guide, you need:
|
|
43
43
|
|
|
44
44
|
- Ingress controller (Traefik or Kong)
|
|
45
45
|
- cert-manager
|
|
46
46
|
- kube-httpcache operator
|
|
47
|
-
- PostgreSQL
|
|
47
|
+
- PostgreSQL: plain single-instance (default, no operator) or the CloudNativePG operator
|
|
48
48
|
|
|
49
49
|
See [Setup Prerequisites](setup-prerequisites.md) for detailed instructions.
|
|
50
50
|
|
|
@@ -89,7 +89,7 @@ CLUSTER_ISSUER=letsencrypt-prod
|
|
|
89
89
|
# Optional: Custom backend image
|
|
90
90
|
#PLONE_BACKEND_IMAGE=plone/plone-backend:6.1.3
|
|
91
91
|
|
|
92
|
-
# Database: '
|
|
92
|
+
# Database: 'plain' or 'cloudnativepg'
|
|
93
93
|
DATABASE=cloudnativepg
|
|
94
94
|
```
|
|
95
95
|
|
|
@@ -258,11 +258,11 @@ Some add-ons are Volto-specific. For Blicca:
|
|
|
258
258
|
If you want to migrate from Blicca to Volto later:
|
|
259
259
|
|
|
260
260
|
1. Keep your backend deployment (same configuration)
|
|
261
|
-
2. Add Volto frontend from the [Volto example](deploy-
|
|
261
|
+
2. Add Volto frontend from the [Volto example](deploy-volto.md)
|
|
262
262
|
3. Update ingress to route to frontend
|
|
263
263
|
4. Both UIs can run simultaneously during migration
|
|
264
264
|
|
|
265
|
-
See the [
|
|
265
|
+
See the [Volto deployment guide](deploy-volto.md) for details.
|
|
266
266
|
|
|
267
267
|
## Customization
|
|
268
268
|
|
|
@@ -328,7 +328,7 @@ kubectl delete -f dist/plone-blicca.k8s.yaml
|
|
|
328
328
|
|
|
329
329
|
## See also
|
|
330
330
|
|
|
331
|
-
- {doc}`deploy-
|
|
331
|
+
- {doc}`deploy-volto` — For the React single-page frontend.
|
|
332
332
|
- {doc}`setup-prerequisites` — Cluster requirements.
|
|
333
333
|
- {doc}`/reference/configuration-options` — API reference.
|
|
334
334
|
- [Plone 6 Classic UI documentation](https://6.docs.plone.org/classic-ui/)
|
|
@@ -3,25 +3,25 @@ myst:
|
|
|
3
3
|
html_meta:
|
|
4
4
|
"description": "Deploy the production-ready Volto example: React frontend, Plone REST API backend, PostgreSQL, Varnish caching, and ingress with TLS."
|
|
5
5
|
"property=og:description": "Deploy the production-ready Volto example: React frontend, Plone REST API backend, PostgreSQL, Varnish caching, and ingress with TLS."
|
|
6
|
-
"property=og:title": "Deploy
|
|
6
|
+
"property=og:title": "Deploy the Volto example"
|
|
7
7
|
"keywords": "Plone, cdk8s, Kubernetes, Volto, production, PostgreSQL, Varnish, ingress, TLS"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Deploy
|
|
10
|
+
# Deploy the Volto example
|
|
11
11
|
|
|
12
12
|
This guide shows you how to deploy the production-ready Volto example to your Kubernetes cluster.
|
|
13
13
|
|
|
14
14
|
## What you'll deploy
|
|
15
15
|
|
|
16
|
-
The [
|
|
16
|
+
The [Volto example](https://github.com/bluedynamics/cdk8s-plone/tree/main/examples/volto) includes:
|
|
17
17
|
|
|
18
18
|
- **Plone 6.1 with Volto** (React frontend + REST API backend)
|
|
19
|
-
- **PostgreSQL** with RelStorage (
|
|
19
|
+
- **PostgreSQL** with RelStorage (plain PostgreSQL or CloudNativePG)
|
|
20
20
|
- **Varnish HTTP caching** with kube-httpcache
|
|
21
21
|
- **Ingress** with TLS (Traefik or Kong)
|
|
22
22
|
- **Three access domains** (cached, uncached, maintenance)
|
|
23
23
|
|
|
24
|
-
(
|
|
24
|
+
(volto-prerequisites)=
|
|
25
25
|
|
|
26
26
|
## Prerequisites
|
|
27
27
|
|
|
@@ -43,16 +43,13 @@ Ensure you have these installed on your cluster:
|
|
|
43
43
|
kubectl apply -f https://github.com/mittwald/kube-httpcache/releases/latest/download/kube-httpcache.yaml
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
4. **PostgreSQL
|
|
46
|
+
4. **PostgreSQL** - The example provisions the database itself; choose the backend with the `DATABASE` variable in Step 4. Prepare the cluster for your choice:
|
|
47
47
|
|
|
48
|
-
**Option A:
|
|
49
|
-
```shell
|
|
50
|
-
kubectl apply -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.24/releases/cnpg-1.24.0.yaml
|
|
51
|
-
```
|
|
48
|
+
**Option A: plain** (default; no operator needed) - the example deploys a single-instance PostgreSQL StatefulSet using the official `postgres` image, so there is nothing to install.
|
|
52
49
|
|
|
53
|
-
**Option B:
|
|
50
|
+
**Option B: CloudNativePG** (recommended for production HA) - install the operator:
|
|
54
51
|
```shell
|
|
55
|
-
kubectl
|
|
52
|
+
kubectl apply -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.24/releases/cnpg-1.24.0.yaml
|
|
56
53
|
```
|
|
57
54
|
|
|
58
55
|
### Local tools
|
|
@@ -67,7 +64,7 @@ Clone the repository and navigate to the example:
|
|
|
67
64
|
|
|
68
65
|
```shell
|
|
69
66
|
git clone https://github.com/bluedynamics/cdk8s-plone.git
|
|
70
|
-
cd cdk8s-plone/examples/
|
|
67
|
+
cd cdk8s-plone/examples/volto
|
|
71
68
|
```
|
|
72
69
|
|
|
73
70
|
## Step 2: Install dependencies
|
|
@@ -110,14 +107,14 @@ CLUSTER_ISSUER=letsencrypt-prod
|
|
|
110
107
|
|
|
111
108
|
# Optional: Custom images
|
|
112
109
|
#PLONE_BACKEND_IMAGE=plone/plone-backend:6.1.3
|
|
113
|
-
#PLONE_FRONTEND_IMAGE=plone/plone-frontend:
|
|
110
|
+
#PLONE_FRONTEND_IMAGE=plone/plone-frontend:16.0.0
|
|
114
111
|
|
|
115
|
-
# Database: '
|
|
116
|
-
DATABASE=
|
|
112
|
+
# Database: 'plain' or 'cloudnativepg'
|
|
113
|
+
DATABASE=plain
|
|
117
114
|
```
|
|
118
115
|
|
|
119
116
|
:::{tip}
|
|
120
|
-
For production, use `cloudnativepg
|
|
117
|
+
For production high availability, use `cloudnativepg`. For development and small setups, `plain` is simpler and needs no operator.
|
|
121
118
|
:::
|
|
122
119
|
|
|
123
120
|
## Step 5: Generate manifests
|
|
@@ -188,7 +185,7 @@ You should see:
|
|
|
188
185
|
- `plone-backend` (backend service)
|
|
189
186
|
- `plone-frontend` (frontend service)
|
|
190
187
|
- `plone-httpcache` (Varnish cache)
|
|
191
|
-
- Database service (
|
|
188
|
+
- Database service (plain PostgreSQL or CloudNativePG)
|
|
192
189
|
|
|
193
190
|
## Step 10: Check ingress
|
|
194
191
|
|
|
@@ -253,14 +250,12 @@ kubectl get cluster
|
|
|
253
250
|
kubectl get secret -l cnpg.io/cluster
|
|
254
251
|
```
|
|
255
252
|
|
|
256
|
-
**
|
|
253
|
+
**Plain PostgreSQL:**
|
|
257
254
|
|
|
258
255
|
```shell
|
|
259
|
-
# Check
|
|
260
|
-
kubectl get
|
|
261
|
-
|
|
262
|
-
# Check secret
|
|
263
|
-
kubectl describe secret <postgresql-secret-name>
|
|
256
|
+
# Check the StatefulSet and pod
|
|
257
|
+
kubectl get statefulset -l app.kubernetes.io/name=plone-postgresql
|
|
258
|
+
kubectl get pods -l app.kubernetes.io/name=plone-postgresql
|
|
264
259
|
```
|
|
265
260
|
|
|
266
261
|
### TLS certificate issues
|
|
@@ -319,7 +314,7 @@ kubectl delete -f dist/plone-example.k8s.yaml
|
|
|
319
314
|
## Next steps
|
|
320
315
|
|
|
321
316
|
- Configure monitoring and metrics through {doc}`enable-prometheus-monitoring`.
|
|
322
|
-
- Customize [Varnish caching rules](https://github.com/bluedynamics/cdk8s-plone/blob/main/examples/
|
|
317
|
+
- Customize [Varnish caching rules](https://github.com/bluedynamics/cdk8s-plone/blob/main/examples/volto/config/varnish.tpl.vcl).
|
|
323
318
|
- Harden pods with {doc}`configure-security-context`.
|
|
324
319
|
|
|
325
320
|
## See also
|