blob: 7d5d8b0478275fd9132ff29b761c7dc53e58734a [file] [log] [blame] [view]
gioc9161872024-04-21 10:46:35 +04001# Helm chart for OpenProject
2
3This is the chart for OpenProject itself. It bootstraps an OpenProject instance, optionally with a PostgreSQL database and Memcached.
4
5## Prerequisites
6
7- Kubernetes 1.16+
8- Helm 3.0.0+
9- PV provisioner support in the underlying infrastructure
10
11
12## Helm chart Provenance and Integrity
13
14We sign our chart using the [Helm Provenance and Integrity](https://helm.sh/docs/topics/provenance/) functionality. You can find the used public key here
15
16- https://github.com/opf/helm-charts/blob/main/signing.key
17- https://keys.openpgp.org/vks/v1/by-fingerprint/CB1CA0488A75B7471EA1B087CF56DD6A0AE260E5
18
19We recommend using the [Helm GnuPG plugin](https://github.com/technosophos/helm-gpg). With it you can manually verify the signature like this:
20
21```bash
22helm repo add openproject https://charts.openproject.org
23helm fetch --prov openproject/openproject
24helm gpg verify openproject-*.tgz
25```
26
27## Installation
28
29### Quick start
30
31```shell
32helm repo add openproject https://charts.openproject.org
33helm upgrade --create-namespace --namespace openproject --install my-openproject openproject/openproject
34```
35
36You can also install the chart with the release name `my-openproject` in its own namespace like this:
37
38```shell
39helm upgrade --create-namespace --namespace openproject --install my-openproject openproject/openproject
40```
41
42The namespace is optional, but we recommend it as it does make it easier to manage the resources created for OpenProject.
43
44## Configuration
45
46Configuration of the chart takes place through defined values, and a catch-all entry `environment` to provide all possible variables through ENV that OpenProject supports. To get more information about the possible values, please see [our guide on environment variables](https://www.openproject.org/docs/installation-and-operations/configuration/environment/).
47
48
49
50### Available OpenProject specific helm values
51
52We try to map the most common options to chart values directly for ease of use. The most common ones are listed here, feel free to extend available values [through a pull request](https://github.com/opf/helm-charts/).
53
54
55
56**OpenProject image and version**
57
58By default, the helm chart will target the latest stable major release. You can define a custom [supported docker tag](https://hub.docker.com/r/openproject/community/) using `image.tag`. Override container registry and repository using `image.registry` and `image.repository`, respectively.
59
60Please make sure to use the `-slim` variant of OpenProject, as the all-in-one container is adding unnecessary services and will not work as expected with default options such as operating as a non-root user.
61
62
63
64**HTTPS mode**
65
66Regardless of the TLS mode of ingress, OpenProject needs to be told whether it's expected to run and return HTTPS responses (or generate correct links in mails, background jobs, etc.). If you're not running https, then set `openproject.https=false`.
67
68
69
70**Seed locale** (13.0+)
71
72By default, demo data and global names for types, statuses, etc. will be in English. If you wish to set a custom locale, set `openproject.seed_locale=XX`, where XX can be a two-character ISO code. For currently supported values, see the `OPENPROJECT_AVAILABLE__LANGUAGES` default value in the [environment guide](https://www.openproject.org/docs/installation-and-operations/configuration/environment/).
73
74
75
76**Admin user** (13.0+)
77
78By default, OpenProject generates an admin user with password `admin` which is required to change after first interactive login.
79If you're operating an automated deployment with fresh databases for testing, this default approach might not be desirable.
80
81You can customize the password as well as name, email, and whether a password change is enforced on first login with these variables:
82
83```ruby
84openproject.admin_user.password="my-secure-password"
85openproject.admin_user.password_reset="false"
86openproject.admin_user.name="Firstname Lastname"
87openproject.admin_user.mail="admin@example.com"
88```
89
90
91
92### ReadWriteMany volumes
93
94By default and when using filesystem-based attachments, OpenProject requires the Kubernetes cluster to support `ReadWriteMany` (rwx) volumes. This is due to the fact that multiple container instances need access to write to the attachment storage.
95
96To avoid using ReadWriteMany, you will need to configure an S3 compatible object storage instead which is shown in the [advanced configuration guide](https://www.openproject.org/docs/installation-and-operations/configuration/#attachments-storage).
97
98```
99persistence:
100 enabled: false
101
102s3:
103 enabled: true
104 accessKeyId:
105 # host:
106 # port:
107```
108
109
110
111### Updating the configuration
112
113The OpenProject configuration can be changed through environment variables.
114You can use `helm upgrade` to set individual values.
115
116For instance:
117
118```shell
119helm upgrade --reuse-values --namespace openproject my-openproject --set environment.OPENPROJECT_IMPRESSUM__LINK=https://www.openproject.org/legal/imprint/ --set environment.OPENPROJECT_APP__TITLE='My OpenProject'
120```
121
122Find out more about the [configuration through environment variables](https://www.openproject.org/docs/installation-and-operations/configuration/environment/) section.
123
124
125
126## Uninstalling the Chart
127
128To uninstall the release with the name my-openproject do the following:
129
130```shell
131helm uninstall --namespace openproject my-openproject
132```
133
134
135
136> **Note**: This will not remove the persistent volumes created while installing.
137> The easiest way to ensure all PVCs are deleted as well is to delete the openproject namespace
138> (`kubectl delete namespace openproject`). If you installed OpenProject into the default
139> namespace, you can delete the volumes manually one by one.
140
141
142
143## Troubleshooting
144
145### Web deployment stuck in `CrashLoopBackoff`
146
147Describing the pod may yield an error like the following:
148
149```
15065s) kubelet Error: failed to start container "openproject": Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error setting cgroup config for procHooks process: failed to write "400000": write /sys/fs/cgroup/cpu,cpuacct/kubepods/burstable/pod990fa25e-dbf0-4fb7-9b31-9d7106473813/openproject/cpu.cfs_quota_us: invalid argument: unknown
151```
152
153This can happen when using **minikube**. By default, it initialises the cluster with 2 CPUs only.
154
155Either increase the cluster's resources to have at least 4 CPUs or install the OpenProject helm chart with a reduced CPU limit by adding the following option to the install command:
156
157```shell
158--set resources.limits.cpu=2
159```
160
161## Development
162
163To install or update from this directory run the following command.
164
165```bash
166bin/install-dev
167```
168
169This will install the chart with `--set develop=true` which is recommended
170on local clusters such as **minikube** or **kind**.
171
172This will also set `OPENPROJECT_HTTPS` to false so no TLS certificate is required
173to access it.
174
175You can set other options just like when installing via `--set`
176(e.g. `bin/install-dev --set persistence.enabled=false`).
177
178### Debugging
179
180Changes to the chart can be debugged using the following.
181
182```bash
183bin/debug
184```
185
186This will try to render the templates and show any errors.
187You can set values just like when installing via `--set`
188(e.g. `bin/debug --set persistence.enabled=false`).
189
190## TLS
191
192Create a TLS certificate, e.g. using [mkcert](https://github.com/FiloSottile/mkcert).
193
194```
195mkcert helm-example.openproject-dev.com
196```
197
198Create the tls secret in kubernetes.
199
200```
201kubectl -n openproject create secret tls openproject-tls \
202 --key="helm-example.openproject-dev.com-key.pem" \
203 --cert="helm-example.openproject-dev.com.pem"
204```
205
206Set the tls secret value during installation or an upgrade by adding the following.
207
208```
209--set ingress.tls.enabled=true --set tls.secretName=openproject-tls
210```
211
212### Root CA
213
214If you want to add your own root CA for outgoing TLS connection, do the following.
215
2161. Put the certificate into a config map.
217
218```
219kubectl -n openproject-dev create configmap ca-pemstore --from-file=/path/to/rootCA.pem
220```
221
222To make OpenProject use this CA for outgoing TLS connection, set the following options.
223
224```
225 --set egress.tls.rootCA.configMap=ca-pemstore \
226 --set egress.tls.rootCA.fileName=rootCA.pem
227```
228
229## Secrets
230
231There are various sensitive credentials used by the chart.
232While they can be provided directly in the values (e.g. `--set postgresql.auth.password`),
233it is recommended to store them in secrets instead.
234
235You can create a new secret like this:
236
237```
238kubectl -n openproject create secret generic <name>
239```
240
241You can then edit the secret to add the credentials via the following.
242
243```
244kubectl -n openproject edit secret <name>
245```
246
247The newly created secret will look something like this:
248
249```
250apiVersion: v1
251kind: Secret
252metadata:
253 creationTimestamp: "2024-01-10T09:36:09Z"
254 name: <name>
255 namespace: openproject
256 resourceVersion: "1074377"
257 uid: ff6538cd-f8cb-418f-8cee-bd1e20d96d24
258type: Opaque
259```
260
261To add the actual content, you can simply add `stringData:` to the end of it and save it.
262
263The keys which are looked up inside the secret data can be changed from their defaults in the values as well. This is the same in all cases where next to `existingSecret` you can also set `secretKeys`.
264
265In the following sections we give examples for what this may look like using the default keys for the credentials used by OpenProject.
266
267### PostgreSQL
268
269```yaml
270stringData:
271 postgres-password: postgresPassword
272 password: userPassword
273```
274
275If you have an existing secret where the keys are not `postgres-password` and `password`, you can customize the used keys as mentioned above.
276
277For instance:
278
279```bash
280helm upgrade --create-namespace --namespace openproject --install openproject \
281 --set postgresql.auth.existingSecret=mysecret \
282 --set postgresql.auth.secretKeys.adminPasswordKey=adminpw \
283 --set postgresql.auth.secretKeys.userPasswordKey=userpw
284```
285
286This can be customized for the the credentials in the following sections too in the same fashion.
287You can look up the respective options in the [`values.yaml`](./values.yaml) file.
288
289#### Default passwords
290
291If you provide neither an existing secret nor passwords directly in the `values.yaml` file,
292the postgres chart will generate a secret automatically.
293
294This secret will contain both the user and admin passwords.
295You can print the base64 encoded passwords as follows.
296
297```
298kubectl get secret -n <namespace> openproject-postgresql -o yaml | grep password
299```
300
301### OIDC (OpenID Connect)
302
303```yaml
304stringData:
305 clientId: 7c6cc104-1d07-4a9f-b3fb-017da8577cec
306 clientSecret: Sf78Q~H14O7F2_EOS4NsLoxu-ayOm42i~MljMb44
307```
308
309
310
311**Sealed secrets**
312
313```bash
314kubectl create secret generic openproject-oidc-secret-sealed --from-literal=OPENPROJECT_OPENID__CONNECT_PROVIDERHERE_IDENTIFIER=xxxxx --from-literal=OPENPROJECT_OPENID__CONNECT_PROVIDERHERE_SECRET=xxxxx --dry-run=client -o yaml | kubeseal ...
315```
316
317Set `openproject.oidc.extraOidcSealedSecret="openproject-oidc-secret-sealed"` in your values.
318
319### S3
320
321```yaml
322stringData:
323 accessKeyId: AKIAXDF2JNZRBFQIRTKA
324 secretAccessKey: zwH7t0H3bJQf/TvlQpE7/Y59k9hD+nYNRlKUBpuq
325```
326
327## OpenShift
328
329For OpenProject to work in OpenShift without further adjustments,
330you need to use the following pod and container security context.
331
332```
333podSecurityContext:
334 supplementalGroups: [1000]
335 fsGroup: null
336
337containerSecurityContext:
338 runAsUser: null
339 runAsGroup: null
340```
341
342By default OpenProject requests `fsGroup: 1000` in the pod security context, and also `1000` for both `runAsUser` and `runAsGroup` in the container security context.
343You have to allow this using a custom SCC (Security Context Constraint) in the cluster. In this case you do not have to adjust the security contexts.
344But the easiest way is the use of the security contexts as shown above.
345
346Due to the default restrictions in OpenShift there may also be issues running
347PostgreSQL and memcached. Again, you may have to create an SCC to fix this
348or adjust the policies in the subcharts accordingly.
349
350Assuming no further options for both, simply disabling the security context values to use the default works as well.
351
352```
353postgresql:
354 primary:
355 containerSecurityContext:
356 enabled: false
357 podSecurityContext:
358 enabled: false
359
360memcached:
361 containerSecurityContext:
362 enabled: false
363 podSecurityContext:
364 enabled: false
365```