(helm) add a ServiceMonitor and a PodMonitor when metrics enabled

When metrics is enabled, we want to create a ServiceMonitor od
PodMonitor in order to scrap the metrics from django and yhub. We have
to add an exception on the redirect to ssl for the metrics endpoint,
like for the probes endpoint, the traffic is internal.
This commit is contained in:
Manuel Raynaud
2026-09-22 16:04:23 +02:00
parent 41e5f455e7
commit e9ba24e0c4
18 changed files with 1319 additions and 369 deletions
+6
View File
@@ -29,6 +29,12 @@ and this project adheres to
bearer token
- ✨(helm) add a dedicated ingress for the prometheus metrics of the backend
and of yhub
- ✨(helm) add a ServiceMonitor and a PodMonitor per component whose metrics
are enabled, and `backend.metrics.enabled`
- 🔧(helm) scrape the metrics of the dev cluster with a trimmed
kube-prometheus-stack and the ServiceMonitors of the chart
- 🔧(helm) serve the example console of django-prometheus on the dev
Prometheus
- ✨(backend) add a service generating cached RS256 JWT tokens
- ✨(backend) publish the JWT public key on a JWKS endpoint
- 🔧(dev) generate the JWT signing key when bootstrapping the dev stack
+37 -2
View File
@@ -63,8 +63,43 @@ k8s_resource('impress-docs-celery-worker', resource_deps=['valkey-docs'])
k8s_resource('impress-docs-yhub', resource_deps=['valkey-yhub'])
k8s_resource('impress-docs-yhub-worker', resource_deps=['valkey-yhub'])
# the valkey chart leaves its objects without a namespace
k8s_yaml(namespace_inject(local('cd ../src/helm && helmfile -n impress -e dev template .'), 'impress'))
# The Prometheus Operator carries the CRDs of its release, and the Prometheus
# it runs (a workload of its own kind, whose pods the operator creates). The
# ServiceMonitors of the application are a resource apart, applied once the
# operator is up: their kind does not exist before its CRDs do, and nothing of
# the application waits for them. The kind is a regular expression, matched
# anywhere in the name: anchored, or it takes the PrometheusRule too.
k8s_kind('^Prometheus$', pod_readiness='ignore')
k8s_resource('prometheus-operator', objects=[
'alertmanagerconfigs.monitoring.coreos.com:customresourcedefinition',
'alertmanagers.monitoring.coreos.com:customresourcedefinition',
'podmonitors.monitoring.coreos.com:customresourcedefinition',
'probes.monitoring.coreos.com:customresourcedefinition',
'prometheusagents.monitoring.coreos.com:customresourcedefinition',
'prometheuses.monitoring.coreos.com:customresourcedefinition',
'prometheusrules.monitoring.coreos.com:customresourcedefinition',
'scrapeconfigs.monitoring.coreos.com:customresourcedefinition',
'servicemonitors.monitoring.coreos.com:customresourcedefinition',
'thanosrulers.monitoring.coreos.com:customresourcedefinition',
])
k8s_resource('prometheus-prometheus', objects=[
'prometheus-prometheus:ingress',
# the example console of django-prometheus and the rules feeding it
'django-console:configmap',
'django:prometheusrule',
], resource_deps=['prometheus-operator'], links=[
'https://docs-prometheus.127.0.0.1.nip.io/targets',
'https://docs-prometheus.127.0.0.1.nip.io/consoles/django.html',
])
k8s_resource(new_name='impress-docs-monitors', objects=[
'impress-docs-backend:servicemonitor',
'impress-docs-yhub:servicemonitor',
'impress-docs-yhub-worker:servicemonitor',
], resource_deps=['prometheus-operator'])
# the valkey chart leaves its objects without a namespace, and the CRDs of the
# prometheus release only come with --include-crds
k8s_yaml(namespace_inject(local('cd ../src/helm && helmfile -n impress -e dev template --include-crds .'), 'impress'))
migration = '''
set -eu
+96 -23
View File
@@ -24,6 +24,12 @@ PROMETHEUS_API_KEY=<a long random secret> # or PROMETHEUS_API_KEY_FILE
The application **refuses to start** with the metrics enabled and no key: the
endpoint would otherwise answer to anybody.
In production the endpoint follows `SECURE_SSL_REDIRECT` like every other
path: a scrape over plain http is redirected to https, so that the key never
travels in clear. `PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT=True` lifts that for
`/metrics` only, for a scraper that reaches the process past the proxy
terminating TLS, see [several replicas](#several-replicas-behind-one-address).
Then scrape `GET /metrics` with the key as a bearer token:
```yaml
@@ -133,19 +139,101 @@ average: use a short scrape interval and rate windows of several minutes, and
aggregate with `sum without (hostname) (rate(...[5m]))`.
This degrades as the number of replicas grows. A Prometheus running inside the
cluster should scrape each pod directly instead (a `PodMonitor` or pod
discovery on the `http` port, same path, same bearer token).
cluster should scrape each pod directly instead: same path, same bearer token,
one target per pod. The chart builds the `ServiceMonitor` or `PodMonitor` for
it, see [below](#kubernetes-helm-chart). Such a scrape reaches the pod over
plain http, past the ingress that terminates TLS, and the Production settings
redirect it to https like anything else — where it gets nothing. Set
`PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT=True` to take `/metrics` out of that
redirect, the way the probes are; the pod's own address is already in
`ALLOWED_HOSTS`. Leave it off wherever the application is reached directly,
without a proxy in front: the redirect is then what keeps the bearer token off
the wire in clear.
## Kubernetes (Helm chart)
```yaml
backend:
metrics:
enabled: true # PROMETHEUS_METRICS_ENABLED on the web pods, not on celery
envVars:
PROMETHEUS_METRICS_ENABLED: "True"
PROMETHEUS_API_KEY:
secretKeyRef:
name: backend
key: PROMETHEUS_API_KEY
yhub:
envVars:
PROMETHEUS_API_KEY: # the worker inherits it
secretKeyRef:
name: yhub
key: PROMETHEUS_API_KEY
metrics:
enabled: true # a port of its own, in the server and in the worker
```
`backend.metrics.enabled` sets `PROMETHEUS_METRICS_ENABLED` on the django
container only: the celery worker serves no request, so its metrics would never
be read. It sets `PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT` there too, since a pod
is only ever scraped over plain http. A value given in `backend.envVars` still
wins, and still reaches celery.
### Prometheus Operator, inside the cluster
```yaml
serviceMonitor:
enabled: true
labels:
release: kube-prometheus-stack # whatever your Prometheus selects monitors by
```
`serviceMonitor.enabled` (or `podMonitor.enabled`, or both) creates one monitor
per component whose metrics are enabled:
| Monitor | Scrapes | Port | Path | Job |
|---|---|---|---|---|
| `<release>-backend` | every backend web pod | `http` | `/metrics` | `backend` |
| `<release>-yhub` | every yhub server pod | `metrics` | `yhub.metrics.path` | `yhub` |
| `<release>-yhub-worker` | every yhub worker pod, when `yhub.worker.enabled` | `metrics` | `yhub.metrics.workerPath` | `yhub-worker` |
Each pod is a target of its own, so every sample of every replica is taken at
every interval, nothing goes through an ingress, and the `hostname` label is
simply the pod. The scrape presents the bearer token of the component, which
the Prometheus Operator reads from the Secret `PROMETHEUS_API_KEY` comes from
in the `envVars` above (or from the one named in `backend.metrics.apiKeySecret`
and `yhub.metrics.apiKeySecret`, for a token given as `PROMETHEUS_API_KEY_FILE`).
A token that is not in a Secret is refused at render time. That Secret has to
live in the namespace of the monitors, and the service account of the operator
be allowed to read it, as the kube-prometheus-stack one is.
A `ServiceMonitor` finds the pods through their Services, a `PodMonitor` through
their labels; they give the same targets. `interval`, `scrapeTimeout`,
`honorLabels`, `relabelings`, `metricRelabelings`, `labels`, `annotations` and
`namespace` are the same on both.
The dev cluster (`make start-tilt`, or `helmfile -e dev apply`) does exactly
this: its helmfile installs a trimmed
[kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack)
(`src/helm/env.d/dev/values.prometheus.yaml.gotmpl`: the operator, its CRDs
and one Prometheus, nothing else), the metrics of the backend and of yhub are
on with a token in the `docs-metrics` Secret, and `serviceMonitor.enabled`
builds the three monitors. The targets are at
https://docs-prometheus.127.0.0.1.nip.io/targets.
That Prometheus also serves the
[example console of django-prometheus](https://github.com/django-commons/django-prometheus/tree/master/examples/prometheus)
at https://docs-prometheus.127.0.0.1.nip.io/consoles/django.html: requests per
second, by view, median and tail latency, model writes and database queries,
drawn from its recording rules. Both files are in
`src/helm/env.d/dev/prometheus/`, the rules verbatim and the console with its
job renamed to `backend`. Console templates draw with the classic UI, which
Prometheus 3 removed, so the dev Prometheus is the last 2.x release.
### A Prometheus outside of the cluster
```yaml
backend:
envVars:
DJANGO_ALLOWED_HOSTS: docs.example.com,metrics.docs.example.com
ingressMetrics:
@@ -156,21 +244,9 @@ ingressMetrics:
```
`ingressMetrics` routes the exact path `/metrics` of that host to the backend
and nothing else. Its host has to be in `DJANGO_ALLOWED_HOSTS`.
With yhub, the same ingress also publishes the server and the worker, each on an
exact path of its own:
```yaml
yhub:
envVars:
PROMETHEUS_API_KEY: # the worker inherits it
secretKeyRef:
name: yhub
key: PROMETHEUS_API_KEY
metrics:
enabled: true # /metrics/yhub and /metrics/yhub-worker
```
and nothing else. Its host has to be in `DJANGO_ALLOWED_HOSTS`. With
`yhub.metrics.enabled`, the same ingress also publishes the server and the
worker, each on an exact path of its own:
| Path | Served by |
|---|---|
@@ -180,8 +256,5 @@ yhub:
That is three scrape jobs on one host, differing by `metrics_path`. What is said
above about [several replicas](#several-replicas-behind-one-address) applies to
each of them: yhub labels its samples with `hostname` too.
The celery worker receives `backend.envVars` too. It serves no request, so its
metrics are never read: turn them off there with
`backend.celery.envVars.PROMETHEUS_METRICS_ENABLED: "False"`.
each of them: yhub labels its samples with `hostname` too. Prefer the monitors
whenever the Prometheus can reach the pods.
@@ -14,6 +14,7 @@ from prometheus_client import REGISTRY, Counter, values
from rest_framework.test import APIClient
from impress import urls
from impress.settings import Production
pytestmark = pytest.mark.django_db
@@ -124,6 +125,38 @@ def test_prometheus_metrics_served_with_the_api_key():
assert not response.cookies
@pytest.mark.usefixtures("metrics_enabled")
def test_prometheus_metrics_redirected_to_https_by_default(settings):
"""
Where the application is reached directly, a scrape over plain http should be sent
to https like everything else: the bearer token must not travel in clear.
"""
settings.SECURE_SSL_REDIRECT = True
settings.SECURE_REDIRECT_EXEMPT = Production.SECURE_REDIRECT_EXEMPT
response = APIClient().get("/metrics", HTTP_AUTHORIZATION=f"Bearer {API_KEY}")
assert response.status_code == 301
assert response["Location"] == "https://testserver/metrics"
@pytest.mark.usefixtures("metrics_enabled")
def test_prometheus_metrics_exempt_from_the_ssl_redirect(settings):
"""
With PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT (what setup_prometheus_metrics adds to
the exemptions), a Prometheus reaching the pods over plain http should be served,
and every other path still sent to https.
"""
settings.SECURE_SSL_REDIRECT = True
settings.SECURE_REDIRECT_EXEMPT = [*Production.SECURE_REDIRECT_EXEMPT, "^metrics$"]
response = APIClient().get("/metrics", HTTP_AUTHORIZATION=f"Bearer {API_KEY}")
assert response.status_code == 200
response = APIClient().get("/api/v1.0/config/")
assert response.status_code == 301
@pytest.mark.usefixtures("metrics_enabled")
def test_prometheus_metrics_is_read_only():
"""Only GET and HEAD should be answered."""
+22 -1
View File
@@ -7,7 +7,7 @@ import tempfile
import pytest
from impress.settings import Base
from impress.settings import Base, Production
def test_invalid_settings_oidc_email_configuration():
@@ -89,6 +89,7 @@ def _prometheus_settings(**attributes):
"PROMETHEUS_API_KEY": "a-key",
"INSTALLED_APPS": list(Base.INSTALLED_APPS),
"MIDDLEWARE": list(Base.MIDDLEWARE),
"SECURE_REDIRECT_EXEMPT": list(Production.SECURE_REDIRECT_EXEMPT),
"DATABASES": {"default": {"ENGINE": "django.db.backends.postgresql"}},
**attributes,
},
@@ -167,6 +168,26 @@ def test_settings_prometheus_metrics_enabled(monkeypatch, tmp_path):
assert middleware.count(PROMETHEUS_AFTER_MIDDLEWARE) == 1
@pytest.mark.parametrize("exempt", [False, True])
def test_settings_prometheus_metrics_ssl_redirect_exempt(monkeypatch, tmp_path, exempt):
"""
/metrics should leave the redirect to https only when asked to, for a scraper that
reaches the process past the proxy terminating TLS, and the probes should stay.
"""
monkeypatch.setenv("PROMETHEUS_MULTIPROC_DIR", str(tmp_path))
test_settings = _prometheus_settings(PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT=exempt)
exemptions = test_settings.SECURE_REDIRECT_EXEMPT
test_settings.post_setup()
# twice: the pattern must not be added a second time
test_settings.post_setup()
# the very object Django was handed before post_setup ran
assert test_settings.SECURE_REDIRECT_EXEMPT is exemptions
expected = ["^__lbheartbeat__", "^__heartbeat__"]
assert exemptions == expected + (["^metrics$"] if exempt else [])
def test_settings_prometheus_multiproc_dir_default(monkeypatch, tmp_path):
"""
Without a directory, a fixed one should be used: every uvicorn worker computes it on
+27
View File
@@ -79,6 +79,9 @@ class Base(Configuration):
# Security
ALLOWED_HOSTS = values.ListValue([])
# Django's default, made explicit because setup_prometheus_metrics may add
# to it in place: Production redefines it with the probes
SECURE_REDIRECT_EXEMPT = []
SECRET_KEY = SecretFileValue(None)
SERVER_TO_SERVER_API_TOKENS = values.ListValue([])
@@ -1264,6 +1267,17 @@ class Base(Configuration):
PROMETHEUS_API_KEY = SecretFileValue(
None, environ_name="PROMETHEUS_API_KEY", environ_prefix=None
)
# Let /metrics be scraped over plain http where SECURE_SSL_REDIRECT is on,
# i.e. take it out of the redirect to https the way the probes are. For a
# scraper that reaches the process itself, past the proxy terminating TLS
# — a Prometheus inside a kubernetes cluster calling the pods. Leave it off
# when the application is reached directly: the redirect is then what keeps
# the bearer token off the wire in clear.
PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT = values.BooleanValue(
False,
environ_name="PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT",
environ_prefix=None,
)
# Also count and time the SQL queries, by swapping the database engine for
# django-prometheus' instrumented subclass of it.
PROMETHEUS_DB_METRICS_ENABLED = values.BooleanValue(
@@ -1371,6 +1385,16 @@ class Base(Configuration):
):
default_database["ENGINE"] = "django_prometheus.db.backends.postgresql"
# in place, like the lists above: a reassignment would go unseen. The
# path is core.middleware.METRICS_PATH, not imported here: the settings
# are read before the applications are.
metrics_pattern = "^metrics$"
if (
cls.PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT
and metrics_pattern not in cls.SECURE_REDIRECT_EXEMPT
):
cls.SECURE_REDIRECT_EXEMPT.append(metrics_pattern)
@classmethod
def post_setup(cls):
"""Post setup configuration.
@@ -1613,6 +1637,9 @@ class Production(Base):
SECURE_HSTS_PRELOAD = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_SSL_REDIRECT = True
# The probes are called on the process itself, over plain http: a redirect
# to https is a probe that fails. /metrics joins them only with
# PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT, see setup_prometheus_metrics
SECURE_REDIRECT_EXEMPT = [
"^__lbheartbeat__",
"^__heartbeat__",
+201
View File
@@ -0,0 +1,201 @@
{{/*
The example console of django-prometheus, from
https://github.com/django-commons/django-prometheus/blob/master/examples/prometheus/consoles/django.html
with two changes: the job is `backend` here (the ServiceMonitor names it after
the component), and the connection errors graph read a metric that does not
exist (`erros`). The graphs come from the recording rules of django.rules.
*/}}
{{template "head" .}}
{{template "prom_right_table_head"}}
<tr>
<th>Django</th>
<th>{{ template "prom_query_drilldown" (args "sum(up{job='backend'})") }}
/ {{ template "prom_query_drilldown" (args "count(up{job='backend'})") }}
</th>
</tr>
<tr>
<td>avg CPU</td>
<td>{{ template "prom_query_drilldown" (args "avg by(job)(rate(process_cpu_seconds_total{job='backend'}[5m]))" "s/s" "humanizeNoSmallPrefix") }}
</td>
</tr>
<tr>
<td>avg Memory</td>
<td>{{ template "prom_query_drilldown" (args "avg by(job)(process_resident_memory_bytes{job='backend'})" "B" "humanize1024") }}
</td>
</tr>
{{template "prom_right_table_tail"}}
{{template "prom_content_head" .}}
<h1>Django</h1>
<h2>Requests</h2>
<h3>Total</h3>
<div id="gr_requests_total"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_requests_total"),
expr: "job:django_http_requests_total:sum_rate30s",
name: "Requests",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Requests",
min: 0
})
</script>
<h3>By view</h3>
<div id="gr_requests_byview"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_requests_byview"),
expr: "job:django_http_requests_total_by_view:sum_rate30s",
name: "[[ view ]]",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Requests",
renderer: "area",
min: 0
})
</script>
<h3>Latency (median)</h3>
<div id="gr_requests_latency_median"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_requests_latency_median"),
expr: "job:django_http_requests_latency_seconds:quantile_rate30s{quantile=\"50\"}",
name: "median latency",
xUnits: "s",
yAxisFormatter: PromConsole.NumberFormatter.humanize,
yHoverFormatter: PromConsole.NumberFormatter.humanize,
yTitle: "s",
min: 0
})
</script>
<h3>Latency (99.9th percentile)</h3>
<div id="gr_requests_latency_tail"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_requests_latency_tail"),
expr: "job:django_http_requests_latency_seconds:quantile_rate30s{quantile=\"99.9\"}",
name: "tail latency",
xUnits: "s",
yAxisFormatter: PromConsole.NumberFormatter.humanize,
yHoverFormatter: PromConsole.NumberFormatter.humanize,
yTitle: "s",
min: 0
})
</script>
<h2>Models</h2>
<h3>Insertions/s</h3>
<div id="gr_model_inserts"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_model_inserts"),
expr: "job:django_model_inserts_total:sum_rate1m",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Insertions",
min: 0
})
</script>
<h3>Updates/s</h3>
<div id="gr_model_updates"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_model_updates"),
expr: "job:django_model_updates_total:sum_rate1m",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Updates",
min: 0
})
</script>
<h3>Deletions/s</h3>
<div id="gr_model_deletes"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_model_deletes"),
expr: "job:django_model_deletes_total:sum_rate1m",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Deletions",
min: 0
})
</script>
<h2>Database</h2>
<h3>Connections/s</h3>
<div id="gr_db_conn"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_db_conn"),
expr: "job:django_db_new_connections_total:sum_rate30s",
name: "[[ alias ]]/[[ vendor ]]",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Connections",
min: 0
})
</script>
<h3>Connections errors/s</h3>
<div id="gr_db_connerr"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_db_connerr"),
expr: "job:django_db_new_connection_errors_total:sum_rate30s",
name: "[[ alias ]]/[[ vendor ]]",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Connection errors",
min: 0
})
</script>
<h3>Queries/s</h3>
<div id="gr_db_execs"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_db_execs"),
expr: "job:django_db_execute_total:sum_rate30s",
name: "[[ alias ]]/[[ vendor ]]",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Queries",
min: 0
})
</script>
<h3>Errors/s</h3>
<div id="gr_db_errs"></div>
<script>
new PromConsole.Graph({
node: document.querySelector("#gr_db_errs"),
expr: "job:django_db_errors_total:sum_rate30s",
name: "[[ alias ]]/[[ vendor ]]",
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
yUnits: "/s",
yTitle: "Errors",
min: 0
})
</script>
{{template "prom_content_tail" .}}
{{template "tail"}}
+108
View File
@@ -0,0 +1,108 @@
# The example recording rules of django-prometheus, verbatim, from
# https://github.com/django-commons/django-prometheus/blob/master/examples/prometheus/django.rules
# They are what the graphs of django.html read.
groups:
- name: django.rules
rules:
- record: job:django_http_requests_before_middlewares_total:sum_rate30s
expr: sum(rate(django_http_requests_before_middlewares_total[30s])) BY (job)
- record: job:django_http_requests_unknown_latency_total:sum_rate30s
expr: sum(rate(django_http_requests_unknown_latency_total[30s])) BY (job)
- record: job:django_http_ajax_requests_total:sum_rate30s
expr: sum(rate(django_http_ajax_requests_total[30s])) BY (job)
- record: job:django_http_responses_before_middlewares_total:sum_rate30s
expr: sum(rate(django_http_responses_before_middlewares_total[30s])) BY (job)
- record: job:django_http_requests_unknown_latency_including_middlewares_total:sum_rate30s
expr: sum(rate(django_http_requests_unknown_latency_including_middlewares_total[30s]))
BY (job)
- record: job:django_http_requests_body_total_bytes:sum_rate30s
expr: sum(rate(django_http_requests_body_total_bytes[30s])) BY (job)
- record: job:django_http_responses_streaming_total:sum_rate30s
expr: sum(rate(django_http_responses_streaming_total[30s])) BY (job)
- record: job:django_http_responses_body_total_bytes:sum_rate30s
expr: sum(rate(django_http_responses_body_total_bytes[30s])) BY (job)
- record: job:django_http_requests_total:sum_rate30s
expr: sum(rate(django_http_requests_total_by_method[30s])) BY (job)
- record: job:django_http_requests_total_by_method:sum_rate30s
expr: sum(rate(django_http_requests_total_by_method[30s])) BY (job, method)
- record: job:django_http_requests_total_by_transport:sum_rate30s
expr: sum(rate(django_http_requests_total_by_transport[30s])) BY (job, transport)
- record: job:django_http_requests_total_by_view:sum_rate30s
expr: sum(rate(django_http_requests_total_by_view_transport_method[30s])) BY (job,
view)
- record: job:django_http_requests_total_by_view_transport_method:sum_rate30s
expr: sum(rate(django_http_requests_total_by_view_transport_method[30s])) BY (job,
view, transport, method)
- record: job:django_http_responses_total_by_templatename:sum_rate30s
expr: sum(rate(django_http_responses_total_by_templatename[30s])) BY (job, templatename)
- record: job:django_http_responses_total_by_status:sum_rate30s
expr: sum(rate(django_http_responses_total_by_status[30s])) BY (job, status)
- record: job:django_http_responses_total_by_status_name_method:sum_rate30s
expr: sum(rate(django_http_responses_total_by_status_name_method[30s])) BY (job,
status, name, method)
- record: job:django_http_responses_total_by_charset:sum_rate30s
expr: sum(rate(django_http_responses_total_by_charset[30s])) BY (job, charset)
- record: job:django_http_exceptions_total_by_type:sum_rate30s
expr: sum(rate(django_http_exceptions_total_by_type[30s])) BY (job, type)
- record: job:django_http_exceptions_total_by_view:sum_rate30s
expr: sum(rate(django_http_exceptions_total_by_view[30s])) BY (job, view)
- record: job:django_http_requests_latency_including_middlewares_seconds:quantile_rate30s
expr: histogram_quantile(0.5, sum(rate(django_http_requests_latency_including_middlewares_seconds_bucket[30s]))
BY (job, le))
labels:
quantile: "50"
- record: job:django_http_requests_latency_including_middlewares_seconds:quantile_rate30s
expr: histogram_quantile(0.95, sum(rate(django_http_requests_latency_including_middlewares_seconds_bucket[30s]))
BY (job, le))
labels:
quantile: "95"
- record: job:django_http_requests_latency_including_middlewares_seconds:quantile_rate30s
expr: histogram_quantile(0.99, sum(rate(django_http_requests_latency_including_middlewares_seconds_bucket[30s]))
BY (job, le))
labels:
quantile: "99"
- record: job:django_http_requests_latency_including_middlewares_seconds:quantile_rate30s
expr: histogram_quantile(0.999, sum(rate(django_http_requests_latency_including_middlewares_seconds_bucket[30s]))
BY (job, le))
labels:
quantile: "99.9"
- record: job:django_http_requests_latency_seconds:quantile_rate30s
expr: histogram_quantile(0.5, sum(rate(django_http_requests_latency_seconds_bucket[30s]))
BY (job, le))
labels:
quantile: "50"
- record: job:django_http_requests_latency_seconds:quantile_rate30s
expr: histogram_quantile(0.95, sum(rate(django_http_requests_latency_seconds_bucket[30s]))
BY (job, le))
labels:
quantile: "95"
- record: job:django_http_requests_latency_seconds:quantile_rate30s
expr: histogram_quantile(0.99, sum(rate(django_http_requests_latency_seconds_bucket[30s]))
BY (job, le))
labels:
quantile: "99"
- record: job:django_http_requests_latency_seconds:quantile_rate30s
expr: histogram_quantile(0.999, sum(rate(django_http_requests_latency_seconds_bucket[30s]))
BY (job, le))
labels:
quantile: "99.9"
- record: job:django_model_inserts_total:sum_rate1m
expr: sum(rate(django_model_inserts_total[1m])) BY (job, model)
- record: job:django_model_updates_total:sum_rate1m
expr: sum(rate(django_model_updates_total[1m])) BY (job, model)
- record: job:django_model_deletes_total:sum_rate1m
expr: sum(rate(django_model_deletes_total[1m])) BY (job, model)
- record: job:django_db_new_connections_total:sum_rate30s
expr: sum(rate(django_db_new_connections_total[30s])) BY (alias, vendor)
- record: job:django_db_new_connection_errors_total:sum_rate30s
expr: sum(rate(django_db_new_connection_errors_total[30s])) BY (alias, vendor)
- record: job:django_db_execute_total:sum_rate30s
expr: sum(rate(django_db_execute_total[30s])) BY (alias, vendor)
- record: job:django_db_execute_many_total:sum_rate30s
expr: sum(rate(django_db_execute_many_total[30s])) BY (alias, vendor)
- record: job:django_db_errors_total:sum_rate30s
expr: sum(rate(django_db_errors_total[30s])) BY (alias, vendor, type)
- record: job:django_migrations_applied_total:max
expr: max(django_migrations_applied_total) BY (job, connection)
- record: job:django_migrations_unapplied_total:max
expr: max(django_migrations_unapplied_total) BY (job, connection)
@@ -14,7 +14,14 @@ image:
backend:
replicas: 1
# scraped by the Prometheus of the cluster, see serviceMonitor below
metrics:
enabled: true
envVars:
PROMETHEUS_API_KEY:
secretKeyRef:
name: docs-metrics
key: PROMETHEUS_API_KEY
CONVERSION_UPLOAD_ENABLED: True
DJANGO_CSRF_TRUSTED_ORIGINS: https://docs.127.0.0.1.nip.io
DJANGO_CONFIGURATION: Feature
@@ -203,6 +210,11 @@ yhub:
enabled: true
replicas: 2
# scraped by the Prometheus of the cluster, server and worker apart, see
# serviceMonitor below
metrics:
enabled: true
image:
repository: localhost:5001/impress-yhub
pullPolicy: Always
@@ -216,6 +228,10 @@ yhub:
# valkey-docs
REDIS: redis://default:pass@valkey-yhub:6379/0
REDIS_PREFIX: yhub
PROMETHEUS_API_KEY:
secretKeyRef:
name: docs-metrics
key: PROMETHEUS_API_KEY
COLLABORATION_BACKEND_BASE_URL: https://docs.127.0.0.1.nip.io
COLLABORATION_SERVER_ORIGIN: https://docs.127.0.0.1.nip.io
NODE_EXTRA_CA_CERTS: /cert/cacert.pem
@@ -295,3 +311,11 @@ ingressMedia:
serviceMedia:
host: dev-backend-minio.impress.svc.cluster.local
port: 9000
# One ServiceMonitor per component whose metrics are enabled above — backend,
# yhub, yhub-worker — for the Prometheus of the prometheus release
# (values.prometheus.yaml.gotmpl), which selects every monitor of the
# namespace. The docs-metrics Secret the scrapes present is created there too.
serviceMonitor:
enabled: true
interval: 15s
@@ -0,0 +1,129 @@
# A Prometheus scraping the dev cluster, to see the metrics of the backend and
# of yhub through the ServiceMonitors the impress chart builds. Trimmed down to
# the Prometheus Operator, its CRDs and one Prometheus: no Grafana, no
# Alertmanager, no exporter, and none of the monitors and rules of the
# kubernetes control plane, which a kind cluster has nothing to show for.
# UI: https://docs-prometheus.127.0.0.1.nip.io (Status > Targets lists the pods)
#
# It also serves the example console of django-prometheus, the graphs of
# https://docs-prometheus.127.0.0.1.nip.io/consoles/django.html, fed by its
# recording rules: both are in the prometheus/ directory next to this file.
# Console templates draw with the classic UI, which Prometheus 3 removed along
# with the console libraries, so this Prometheus is the last 2.x release.
fullnameOverride: prometheus
defaultRules:
create: false
alertmanager:
enabled: false
grafana:
enabled: false
nodeExporter:
enabled: false
kubeStateMetrics:
enabled: false
kubernetesServiceMonitors:
enabled: false
kubeApiServer:
enabled: false
kubelet:
enabled: false
kubeControllerManager:
enabled: false
coreDns:
enabled: false
kubeDns:
enabled: false
kubeEtcd:
enabled: false
kubeScheduler:
enabled: false
kubeProxy:
enabled: false
prometheusOperator:
# the webhooks validate the monitors and rules: not worth the certificate
# patch jobs in a dev cluster
admissionWebhooks:
enabled: false
tls:
enabled: false
kubeletService:
enabled: false
serviceMonitor:
selfMonitor: false
prometheus:
serviceMonitor:
selfMonitor: false
prometheusSpec:
image:
tag: v2.55.1
# the console, in the directory the operator points --web.console.templates
# at (/etc/prometheus/consoles is a symlink to it in the image). Only the
# console libraries of the image are left next to it, which is all it needs
volumes:
- name: django-console
configMap:
name: django-console
volumeMounts:
- name: django-console
mountPath: /usr/share/prometheus/consoles
readOnly: true
# every ServiceMonitor and PodMonitor of the namespace, whatever its labels
serviceMonitorSelectorNilUsesHelmValues: false
podMonitorSelectorNilUsesHelmValues: false
ruleSelectorNilUsesHelmValues: false
probeSelectorNilUsesHelmValues: false
scrapeConfigSelectorNilUsesHelmValues: false
scrapeInterval: 15s
retention: 2d
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
memory: 1Gi
ingress:
enabled: true
hosts:
- docs-prometheus.127.0.0.1.nip.io
paths:
- /
pathType: Prefix
tls:
- secretName: docs-tls
hosts:
- docs-prometheus.127.0.0.1.nip.io
# The bearer token the backend and yhub check on their metrics endpoints, and
# the Prometheus Operator reads to scrape them with (values.impress: the
# PROMETHEUS_API_KEY of both, and the monitors). A Secret of the release that
# needs it first, dev only: a real deployment keeps it with its other secrets.
extraManifests:
- apiVersion: v1
kind: Secret
metadata:
name: docs-metrics
stringData:
PROMETHEUS_API_KEY: ThisIsAnExampleMetricsTokenForDevPurposeOnly
# The recording rules the console reads, selected like the monitors are
- apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: django
spec:
{{- readFile "prometheus/django.rules" | nindent 6 }}
# The console itself. The chart passes every extra manifest through helm's
# tpl, which would render the actions of the console template: each opening
# delimiter is escaped so that tpl writes it back as is (the closing one is
# spelled in two halves so that it does not end this action)
{{- $open := "{{" }}
{{- $escaped := printf "%s %q %s" $open $open (print "}" "}") }}
- apiVersion: v1
kind: ConfigMap
metadata:
name: django-console
data:
django.html: |
{{- readFile "prometheus/django.html" | replace $open $escaped | nindent 8 }}
+20 -1
View File
@@ -1,7 +1,9 @@
environments:
dev:
values:
- version: 6.0.0-alpha.1
- version: 6.0.0-alpha.2
# a Prometheus scraping the metrics of the backend and of yhub
monitoring: true
feature:
values:
- version: 6.0.0-alpha.1
@@ -14,6 +16,8 @@ repositories:
url: https://suitenumerique.github.io/helm-dev-backend
- name: valkey
url: https://valkey.io/valkey-helm/
- name: prometheus-community
url: https://prometheus-community.github.io/helm-charts
---
releases:
@@ -40,9 +44,24 @@ releases:
values:
- env.d/{{ .Environment.Name }}/values.valkey.yaml.gotmpl
# The Prometheus Operator and a Prometheus, in the environments that ask for
# it: what the ServiceMonitors of the impress release are for
- name: prometheus
namespace: {{ .Namespace }}
chart: prometheus-community/kube-prometheus-stack
version: 91.4.1
installed: {{ .Values | get "monitoring" false }}
values:
- env.d/{{ .Environment.Name }}/values.prometheus.yaml.gotmpl
- name: impress
version: {{ .Values.version }}
namespace: {{ .Namespace }}
chart: ./impress
{{- if .Values | get "monitoring" false }}
# its ServiceMonitors need the CRDs of the operator
needs:
- {{ .Namespace }}/prometheus
{{- end }}
values:
- env.d/{{ .Environment.Name }}/values.impress.yaml.gotmpl
+1 -1
View File
@@ -1,5 +1,5 @@
apiVersion: v2
type: application
name: docs
version: 6.0.0-alpha.1
version: 6.0.0-alpha.2
appVersion: latest
+362 -339
View File
@@ -4,229 +4,250 @@
### General configuration
| Name | Description | Value |
| ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `image.repository` | Repository to use to pull impress's container image | `lasuite/impress-backend` |
| `image.tag` | impress's container tag | `latest` |
| `image.pullPolicy` | Container image pull policy | `IfNotPresent` |
| `image.credentials.username` | Username for container registry authentication | |
| `image.credentials.password` | Password for container registry authentication | |
| `image.credentials.registry` | Registry url for which the credentials are specified | |
| `image.credentials.name` | Name of the generated secret for imagePullSecrets | |
| `nameOverride` | Override the chart name | `""` |
| `fullnameOverride` | Override the full application name | `""` |
| `ingress.enabled` | whether to enable the Ingress or not | `false` |
| `ingress.className` | IngressClass to use for the Ingress | `nil` |
| `ingress.host` | Host for the Ingress | `impress.example.com` |
| `ingress.path` | Path to use for the Ingress | `/` |
| `ingress.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingress.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingress.tls.secretName` | Secret name for TLS config | `nil` |
| `ingress.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingress.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingress.customBackends` | Add custom backends to ingress | `[]` |
| `ingressCollaborationWS.enabled` | whether to enable the Ingress or not | `false` |
| `ingressCollaborationWS.className` | IngressClass to use for the Ingress | `nil` |
| `ingressCollaborationWS.host` | Host for the Ingress | `impress.example.com` |
| `ingressCollaborationWS.path` | Path to use for the Ingress | `/collaboration/ws/` |
| `ingressCollaborationWS.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressCollaborationWS.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressCollaborationWS.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressCollaborationWS.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressCollaborationWS.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressCollaborationWS.customBackends` | Add custom backends to ingress | `[]` |
| `ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/enable-websocket` | | `true` |
| `ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/proxy-read-timeout` | | `86400` |
| `ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/proxy-send-timeout` | | `86400` |
| `ingressRedirects.enabled` | whether to enable the Ingress Redirects or not | `false` |
| `ingressRedirects.className` | IngressClass to use for the Ingress Redirects | `nil` |
| `ingressRedirects.host` | Host for the Ingress Redirects | `impress.example.com` |
| `ingressRedirects.tls.enabled` | Whether to enable TLS for the Ingress Redirects | `true` |
| `ingressRedirects.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressRedirects.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressRedirects.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressRedirects.rules` | Rules for the Ingress Redirects | `[]` |
| `ingressCollaborationApi.enabled` | whether to enable the Ingress or not | `false` |
| `ingressCollaborationApi.className` | IngressClass to use for the Ingress | `nil` |
| `ingressCollaborationApi.host` | Host for the Ingress | `impress.example.com` |
| `ingressCollaborationApi.path` | Path to use for the Ingress | `/collaboration/api/` |
| `ingressCollaborationApi.paths` | Paths to route to the collaboration server, one rule each | `["/collaboration/ydoc/","/collaboration/jwks/"]` |
| `ingressCollaborationApi.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressCollaborationApi.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressCollaborationApi.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressCollaborationApi.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressCollaborationApi.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressCollaborationApi.customBackends` | Add custom backends to ingress | `[]` |
| `ingressAdmin.enabled` | whether to enable the Ingress or not | `false` |
| `ingressAdmin.className` | IngressClass to use for the Ingress | `nil` |
| `ingressAdmin.host` | Host for the Ingress | `impress.example.com` |
| `ingressAdmin.path` | Path to use for the Ingress | `/admin` |
| `ingressAdmin.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressAdmin.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressAdmin.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressAdmin.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressAdmin.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressMetrics.enabled` | whether to enable the Ingress publishing the Prometheus metrics of the backend (requires PROMETHEUS_METRICS_ENABLED and PROMETHEUS_API_KEY in backend.envVars) and, with yhub.metrics.enabled, those of yhub | `false` |
| `ingressMetrics.className` | IngressClass to use for the Ingress | `nil` |
| `ingressMetrics.host` | Host for the Ingress. Use a host of its own, and add it to DJANGO_ALLOWED_HOSTS | `metrics.impress.example.com` |
| `ingressMetrics.path` | Path of the backend metrics, matched exactly. The yhub ones are published at yhub.metrics.path and yhub.metrics.workerPath | `/metrics` |
| `ingressMetrics.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressMetrics.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressMetrics.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressMetrics.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressMetrics.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressMetrics.annotations` | Annotations of the Ingress. Restrict the callers by address here | `{}` |
| `ingressMedia.enabled` | whether to enable the Ingress or not | `false` |
| `ingressMedia.className` | IngressClass to use for the Ingress | `nil` |
| `ingressMedia.host` | Host for the Ingress | `impress.example.com` |
| `ingressMedia.path` | Path to use for the Ingress | `/media/(.*)` |
| `ingressMedia.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressMedia.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressMedia.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressMedia.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressMedia.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/auth-url` | | `https://impress.example.com/api/v1.0/documents/media-auth/` |
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/auth-response-headers` | | `Authorization, X-Amz-Date, X-Amz-Content-SHA256` |
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/upstream-vhost` | | `minio.impress.svc.cluster.local:9000` |
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/configuration-snippet` | | `add_header Content-Security-Policy "default-src 'none'" always;
` |
| `serviceMedia.host` | Hostname of the media storage backend (S3/MinIO) used by the media ingress | `minio.impress.svc.cluster.local` |
| `serviceMedia.port` | Port of the media storage backend | `9000` |
| `serviceMedia.annotations` | Annotations to add to the media ExternalName Service | `{}` |
| Name | Description | Value |
| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `image.repository` | Repository to use to pull impress's container image | `lasuite/impress-backend` |
| `image.tag` | impress's container tag | `latest` |
| `image.pullPolicy` | Container image pull policy | `IfNotPresent` |
| `image.credentials.username` | Username for container registry authentication | |
| `image.credentials.password` | Password for container registry authentication | |
| `image.credentials.registry` | Registry url for which the credentials are specified | |
| `image.credentials.name` | Name of the generated secret for imagePullSecrets | |
| `nameOverride` | Override the chart name | `""` |
| `fullnameOverride` | Override the full application name | `""` |
| `ingress.enabled` | whether to enable the Ingress or not | `false` |
| `ingress.className` | IngressClass to use for the Ingress | `nil` |
| `ingress.host` | Host for the Ingress | `impress.example.com` |
| `ingress.path` | Path to use for the Ingress | `/` |
| `ingress.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingress.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingress.tls.secretName` | Secret name for TLS config | `nil` |
| `ingress.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingress.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingress.customBackends` | Add custom backends to ingress | `[]` |
| `ingressCollaborationWS.enabled` | whether to enable the Ingress or not | `false` |
| `ingressCollaborationWS.className` | IngressClass to use for the Ingress | `nil` |
| `ingressCollaborationWS.host` | Host for the Ingress | `impress.example.com` |
| `ingressCollaborationWS.path` | Path to use for the Ingress | `/collaboration/ws/` |
| `ingressCollaborationWS.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressCollaborationWS.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressCollaborationWS.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressCollaborationWS.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressCollaborationWS.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressCollaborationWS.customBackends` | Add custom backends to ingress | `[]` |
| `ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/enable-websocket` | | `true` |
| `ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/proxy-read-timeout` | | `86400` |
| `ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/proxy-send-timeout` | | `86400` |
| `ingressRedirects.enabled` | whether to enable the Ingress Redirects or not | `false` |
| `ingressRedirects.className` | IngressClass to use for the Ingress Redirects | `nil` |
| `ingressRedirects.host` | Host for the Ingress Redirects | `impress.example.com` |
| `ingressRedirects.tls.enabled` | Whether to enable TLS for the Ingress Redirects | `true` |
| `ingressRedirects.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressRedirects.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressRedirects.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressRedirects.rules` | Rules for the Ingress Redirects | `[]` |
| `ingressCollaborationApi.enabled` | whether to enable the Ingress or not | `false` |
| `ingressCollaborationApi.className` | IngressClass to use for the Ingress | `nil` |
| `ingressCollaborationApi.host` | Host for the Ingress | `impress.example.com` |
| `ingressCollaborationApi.path` | Path to use for the Ingress | `/collaboration/api/` |
| `ingressCollaborationApi.paths` | Paths to route to the collaboration server, one rule each | `["/collaboration/ydoc/","/collaboration/activity/","/collaboration/changeset/","/collaboration/rollback/","/collaboration/jwks/"]` |
| `ingressCollaborationApi.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressCollaborationApi.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressCollaborationApi.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressCollaborationApi.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressCollaborationApi.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressCollaborationApi.customBackends` | Add custom backends to ingress | `[]` |
| `ingressAdmin.enabled` | whether to enable the Ingress or not | `false` |
| `ingressAdmin.className` | IngressClass to use for the Ingress | `nil` |
| `ingressAdmin.host` | Host for the Ingress | `impress.example.com` |
| `ingressAdmin.path` | Path to use for the Ingress | `/admin` |
| `ingressAdmin.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressAdmin.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressAdmin.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressAdmin.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressAdmin.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressMetrics.enabled` | whether to enable the Ingress publishing the Prometheus metrics of the backend (backend.metrics.enabled) and of yhub (yhub.metrics.enabled) to a Prometheus outside of the cluster. One inside it scrapes the pods directly with serviceMonitor or podMonitor instead | `false` |
| `ingressMetrics.className` | IngressClass to use for the Ingress | `nil` |
| `ingressMetrics.host` | Host for the Ingress. Use a host of its own, and add it to DJANGO_ALLOWED_HOSTS | `metrics.impress.example.com` |
| `ingressMetrics.path` | Path of the backend metrics, matched exactly. The yhub ones are published at yhub.metrics.path and yhub.metrics.workerPath | `/metrics` |
| `ingressMetrics.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressMetrics.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressMetrics.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressMetrics.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressMetrics.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressMetrics.annotations` | Annotations of the Ingress. Restrict the callers by address here | `{}` |
| `serviceMonitor.enabled` | Create a ServiceMonitor for each component whose metrics are enabled | `false` |
| `serviceMonitor.namespace` | Namespace the ServiceMonitors are created in, the release one when empty | `""` |
| `serviceMonitor.labels` | Labels of the ServiceMonitors, which the Prometheus Operator selects them by (e.g. release: kube-prometheus-stack) | `{}` |
| `serviceMonitor.annotations` | Annotations of the ServiceMonitors | `{}` |
| `serviceMonitor.interval` | Scrape interval, the Prometheus default when empty | `""` |
| `serviceMonitor.scrapeTimeout` | Scrape timeout, the Prometheus default when empty | `""` |
| `serviceMonitor.honorLabels` | Keep the labels of the scraped samples when they clash with the target ones | `false` |
| `serviceMonitor.relabelings` | Relabelings of the targets, before the scrape | `[]` |
| `serviceMonitor.metricRelabelings` | Relabelings of the samples, after the scrape | `[]` |
| `podMonitor.enabled` | Create a PodMonitor for each component whose metrics are enabled | `false` |
| `podMonitor.namespace` | Namespace the PodMonitors are created in, the release one when empty | `""` |
| `podMonitor.labels` | Labels of the PodMonitors, which the Prometheus Operator selects them by (e.g. release: kube-prometheus-stack) | `{}` |
| `podMonitor.annotations` | Annotations of the PodMonitors | `{}` |
| `podMonitor.interval` | Scrape interval, the Prometheus default when empty | `""` |
| `podMonitor.scrapeTimeout` | Scrape timeout, the Prometheus default when empty | `""` |
| `podMonitor.honorLabels` | Keep the labels of the scraped samples when they clash with the target ones | `false` |
| `podMonitor.relabelings` | Relabelings of the targets, before the scrape | `[]` |
| `podMonitor.metricRelabelings` | Relabelings of the samples, after the scrape | `[]` |
| `ingressMedia.enabled` | whether to enable the Ingress or not | `false` |
| `ingressMedia.className` | IngressClass to use for the Ingress | `nil` |
| `ingressMedia.host` | Host for the Ingress | `impress.example.com` |
| `ingressMedia.path` | Path to use for the Ingress | `/media/(.*)` |
| `ingressMedia.hosts` | Additional host to configure for the Ingress | `[]` |
| `ingressMedia.tls.enabled` | Whether to enable TLS for the Ingress | `true` |
| `ingressMedia.tls.secretName` | Secret name for TLS config | `nil` |
| `ingressMedia.tls.additional[].secretName` | Secret name for additional TLS config | |
| `ingressMedia.tls.additional[].hosts[]` | Hosts for additional TLS config | |
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/auth-url` | | `https://impress.example.com/api/v1.0/documents/media-auth/` |
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/auth-response-headers` | | `Authorization, X-Amz-Date, X-Amz-Content-SHA256` |
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/upstream-vhost` | | `minio.impress.svc.cluster.local:9000` |
| `ingressMedia.annotations.nginx.ingress.kubernetes.io/configuration-snippet` | | `add_header Content-Security-Policy "default-src 'none'" always;
` |
| `serviceMedia.host` | Hostname of the media storage backend (S3/MinIO) used by the media ingress | `minio.impress.svc.cluster.local` |
| `serviceMedia.port` | Port of the media storage backend | `9000` |
| `serviceMedia.annotations` | Annotations to add to the media ExternalName Service | `{}` |
### backend
| Name | Description | Value |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `backend.command` | Override the backend container command | `[]` |
| `backend.args` | Override the backend container args | `[]` |
| `backend.replicas` | Amount of backend replicas | `3` |
| `backend.shareProcessNamespace` | Enable share process namespace between containers | `false` |
| `backend.sidecars` | Add sidecars containers to backend deployment | `[]` |
| `backend.migrateJobAnnotations` | Annotations for the migrate job | `{}` |
| `backend.jobs.ttlSecondsAfterFinished` | Period to wait before remove jobs | `30` |
| `backend.jobs.backoffLimit` | Numbers of jobs retries | `2` |
| `backend.securityContext.allowPrivilegeEscalation` | Whether to allow privilege escalation for the backend container | `false` |
| `backend.securityContext.capabilities.drop` | List of capabilities to drop for the backend container | `["ALL"]` |
| `backend.securityContext.runAsNonRoot` | Whether to run the backend container as a non-root user | `true` |
| `backend.securityContext.seccompProfile.type` | Seccomp profile type for the backend container | `RuntimeDefault` |
| `backend.envVars` | Configure backend container environment variables | `undefined` |
| `backend.envVars.BY_VALUE` | Example environment variable by setting value directly | |
| `backend.envVars.FROM_CONFIGMAP.configMapKeyRef.name` | Name of a ConfigMap when configuring env vars from a ConfigMap | |
| `backend.envVars.FROM_CONFIGMAP.configMapKeyRef.key` | Key within a ConfigMap when configuring env vars from a ConfigMap | |
| `backend.envVars.FROM_SECRET.secretKeyRef.name` | Name of a Secret when configuring env vars from a Secret | |
| `backend.envVars.FROM_SECRET.secretKeyRef.key` | Key within a Secret when configuring env vars from a Secret | |
| `backend.django.envVars` | Backend web deployment specific environment variables (not shared with celery worker) | |
| `backend.podAnnotations` | Annotations to add to the backend Pod | `{}` |
| `backend.dpAnnotations` | Annotations to add to the backend Deployment | `{}` |
| `backend.service.type` | backend Service type | `ClusterIP` |
| `backend.service.port` | backend Service listening port | `80` |
| `backend.service.targetPort` | backend container listening port | `8000` |
| `backend.service.annotations` | Annotations to add to the backend Service | `{}` |
| `backend.migrate.command` | backend migrate command | `["/bin/sh","-c","attempt=0\nuntil output=$(python manage.py check --database default 2>&1)\ndo\n attempt=$((attempt + 1))\n echo \"Database check failed (attempt $attempt), retrying in 2s:\"\n echo \"$output\"\n sleep 2\ndone\n\necho \"Database is ready\"\n\npython manage.py migrate --no-input\n"]` |
| `backend.migrate.restartPolicy` | backend migrate job restart policy | `Never` |
| `backend.createsuperuser.command` | backend migrate command | `["/bin/sh","-c","attempt=0\nuntil output=$(python manage.py check --database default 2>&1)\ndo\n attempt=$((attempt + 1))\n echo \"Database check failed (attempt $attempt), retrying in 2s:\"\n echo \"$output\"\n sleep 2\ndone\n\necho \"Database is ready\"\n\npython manage.py createsuperuser --email $DJANGO_SUPERUSER_EMAIL --password $DJANGO_SUPERUSER_PASSWORD\n"]` |
| `backend.createsuperuser.restartPolicy` | backend migrate job restart policy | `Never` |
| `backend.job` | job dedicated to run a random management command, for example after a deployment | |
| `backend.job.name` | The name to use to describe this job | `""` |
| `backend.job.command` | The management command to execute | `[]` |
| `backend.job.restartPolicy` | The restart policy for the job. | `Never` |
| `backend.job.annotations` | Annotations to add to the job [default: argocd.argoproj.io/hook: PostSync] | |
| `backend.cronjobs` | Cronjob name, schedule, command | `[]` |
| `backend.probes.liveness.path` | Configure path for backend HTTP liveness probe | `/__lbheartbeat__` |
| `backend.probes.liveness.targetPort` | Configure port for backend HTTP liveness probe | `nil` |
| `backend.probes.liveness.initialDelaySeconds` | Configure initial delay for backend liveness probe | `10` |
| `backend.probes.liveness.timeoutSeconds` | Configure timeout for backend liveness probe | `nil` |
| `backend.probes.startup.path` | Configure path for backend HTTP startup probe | |
| `backend.probes.startup.targetPort` | Configure port for backend HTTP startup probe | |
| `backend.probes.startup.initialDelaySeconds` | Configure initial delay for backend startup probe | |
| `backend.probes.startup.timeoutSeconds` | Configure timeout for backend startup probe | |
| `backend.probes.readiness.path` | Configure path for backend HTTP readiness probe | `/__heartbeat__` |
| `backend.probes.readiness.targetPort` | Configure port for backend HTTP readiness probe | `nil` |
| `backend.probes.readiness.initialDelaySeconds` | Configure initial delay for backend readiness probe | `10` |
| `backend.probes.readiness.timeoutSeconds` | Configure timeout for backend readiness probe | `nil` |
| `backend.resources` | Resource requirements for the backend container | `{}` |
| `backend.nodeSelector` | Node selector for the backend Pod | `{}` |
| `backend.tolerations` | Tolerations for the backend Pod | `[]` |
| `backend.affinity` | Affinity for the backend Pod | `{}` |
| `backend.persistence` | Additional volumes to create and mount on the backend. Used for debugging purposes | `{}` |
| `backend.persistence.volume-name.size` | Size of the additional volume | |
| `backend.persistence.volume-name.type` | Type of the additional volume, persistentVolumeClaim or emptyDir | |
| `backend.persistence.volume-name.mountPath` | Path where the volume should be mounted to | |
| `backend.extraVolumeMounts` | Additional volumes to mount on the backend. | `[]` |
| `backend.extraVolumes` | Additional volumes to mount on the backend. | `[]` |
| `backend.pdb.enabled` | Enable pdb on backend | `true` |
| `backend.serviceAccountName` | Optional service account name to use for backend pods | `nil` |
| `backend.themeCustomization.enabled` | Enable theme customization | `false` |
| `backend.themeCustomization.file_content` | Content of the theme customization file. Must be a json object. | `""` |
| `backend.themeCustomization.mount_path` | Path where the customization file will be mounted in the backend deployment. | `/app/impress/configuration/theme` |
| `backend.celery.replicas` | Amount of celery replicas | `1` |
| `backend.celery.command` | Override the celery container command | `[]` |
| `backend.celery.args` | Override the celery container args | `["celery","-A","impress.celery_app","worker","-l","INFO","-n","impress@%h"]` |
| `backend.celery.resources` | Resource requirements for the celery container | `{}` |
| `backend.celery.probes.liveness.exec.command` | Override the celery container liveness probe command | `["/bin/sh","-c","celery -A impress.celery_app inspect ping -d impress@$HOSTNAME"]` |
| `backend.celery.probes.liveness.initialDelaySeconds` | Initial delay for the celery container liveness probe | `60` |
| `backend.celery.probes.liveness.timeoutSeconds` | Timeout for the celery container liveness probe | `5` |
| `backend.celery.probes.readiness.exec.command` | Override the celery container readiness probe command | `["/bin/sh","-c","celery -A impress.celery_app inspect ping -d impress@$HOSTNAME"]` |
| `backend.celery.probes.readiness.initialDelaySeconds` | Initial delay for the celery container readiness probe | `15` |
| `backend.celery.probes.readiness.timeoutSeconds` | Timeout for the celery container readiness probe | `5` |
| `backend.celery.envVars` | Celery worker specific environment variables (not shared with the backend web deployment) | |
| Name | Description | Value |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `backend.command` | Override the backend container command | `[]` |
| `backend.args` | Override the backend container args | `[]` |
| `backend.replicas` | Amount of backend replicas | `3` |
| `backend.shareProcessNamespace` | Enable share process namespace between containers | `false` |
| `backend.sidecars` | Add sidecars containers to backend deployment | `[]` |
| `backend.migrateJobAnnotations` | Annotations for the migrate job | `{}` |
| `backend.jobs.ttlSecondsAfterFinished` | Period to wait before remove jobs | `30` |
| `backend.jobs.backoffLimit` | Numbers of jobs retries | `2` |
| `backend.securityContext.allowPrivilegeEscalation` | Whether to allow privilege escalation for the backend container | `false` |
| `backend.securityContext.capabilities.drop` | List of capabilities to drop for the backend container | `["ALL"]` |
| `backend.securityContext.runAsNonRoot` | Whether to run the backend container as a non-root user | `true` |
| `backend.securityContext.seccompProfile.type` | Seccomp profile type for the backend container | `RuntimeDefault` |
| `backend.envVars` | Configure backend container environment variables | `undefined` |
| `backend.envVars.BY_VALUE` | Example environment variable by setting value directly | |
| `backend.envVars.FROM_CONFIGMAP.configMapKeyRef.name` | Name of a ConfigMap when configuring env vars from a ConfigMap | |
| `backend.envVars.FROM_CONFIGMAP.configMapKeyRef.key` | Key within a ConfigMap when configuring env vars from a ConfigMap | |
| `backend.envVars.FROM_SECRET.secretKeyRef.name` | Name of a Secret when configuring env vars from a Secret | |
| `backend.envVars.FROM_SECRET.secretKeyRef.key` | Key within a Secret when configuring env vars from a Secret | |
| `backend.django.envVars` | Backend web deployment specific environment variables (not shared with celery worker) | |
| `backend.metrics.enabled` | Serve the prometheus metrics of the backend on /metrics of the web pods, scraped over plain http inside the cluster. Sets PROMETHEUS_METRICS_ENABLED and PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT on the django container, and not on celery, unless backend.envVars sets them. Requires PROMETHEUS_API_KEY in backend.envVars | `false` |
| `backend.metrics.apiKeySecret.name` | Secret the monitors read the bearer token from. Defaults to the secretKeyRef of backend.envVars.PROMETHEUS_API_KEY | `""` |
| `backend.metrics.apiKeySecret.key` | Key of the bearer token in that Secret | `""` |
| `backend.podAnnotations` | Annotations to add to the backend Pod | `{}` |
| `backend.dpAnnotations` | Annotations to add to the backend Deployment | `{}` |
| `backend.service.type` | backend Service type | `ClusterIP` |
| `backend.service.port` | backend Service listening port | `80` |
| `backend.service.targetPort` | backend container listening port | `8000` |
| `backend.service.annotations` | Annotations to add to the backend Service | `{}` |
| `backend.migrate.command` | backend migrate command | `["/bin/sh","-c","attempt=0\nuntil output=$(python manage.py check --database default 2>&1)\ndo\n attempt=$((attempt + 1))\n echo \"Database check failed (attempt $attempt), retrying in 2s:\"\n echo \"$output\"\n sleep 2\ndone\n\necho \"Database is ready\"\n\npython manage.py migrate --no-input\n"]` |
| `backend.migrate.restartPolicy` | backend migrate job restart policy | `Never` |
| `backend.createsuperuser.command` | backend migrate command | `["/bin/sh","-c","attempt=0\nuntil output=$(python manage.py check --database default 2>&1)\ndo\n attempt=$((attempt + 1))\n echo \"Database check failed (attempt $attempt), retrying in 2s:\"\n echo \"$output\"\n sleep 2\ndone\n\necho \"Database is ready\"\n\npython manage.py createsuperuser --email $DJANGO_SUPERUSER_EMAIL --password $DJANGO_SUPERUSER_PASSWORD\n"]` |
| `backend.createsuperuser.restartPolicy` | backend migrate job restart policy | `Never` |
| `backend.job` | job dedicated to run a random management command, for example after a deployment | |
| `backend.job.name` | The name to use to describe this job | `""` |
| `backend.job.command` | The management command to execute | `[]` |
| `backend.job.restartPolicy` | The restart policy for the job. | `Never` |
| `backend.job.annotations` | Annotations to add to the job [default: argocd.argoproj.io/hook: PostSync] | |
| `backend.cronjobs` | Cronjob name, schedule, command | `[]` |
| `backend.probes.liveness.path` | Configure path for backend HTTP liveness probe | `/__lbheartbeat__` |
| `backend.probes.liveness.targetPort` | Configure port for backend HTTP liveness probe | `nil` |
| `backend.probes.liveness.initialDelaySeconds` | Configure initial delay for backend liveness probe | `10` |
| `backend.probes.liveness.timeoutSeconds` | Configure timeout for backend liveness probe | `nil` |
| `backend.probes.startup.path` | Configure path for backend HTTP startup probe | |
| `backend.probes.startup.targetPort` | Configure port for backend HTTP startup probe | |
| `backend.probes.startup.initialDelaySeconds` | Configure initial delay for backend startup probe | |
| `backend.probes.startup.timeoutSeconds` | Configure timeout for backend startup probe | |
| `backend.probes.readiness.path` | Configure path for backend HTTP readiness probe | `/__heartbeat__` |
| `backend.probes.readiness.targetPort` | Configure port for backend HTTP readiness probe | `nil` |
| `backend.probes.readiness.initialDelaySeconds` | Configure initial delay for backend readiness probe | `10` |
| `backend.probes.readiness.timeoutSeconds` | Configure timeout for backend readiness probe | `nil` |
| `backend.resources` | Resource requirements for the backend container | `{}` |
| `backend.nodeSelector` | Node selector for the backend Pod | `{}` |
| `backend.tolerations` | Tolerations for the backend Pod | `[]` |
| `backend.affinity` | Affinity for the backend Pod | `{}` |
| `backend.persistence` | Additional volumes to create and mount on the backend. Used for debugging purposes | `{}` |
| `backend.persistence.volume-name.size` | Size of the additional volume | |
| `backend.persistence.volume-name.type` | Type of the additional volume, persistentVolumeClaim or emptyDir | |
| `backend.persistence.volume-name.mountPath` | Path where the volume should be mounted to | |
| `backend.extraVolumeMounts` | Additional volumes to mount on the backend. | `[]` |
| `backend.extraVolumes` | Additional volumes to mount on the backend. | `[]` |
| `backend.pdb.enabled` | Enable pdb on backend | `true` |
| `backend.serviceAccountName` | Optional service account name to use for backend pods | `nil` |
| `backend.themeCustomization.enabled` | Enable theme customization | `false` |
| `backend.themeCustomization.file_content` | Content of the theme customization file. Must be a json object. | `""` |
| `backend.themeCustomization.mount_path` | Path where the customization file will be mounted in the backend deployment. | `/app/impress/configuration/theme` |
| `backend.celery.replicas` | Amount of celery replicas | `1` |
| `backend.celery.command` | Override the celery container command | `[]` |
| `backend.celery.args` | Override the celery container args | `["celery","-A","impress.celery_app","worker","-l","INFO","-n","impress@%h"]` |
| `backend.celery.resources` | Resource requirements for the celery container | `{}` |
| `backend.celery.probes.liveness.exec.command` | Override the celery container liveness probe command | `["/bin/sh","-c","celery -A impress.celery_app inspect ping -d impress@$HOSTNAME"]` |
| `backend.celery.probes.liveness.initialDelaySeconds` | Initial delay for the celery container liveness probe | `60` |
| `backend.celery.probes.liveness.timeoutSeconds` | Timeout for the celery container liveness probe | `5` |
| `backend.celery.probes.readiness.exec.command` | Override the celery container readiness probe command | `["/bin/sh","-c","celery -A impress.celery_app inspect ping -d impress@$HOSTNAME"]` |
| `backend.celery.probes.readiness.initialDelaySeconds` | Initial delay for the celery container readiness probe | `15` |
| `backend.celery.probes.readiness.timeoutSeconds` | Timeout for the celery container readiness probe | `5` |
| `backend.celery.envVars` | Celery worker specific environment variables (not shared with the backend web deployment) | |
### frontend
| Name | Description | Value |
| ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------------- |
| `frontend.image.repository` | Repository to use to pull impress's frontend container image | `lasuite/impress-frontend` |
| `frontend.image.tag` | impress's frontend container tag | `latest` |
| `frontend.image.pullPolicy` | frontend container image pull policy | `IfNotPresent` |
| `frontend.command` | Override the frontend container command | `[]` |
| `frontend.args` | Override the frontend container args | `[]` |
| `frontend.replicas` | Amount of frontend replicas | `3` |
| `frontend.shareProcessNamespace` | Enable share process namespace between containers | `false` |
| `frontend.sidecars` | Add sidecars containers to frontend deployment | `[]` |
| `frontend.securityContext.allowPrivilegeEscalation` | Whether to allow privilege escalation for the frontend container | `false` |
| `frontend.securityContext.capabilities.drop` | List of capabilities to drop for the frontend container | `["ALL"]` |
| `frontend.securityContext.runAsNonRoot` | Whether to run the frontend container as a non-root user | `true` |
| `frontend.securityContext.seccompProfile.type` | Seccomp profile type for the frontend container | `RuntimeDefault` |
| `frontend.envVars` | Configure frontend container environment variables | `undefined` |
| `frontend.envVars.BY_VALUE` | Example environment variable by setting value directly | |
| `frontend.envVars.FROM_CONFIGMAP.configMapKeyRef.name` | Name of a ConfigMap when configuring env vars from a ConfigMap | |
| `frontend.envVars.FROM_CONFIGMAP.configMapKeyRef.key` | Key within a ConfigMap when configuring env vars from a ConfigMap | |
| `frontend.envVars.FROM_SECRET.secretKeyRef.name` | Name of a Secret when configuring env vars from a Secret | |
| `frontend.envVars.FROM_SECRET.secretKeyRef.key` | Key within a Secret when configuring env vars from a Secret | |
| `frontend.podAnnotations` | Annotations to add to the frontend Pod | `{}` |
| `frontend.dpAnnotations` | Annotations to add to the frontend Deployment | `{}` |
| `frontend.service.type` | frontend Service type | `ClusterIP` |
| `frontend.service.port` | frontend Service listening port | `80` |
| `frontend.service.targetPort` | frontend container listening port | `8080` |
| `frontend.service.annotations` | Annotations to add to the frontend Service | `{}` |
| `frontend.probes` | Configure probe for frontend | `{}` |
| `frontend.probes.liveness.path` | Configure path for frontend HTTP liveness probe | |
| `frontend.probes.liveness.targetPort` | Configure port for frontend HTTP liveness probe | |
| `frontend.probes.liveness.initialDelaySeconds` | Configure initial delay for frontend liveness probe | |
| `frontend.probes.liveness.initialDelaySeconds` | Configure timeout for frontend liveness probe | |
| `frontend.probes.startup.path` | Configure path for frontend HTTP startup probe | |
| `frontend.probes.startup.targetPort` | Configure port for frontend HTTP startup probe | |
| `frontend.probes.startup.initialDelaySeconds` | Configure initial delay for frontend startup probe | |
| `frontend.probes.startup.initialDelaySeconds` | Configure timeout for frontend startup probe | |
| `frontend.probes.readiness.path` | Configure path for frontend HTTP readiness probe | |
| `frontend.probes.readiness.targetPort` | Configure port for frontend HTTP readiness probe | |
| `frontend.probes.readiness.initialDelaySeconds` | Configure initial delay for frontend readiness probe | |
| `frontend.probes.readiness.initialDelaySeconds` | Configure timeout for frontend readiness probe | |
| `frontend.resources` | Resource requirements for the frontend container | `{}` |
| `frontend.nodeSelector` | Node selector for the frontend Pod | `{}` |
| `frontend.tolerations` | Tolerations for the frontend Pod | `[]` |
| `frontend.affinity` | Affinity for the frontend Pod | `{}` |
| `frontend.persistence` | Additional volumes to create and mount on the frontend. Used for debugging purposes | `{}` |
| `frontend.persistence.volume-name.size` | Size of the additional volume | |
| `frontend.persistence.volume-name.type` | Type of the additional volume, persistentVolumeClaim or emptyDir | |
| `frontend.persistence.volume-name.mountPath` | Path where the volume should be mounted to | |
| `frontend.extraVolumeMounts` | Additional volumes to mount on the frontend. | `[]` |
| `frontend.extraVolumes` | Additional volumes to mount on the frontend. | `[]` |
| `frontend.pdb.enabled` | Enable pdb on frontend | `true` |
| `frontend.serviceAccountName` | Optional service account name to use for frontend pods | `nil` |
| `frontend.robotsTxt.enabled` | Enable serving a custom robots.txt file from the frontend, e.g. to disallow indexing of non-production instances | `false` |
| `frontend.robotsTxt.content` | Content of the robots.txt file | `"User-agent: *\nAllow: /\n"` |
| Name | Description | Value |
| ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------- |
| `frontend.image.repository` | Repository to use to pull impress's frontend container image | `lasuite/impress-frontend` |
| `frontend.image.tag` | impress's frontend container tag | `latest` |
| `frontend.image.pullPolicy` | frontend container image pull policy | `IfNotPresent` |
| `frontend.command` | Override the frontend container command | `[]` |
| `frontend.args` | Override the frontend container args | `[]` |
| `frontend.replicas` | Amount of frontend replicas | `3` |
| `frontend.shareProcessNamespace` | Enable share process namespace between containers | `false` |
| `frontend.sidecars` | Add sidecars containers to frontend deployment | `[]` |
| `frontend.securityContext.allowPrivilegeEscalation` | Whether to allow privilege escalation for the frontend container | `false` |
| `frontend.securityContext.capabilities.drop` | List of capabilities to drop for the frontend container | `["ALL"]` |
| `frontend.securityContext.runAsNonRoot` | Whether to run the frontend container as a non-root user | `true` |
| `frontend.securityContext.seccompProfile.type` | Seccomp profile type for the frontend container | `RuntimeDefault` |
| `frontend.envVars` | Configure frontend container environment variables | `undefined` |
| `frontend.envVars.BY_VALUE` | Example environment variable by setting value directly | |
| `frontend.envVars.FROM_CONFIGMAP.configMapKeyRef.name` | Name of a ConfigMap when configuring env vars from a ConfigMap | |
| `frontend.envVars.FROM_CONFIGMAP.configMapKeyRef.key` | Key within a ConfigMap when configuring env vars from a ConfigMap | |
| `frontend.envVars.FROM_SECRET.secretKeyRef.name` | Name of a Secret when configuring env vars from a Secret | |
| `frontend.envVars.FROM_SECRET.secretKeyRef.key` | Key within a Secret when configuring env vars from a Secret | |
| `frontend.podAnnotations` | Annotations to add to the frontend Pod | `{}` |
| `frontend.dpAnnotations` | Annotations to add to the frontend Deployment | `{}` |
| `frontend.service.type` | frontend Service type | `ClusterIP` |
| `frontend.service.port` | frontend Service listening port | `80` |
| `frontend.service.targetPort` | frontend container listening port | `8080` |
| `frontend.service.annotations` | Annotations to add to the frontend Service | `{}` |
| `frontend.probes` | Configure probe for frontend | `{}` |
| `frontend.probes.liveness.path` | Configure path for frontend HTTP liveness probe | |
| `frontend.probes.liveness.targetPort` | Configure port for frontend HTTP liveness probe | |
| `frontend.probes.liveness.initialDelaySeconds` | Configure initial delay for frontend liveness probe | |
| `frontend.probes.liveness.initialDelaySeconds` | Configure timeout for frontend liveness probe | |
| `frontend.probes.startup.path` | Configure path for frontend HTTP startup probe | |
| `frontend.probes.startup.targetPort` | Configure port for frontend HTTP startup probe | |
| `frontend.probes.startup.initialDelaySeconds` | Configure initial delay for frontend startup probe | |
| `frontend.probes.startup.initialDelaySeconds` | Configure timeout for frontend startup probe | |
| `frontend.probes.readiness.path` | Configure path for frontend HTTP readiness probe | |
| `frontend.probes.readiness.targetPort` | Configure port for frontend HTTP readiness probe | |
| `frontend.probes.readiness.initialDelaySeconds` | Configure initial delay for frontend readiness probe | |
| `frontend.probes.readiness.initialDelaySeconds` | Configure timeout for frontend readiness probe | |
| `frontend.resources` | Resource requirements for the frontend container | `{}` |
| `frontend.nodeSelector` | Node selector for the frontend Pod | `{}` |
| `frontend.tolerations` | Tolerations for the frontend Pod | `[]` |
| `frontend.affinity` | Affinity for the frontend Pod | `{}` |
| `frontend.persistence` | Additional volumes to create and mount on the frontend. Used for debugging purposes | `{}` |
| `frontend.persistence.volume-name.size` | Size of the additional volume | |
| `frontend.persistence.volume-name.type` | Type of the additional volume, persistentVolumeClaim or emptyDir | |
| `frontend.persistence.volume-name.mountPath` | Path where the volume should be mounted to | |
| `frontend.extraVolumeMounts` | Additional volumes to mount on the frontend. | `[]` |
| `frontend.extraVolumes` | Additional volumes to mount on the frontend. | `[]` |
| `frontend.pdb.enabled` | Enable pdb on frontend | `true` |
| `frontend.serviceAccountName` | Optional service account name to use for frontend pods | `nil` |
| `frontend.robotsTxt.enabled` | Enable serving a custom robots.txt file from the frontend, e.g. to disallow indexing of non-production instances | `false` |
| `frontend.robotsTxt.content` | Content of the robots.txt file | `"User-agent: *\nAllow: /\n"`|
### posthog
@@ -351,129 +372,131 @@
### yhub
| Name | Description | Value |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
| `yhub.enabled` | Enable the yhub collaboration server, its service and its init-db job | `true` |
| `yhub.image.repository` | Repository to use to pull the yhub container image | `lasuite/impress-yhub` |
| `yhub.image.tag` | yhub container tag | `latest` |
| `yhub.image.pullPolicy` | yhub container image pull policy | `IfNotPresent` |
| `yhub.command` | Override the yhub container command | `[]` |
| `yhub.args` | Override the yhub container args | `[]` |
| `yhub.replicas` | Amount of yhub replicas | `3` |
| `yhub.metrics.enabled` | Serve the prometheus metrics of yhub on a port of their own, in the server and in the worker. Requires PROMETHEUS_API_KEY in yhub.envVars | `false` |
| `yhub.metrics.port` | Port the metrics are served on. Added to the yhub Service, and to a Service of its own for the worker | `9464` |
| `yhub.metrics.path` | Path the server serves its metrics on, which is the path ingressMetrics publishes them at | `/metrics/yhub` |
| `yhub.metrics.workerPath` | Path the worker serves its metrics on, which is the path ingressMetrics publishes them at | `/metrics/yhub-worker` |
| `yhub.worker.enabled` | Deploy the worker apart from the server, each scaling on its own | `false` |
| `yhub.worker.replicas` | Amount of yhub worker replicas | `1` |
| `yhub.worker.resources` | Resource requirements for the yhub worker container, the server ones when empty | `{}` |
| `yhub.worker.podAnnotations` | Annotations to add to the yhub worker Pod, the server ones when empty | `{}` |
| `yhub.worker.dpAnnotations` | Annotations to add to the yhub worker Deployment, the server ones when empty | `{}` |
| `yhub.worker.nodeSelector` | Node selector for the yhub worker Pod, the server one when empty | `{}` |
| `yhub.worker.tolerations` | Tolerations for the yhub worker Pod, the server ones when empty | `[]` |
| `yhub.worker.affinity` | Affinity for the yhub worker Pod, the server one when empty | `{}` |
| `yhub.worker.terminationGracePeriodSeconds` | Grace period given to a worker pod to finish its task, the server one when empty | `nil` |
| `yhub.worker.pdb.enabled` | Enable pdb on the yhub worker | `true` |
| `yhub.shareProcessNamespace` | Enable share process namespace between containers | `false` |
| `yhub.sidecars` | Add sidecars containers to yhub deployment | `[]` |
| `yhub.terminationGracePeriodSeconds` | Grace period given to a yhub pod to drain before it is killed | `60` |
| `yhub.securityContext.allowPrivilegeEscalation` | Whether to allow privilege escalation for the yhub container | `false` |
| `yhub.securityContext.capabilities.drop` | List of capabilities to drop for the yhub container | `["ALL"]` |
| `yhub.securityContext.runAsNonRoot` | Whether to run the yhub container as a non-root user | `true` |
| `yhub.securityContext.runAsUser` | User the yhub container runs as | `1000` |
| `yhub.securityContext.runAsGroup` | Group the yhub container runs as | `1000` |
| `yhub.securityContext.seccompProfile.type` | Seccomp profile type for the yhub container | `RuntimeDefault` |
| `yhub.envVars` | Configure yhub container environment variables | `undefined` |
| `yhub.envVars.REDIS` | Required, redis/valkey url holding the live document state (e.g. redis://valkey:6379/0) | |
| `yhub.envVars.POSTGRES` | Required, url of the yhub database, created by the init-db job (e.g. postgres://user:pass@postgres:5432/yhub) | |
| `yhub.envVars.REDIS_PREFIX` | Namespace of the redis keys, when the instance is shared (default: yhub) | |
| `yhub.envVars.COLLABORATION_BACKEND_BASE_URL` | Base url of the Docs backend, which yhub asks about users and document access rights | |
| `yhub.envVars.COLLABORATION_SERVER_ORIGIN` | Comma separated list of the origins allowed to open a websocket | |
| `yhub.envVars.YHUB_JWT_PRIVATE_KEY_FILE` | Path to the RSA private key (PEM) yhub signs its calls to the backend with, mounted from a secret | |
| `yhub.envVars.YHUB_TASK_CONCURRENCY` | Tasks one worker process claims at once, times the replicas running a worker (default: 5) | |
| `yhub.envVars.YHUB_TASK_DEBOUNCE_MS` | How long an update waits on the redis stream before a worker persists it, in ms (default: 10000) | |
| `yhub.envVars.YHUB_MIN_MESSAGE_LIFETIME_MS` | How long persisted updates stay replayable from redis, in ms (default: 60000) | |
| `yhub.envVars.SOFT_MIGRATION` | Set to "true" to seed rooms from the legacy Django/S3 document store on first access | |
| `yhub.envVars.LEGACY_S3_ENDPOINT_URL` | Required by SOFT_MIGRATION, endpoint of the legacy Django media bucket, without a path (e.g. https://s3.example.com) | |
| `yhub.envVars.LEGACY_S3_ACCESS_KEY_ID` | Required by SOFT_MIGRATION, read access to the legacy bucket (or LEGACY_S3_ACCESS_KEY_ID_FILE) | |
| `yhub.envVars.LEGACY_S3_SECRET_ACCESS_KEY` | Required by SOFT_MIGRATION, secret of the key above (or LEGACY_S3_SECRET_ACCESS_KEY_FILE) | |
| `yhub.envVars.LEGACY_S3_REGION_NAME` | Region of the legacy bucket, when its provider needs one | |
| `yhub.envVars.LEGACY_S3_BUCKET_NAME` | Name of the legacy Django media bucket (default: impress-media-storage) | |
| `yhub.envVars.LEGACY_S3_SIGNATURE_VERSION` | How the calls to the legacy bucket are signed, s3v4 or v4 (default: s3v4) | |
| Name | Description | Value |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
| `yhub.enabled` | Enable the yhub collaboration server, its service and its init-db job | `true` |
| `yhub.image.repository` | Repository to use to pull the yhub container image | `lasuite/impress-yhub` |
| `yhub.image.tag` | yhub container tag | `latest` |
| `yhub.image.pullPolicy` | yhub container image pull policy | `IfNotPresent` |
| `yhub.command` | Override the yhub container command | `[]` |
| `yhub.args` | Override the yhub container args | `[]` |
| `yhub.replicas` | Amount of yhub replicas | `3` |
| `yhub.metrics.enabled` | Serve the prometheus metrics of yhub on a port of their own, in the server and in the worker. Requires PROMETHEUS_API_KEY in yhub.envVars | `false` |
| `yhub.metrics.port` | Port the metrics are served on. Added to the yhub Service, and to a Service of its own for the worker | `9464` |
| `yhub.metrics.path` | Path the server serves its metrics on, which is the path ingressMetrics publishes them at | `/metrics/yhub` |
| `yhub.metrics.workerPath` | Path the worker serves its metrics on, which is the path ingressMetrics publishes them at | `/metrics/yhub-worker` |
| `yhub.metrics.apiKeySecret.name` | Secret the monitors read the bearer token from. Defaults to the secretKeyRef of PROMETHEUS_API_KEY in yhub.envVars (yhub.worker.envVars for the worker) | `""` |
| `yhub.metrics.apiKeySecret.key` | Key of the bearer token in that Secret | `""` |
| `yhub.worker.enabled` | Deploy the worker apart from the server, each scaling on its own | `false` |
| `yhub.worker.replicas` | Amount of yhub worker replicas | `1` |
| `yhub.worker.resources` | Resource requirements for the yhub worker container, the server ones when empty | `{}` |
| `yhub.worker.podAnnotations` | Annotations to add to the yhub worker Pod, the server ones when empty | `{}` |
| `yhub.worker.dpAnnotations` | Annotations to add to the yhub worker Deployment, the server ones when empty | `{}` |
| `yhub.worker.nodeSelector` | Node selector for the yhub worker Pod, the server one when empty | `{}` |
| `yhub.worker.tolerations` | Tolerations for the yhub worker Pod, the server ones when empty | `[]` |
| `yhub.worker.affinity` | Affinity for the yhub worker Pod, the server one when empty | `{}` |
| `yhub.worker.terminationGracePeriodSeconds` | Grace period given to a worker pod to finish its task, the server one when empty | `nil` |
| `yhub.worker.pdb.enabled` | Enable pdb on the yhub worker | `true` |
| `yhub.shareProcessNamespace` | Enable share process namespace between containers | `false` |
| `yhub.sidecars` | Add sidecars containers to yhub deployment | `[]` |
| `yhub.terminationGracePeriodSeconds` | Grace period given to a yhub pod to drain before it is killed | `60` |
| `yhub.securityContext.allowPrivilegeEscalation` | Whether to allow privilege escalation for the yhub container | `false` |
| `yhub.securityContext.capabilities.drop` | List of capabilities to drop for the yhub container | `["ALL"]` |
| `yhub.securityContext.runAsNonRoot` | Whether to run the yhub container as a non-root user | `true` |
| `yhub.securityContext.runAsUser` | User the yhub container runs as | `1000` |
| `yhub.securityContext.runAsGroup` | Group the yhub container runs as | `1000` |
| `yhub.securityContext.seccompProfile.type` | Seccomp profile type for the yhub container | `RuntimeDefault` |
| `yhub.envVars` | Configure yhub container environment variables | `undefined` |
| `yhub.envVars.REDIS` | Required, redis/valkey url holding the live document state (e.g. redis://valkey:6379/0) | |
| `yhub.envVars.POSTGRES` | Required, url of the yhub database, created by the init-db job (e.g. postgres://user:pass@postgres:5432/yhub) | |
| `yhub.envVars.REDIS_PREFIX` | Namespace of the redis keys, when the instance is shared (default: yhub) | |
| `yhub.envVars.COLLABORATION_BACKEND_BASE_URL` | Base url of the Docs backend, which yhub asks about users and document access rights | |
| `yhub.envVars.COLLABORATION_SERVER_ORIGIN` | Comma separated list of the origins allowed to open a websocket | |
| `yhub.envVars.YHUB_JWT_PRIVATE_KEY_FILE` | Path to the RSA private key (PEM) yhub signs its calls to the backend with, mounted from a secret | |
| `yhub.envVars.YHUB_TASK_CONCURRENCY` | Tasks one worker process claims at once, times the replicas running a worker (default: 5) | |
| `yhub.envVars.YHUB_TASK_DEBOUNCE_MS` | How long an update waits on the redis stream before a worker persists it, in ms (default: 10000) | |
| `yhub.envVars.YHUB_MIN_MESSAGE_LIFETIME_MS` | How long persisted updates stay replayable from redis, in ms (default: 60000) | |
| `yhub.envVars.SOFT_MIGRATION` | Set to "true" to seed rooms from the legacy Django/S3 document store on first access | |
| `yhub.envVars.LEGACY_S3_ENDPOINT_URL` | Required by SOFT_MIGRATION, endpoint of the legacy Django media bucket, without a path (e.g. https://s3.example.com) | |
| `yhub.envVars.LEGACY_S3_ACCESS_KEY_ID` | Required by SOFT_MIGRATION, read access to the legacy bucket (or LEGACY_S3_ACCESS_KEY_ID_FILE) | |
| `yhub.envVars.LEGACY_S3_SECRET_ACCESS_KEY` | Required by SOFT_MIGRATION, secret of the key above (or LEGACY_S3_SECRET_ACCESS_KEY_FILE) | |
| `yhub.envVars.LEGACY_S3_REGION_NAME` | Region of the legacy bucket, when its provider needs one | |
| `yhub.envVars.LEGACY_S3_BUCKET_NAME` | Name of the legacy Django media bucket (default: impress-media-storage) | |
| `yhub.envVars.LEGACY_S3_SIGNATURE_VERSION` | How the calls to the legacy bucket are signed, s3v4 or v4 (default: s3v4) | |
| `yhub.envVars.YHUB_S3_PERSISTENCE` | Set to "true" to write new document blobs to a bucket instead of the yhub database — the YHUB_S3_* settings attach the bucket whether or not this is on, read src/yhub-server/README.md first | |
| `yhub.envVars.YHUB_S3_ENDPOINT_URL` | Required by YHUB_S3_PERSISTENCE, endpoint of the bucket the blobs are stored in, without a path (e.g. https://s3.example.com) | |
| `yhub.envVars.YHUB_S3_ACCESS_KEY_ID` | Required by YHUB_S3_PERSISTENCE, read/write/delete access to that bucket (or YHUB_S3_ACCESS_KEY_ID_FILE) | |
| `yhub.envVars.YHUB_S3_SECRET_ACCESS_KEY` | Required by YHUB_S3_PERSISTENCE, secret of the key above (or YHUB_S3_SECRET_ACCESS_KEY_FILE) | |
| `yhub.envVars.YHUB_S3_BUCKET_NAME` | Required by YHUB_S3_PERSISTENCE, name of that bucket, created on startup when missing | |
| `yhub.envVars.YHUB_S3_REGION_NAME` | Region of that bucket, when its provider needs one | |
| `yhub.envVars.BY_VALUE` | Example environment variable by setting value directly | |
| `yhub.envVars.FROM_CONFIGMAP.configMapKeyRef.name` | Name of a ConfigMap when configuring env vars from a ConfigMap | |
| `yhub.envVars.FROM_CONFIGMAP.configMapKeyRef.key` | Key within a ConfigMap when configuring env vars from a ConfigMap | |
| `yhub.envVars.FROM_SECRET.secretKeyRef.name` | Name of a Secret when configuring env vars from a Secret | |
| `yhub.envVars.FROM_SECRET.secretKeyRef.key` | Key within a Secret when configuring env vars from a Secret | |
| `yhub.podAnnotations` | Annotations to add to the yhub Pod | `{}` |
| `yhub.dpAnnotations` | Annotations to add to the yhub Deployment | `{}` |
| `yhub.initDbJobAnnotations` | Annotations for the yhub init-db job | `{}` |
| `yhub.jobs.ttlSecondsAfterFinished` | Period to wait before removing the init-db job | `30` |
| `yhub.jobs.backoffLimit` | Numbers of init-db job retries | `2` |
| `yhub.initDb.enabled` | Run the job creating and upgrading the yhub schema | `true` |
| `yhub.initDb.command` | Override the command creating and upgrading the yhub schema | `[]` |
| `yhub.initDb.retries` | How many times the schema script is retried while the postgres server does not answer | `60` |
| `yhub.initDb.retryDelaySeconds` | Seconds between two attempts | `5` |
| `yhub.initDb.restartPolicy` | Restart policy of the init-db job | `Never` |
| `yhub.service.type` | yhub Service type | `ClusterIP` |
| `yhub.service.port` | yhub Service listening port | `443` |
| `yhub.service.targetPort` | yhub container listening port | `3002` |
| `yhub.service.annotations` | Annotations to add to the yhub Service | `{}` |
| `yhub.probes.liveness.path` | Configure path for yhub HTTP liveness probe | `/collaboration/ping/v1` |
| `yhub.probes.liveness.initialDelaySeconds` | Configure initial delay for yhub liveness probe | `10` |
| `yhub.probes.liveness.timeoutSeconds` | Configure timeout for yhub liveness probe | `2` |
| `yhub.probes.readiness.path` | Configure path for yhub HTTP readiness probe | `/collaboration/ready/v1` |
| `yhub.probes.readiness.initialDelaySeconds` | Configure initial delay for yhub readiness probe | `5` |
| `yhub.probes.readiness.timeoutSeconds` | Configure timeout for yhub readiness probe | `3` |
| `yhub.probes.liveness.targetPort` | Configure port for yhub HTTP liveness probe | |
| `yhub.probes.readiness.targetPort` | Configure port for yhub HTTP readiness probe | |
| `yhub.probes.startup.path` | Configure path for yhub HTTP startup probe | |
| `yhub.probes.startup.targetPort` | Configure port for yhub HTTP startup probe | |
| `yhub.probes.startup.initialDelaySeconds` | Configure initial delay for yhub startup probe | |
| `yhub.probes.startup.timeoutSeconds` | Configure timeout for yhub startup probe | |
| `yhub.resources` | Resource requirements for the yhub container | `{}` |
| `yhub.nodeSelector` | Node selector for the yhub Pod | `{}` |
| `yhub.tolerations` | Tolerations for the yhub Pod | `[]` |
| `yhub.affinity` | Affinity for the yhub Pod | `{}` |
| `yhub.persistence` | Additional volumes to create and mount on the yhub. Used for debugging purposes | `{}` |
| `yhub.persistence.volume-name.size` | Size of the additional volume | |
| `yhub.persistence.volume-name.type` | Type of the additional volume, persistentVolumeClaim or emptyDir | |
| `yhub.persistence.volume-name.mountPath` | Path where the volume should be mounted to | |
| `yhub.extraVolumeMounts` | Additional volumes to mount on the yhub. Mounted on the init-db job too | `[]` |
| `yhub.extraVolumes` | Additional volumes to mount on the yhub. Mounted on the init-db job too | `[]` |
| `yhub.pdb.enabled` | Enable pdb on yhub | `true` |
| `yhub.serviceAccountName` | Optional service account name to use for yhub pods | `nil` |
| `yhub.envVars.YHUB_S3_ENDPOINT_URL` | Required by YHUB_S3_PERSISTENCE, endpoint of the bucket the blobs are stored in, without a path (e.g. https://s3.example.com) | |
| `yhub.envVars.YHUB_S3_ACCESS_KEY_ID` | Required by YHUB_S3_PERSISTENCE, read/write/delete access to that bucket (or YHUB_S3_ACCESS_KEY_ID_FILE) | |
| `yhub.envVars.YHUB_S3_SECRET_ACCESS_KEY` | Required by YHUB_S3_PERSISTENCE, secret of the key above (or YHUB_S3_SECRET_ACCESS_KEY_FILE) | |
| `yhub.envVars.YHUB_S3_BUCKET_NAME` | Required by YHUB_S3_PERSISTENCE, name of that bucket, created on startup when missing | |
| `yhub.envVars.YHUB_S3_REGION_NAME` | Region of that bucket, when its provider needs one | |
| `yhub.envVars.BY_VALUE` | Example environment variable by setting value directly | |
| `yhub.envVars.FROM_CONFIGMAP.configMapKeyRef.name` | Name of a ConfigMap when configuring env vars from a ConfigMap | |
| `yhub.envVars.FROM_CONFIGMAP.configMapKeyRef.key` | Key within a ConfigMap when configuring env vars from a ConfigMap | |
| `yhub.envVars.FROM_SECRET.secretKeyRef.name` | Name of a Secret when configuring env vars from a Secret | |
| `yhub.envVars.FROM_SECRET.secretKeyRef.key` | Key within a Secret when configuring env vars from a Secret | |
| `yhub.podAnnotations` | Annotations to add to the yhub Pod | `{}` |
| `yhub.dpAnnotations` | Annotations to add to the yhub Deployment | `{}` |
| `yhub.initDbJobAnnotations` | Annotations for the yhub init-db job | `{}` |
| `yhub.jobs.ttlSecondsAfterFinished` | Period to wait before removing the init-db job | `30` |
| `yhub.jobs.backoffLimit` | Numbers of init-db job retries | `2` |
| `yhub.initDb.enabled` | Run the job creating and upgrading the yhub schema | `true` |
| `yhub.initDb.command` | Override the command creating and upgrading the yhub schema | `[]` |
| `yhub.initDb.retries` | How many times the schema script is retried while the postgres server does not answer | `60` |
| `yhub.initDb.retryDelaySeconds` | Seconds between two attempts | `5` |
| `yhub.initDb.restartPolicy` | Restart policy of the init-db job | `Never` |
| `yhub.service.type` | yhub Service type | `ClusterIP` |
| `yhub.service.port` | yhub Service listening port | `443` |
| `yhub.service.targetPort` | yhub container listening port | `3002` |
| `yhub.service.annotations` | Annotations to add to the yhub Service | `{}` |
| `yhub.probes.liveness.path` | Configure path for yhub HTTP liveness probe | `/collaboration/ping/v1` |
| `yhub.probes.liveness.initialDelaySeconds` | Configure initial delay for yhub liveness probe | `10` |
| `yhub.probes.liveness.timeoutSeconds` | Configure timeout for yhub liveness probe | `2` |
| `yhub.probes.readiness.path` | Configure path for yhub HTTP readiness probe | `/collaboration/ready/v1` |
| `yhub.probes.readiness.initialDelaySeconds` | Configure initial delay for yhub readiness probe | `5` |
| `yhub.probes.readiness.timeoutSeconds` | Configure timeout for yhub readiness probe | `3` |
| `yhub.probes.liveness.targetPort` | Configure port for yhub HTTP liveness probe | |
| `yhub.probes.readiness.targetPort` | Configure port for yhub HTTP readiness probe | |
| `yhub.probes.startup.path` | Configure path for yhub HTTP startup probe | |
| `yhub.probes.startup.targetPort` | Configure port for yhub HTTP startup probe | |
| `yhub.probes.startup.initialDelaySeconds` | Configure initial delay for yhub startup probe | |
| `yhub.probes.startup.timeoutSeconds` | Configure timeout for yhub startup probe | |
| `yhub.resources` | Resource requirements for the yhub container | `{}` |
| `yhub.nodeSelector` | Node selector for the yhub Pod | `{}` |
| `yhub.tolerations` | Tolerations for the yhub Pod | `[]` |
| `yhub.affinity` | Affinity for the yhub Pod | `{}` |
| `yhub.persistence` | Additional volumes to create and mount on the yhub. Used for debugging purposes | `{}` |
| `yhub.persistence.volume-name.size` | Size of the additional volume | |
| `yhub.persistence.volume-name.type` | Type of the additional volume, persistentVolumeClaim or emptyDir | |
| `yhub.persistence.volume-name.mountPath` | Path where the volume should be mounted to | |
| `yhub.extraVolumeMounts` | Additional volumes to mount on the yhub. Mounted on the init-db job too | `[]` |
| `yhub.extraVolumes` | Additional volumes to mount on the yhub. Mounted on the init-db job too | `[]` |
| `yhub.pdb.enabled` | Enable pdb on yhub | `true` |
| `yhub.serviceAccountName` | Optional service account name to use for yhub pods | `nil` |
### docSpec
| Name | Description | Value |
| -------------------------------------------------- | --------------------------------------------------------------- | ----------------------- |
| `docSpec.enabled` | Enable docSpec deployment | `false` |
| `docSpec.image.repository` | Repository to use to pull docSpec container image | `ghcr.io/docspecio/api` |
| `docSpec.image.tag` | docSpec container tag | `3.0.1` |
| `docSpec.image.pullPolicy` | docSpec container image pull policy | `IfNotPresent` |
| `docSpec.command` | Override the docSpec container command | `[]` |
| `docSpec.args` | Override the docSpec container args | `[]` |
| `docSpec.replicas` | Amount of docSpec replicas | `1` |
| `docSpec.securityContext.allowPrivilegeEscalation` | Whether to allow privilege escalation for the docSpec container | `false` |
| `docSpec.securityContext.capabilities.drop` | List of capabilities to drop for the docSpec container | `["ALL"]` |
| `docSpec.securityContext.runAsNonRoot` | Whether to run the docSpec container as a non-root user | `true` |
| `docSpec.securityContext.seccompProfile.type` | Seccomp profile type for the docSpec container | `RuntimeDefault` |
| `docSpec.envVars` | Configure docSpec container environment variables | `{}` |
| `docSpec.service.type` | docSpec Service type | `ClusterIP` |
| `docSpec.service.port` | docSpec Service listening port | `4000` |
| `docSpec.service.targetPort` | docSpec container listening port | `3000` |
| `docSpec.probes.liveness.path` | Configure path for docSpec HTTP liveness probe | `/health` |
| `docSpec.probes.readiness.path` | Configure path for docSpec HTTP readiness probe | `/health` |
| `docSpec.resources` | docSpec resources | `{}` |
| `docSpec.nodeSelector` | Node selector for the docSpec Pod | `{}` |
| `docSpec.tolerations` | Tolerations for the docSpec Pod | `[]` |
| `docSpec.affinity` | Affinity for the docSpec Pod | `{}` |
| `docSpec.extraVolumeMounts` | Additional volumes to mount on docSpec | `[]` |
| `docSpec.extraVolumes` | Additional volumes to mount on docSpec | `[]` |
| Name | Description | Value |
| -------------------------------------------------- | --------------------------------------------------------------- | --------------------- |
| `docSpec.enabled` | Enable docSpec deployment | `false` |
| `docSpec.image.repository` | Repository to use to pull docSpec container image | `ghcr.io/docspec/api` |
| `docSpec.image.tag` | docSpec container tag | `1.21.4` |
| `docSpec.image.pullPolicy` | docSpec container image pull policy | `IfNotPresent` |
| `docSpec.command` | Override the docSpec container command | `[]` |
| `docSpec.args` | Override the docSpec container args | `[]` |
| `docSpec.replicas` | Amount of docSpec replicas | `1` |
| `docSpec.securityContext.allowPrivilegeEscalation` | Whether to allow privilege escalation for the docSpec container | `false` |
| `docSpec.securityContext.capabilities.drop` | List of capabilities to drop for the docSpec container | `["ALL"]` |
| `docSpec.securityContext.runAsNonRoot` | Whether to run the docSpec container as a non-root user | `true` |
| `docSpec.securityContext.seccompProfile.type` | Seccomp profile type for the docSpec container | `RuntimeDefault` |
| `docSpec.envVars` | Configure docSpec container environment variables | `{}` |
| `docSpec.service.type` | docSpec Service type | `ClusterIP` |
| `docSpec.service.port` | docSpec Service listening port | `4000` |
| `docSpec.service.targetPort` | docSpec container listening port | `3000` |
| `docSpec.probes.liveness.path` | Configure path for docSpec HTTP liveness probe | `/health` |
| `docSpec.probes.readiness.path` | Configure path for docSpec HTTP readiness probe | `/health` |
| `docSpec.resources` | docSpec resources | `{}` |
| `docSpec.nodeSelector` | Node selector for the docSpec Pod | `{}` |
| `docSpec.tolerations` | Tolerations for the docSpec Pod | `[]` |
| `docSpec.affinity` | Affinity for the docSpec Pod | `{}` |
| `docSpec.extraVolumeMounts` | Additional volumes to mount on docSpec | `[]` |
| `docSpec.extraVolumes` | Additional volumes to mount on docSpec | `[]` |
+104
View File
@@ -405,3 +405,107 @@ is told to serve its metrics on the path it is published at.
{{- end }}
{{- end }}
{{- end }}
{{/*
Environment enabling the prometheus metrics of the backend on the django
container, and on it only: the celery worker serves no request, so its metrics
would never be read. A pod is only ever scraped over plain http — TLS ends at
the ingress, and a Prometheus of the cluster calls the pods themselves — so the
path is also taken out of the redirect to https. Each variable is skipped when
the deployment sets it by hand, in either env map — an explicit value wins, as
everywhere else here. The bearer token (PROMETHEUS_API_KEY) is not set here: it
is a secret, given through `backend.envVars`.
Requires top level scope
*/}}
{{- define "impress.backend.metrics.env" -}}
{{- if .Values.backend.metrics.enabled -}}
{{- $named := merge (dict) ((.Values.backend.django | default dict).envVars | default dict) (.Values.backend.envVars | default dict) -}}
{{- range $variable := list "PROMETHEUS_METRICS_ENABLED" "PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT" -}}
{{- if not (hasKey $named $variable) }}
- name: {{ $variable | quote }}
value: "True"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{/*
The Secret a monitor reads the bearer token of a scrape from: the one named in
`<component>.metrics.apiKeySecret`, or else the one PROMETHEUS_API_KEY is taken
from in the env of the scraped process. A token that comes from nowhere the
Prometheus Operator can read is refused at render time, rather than left to
fail at scrape time with a 401.
Requires a dict with "name" (of the monitor, for the message), "metrics" (the
`<component>.metrics` values) and "envVars" (the env map of the scraped process)
*/}}
{{- define "impress.metrics.apiKeySecret" -}}
{{- $ref := .metrics.apiKeySecret | default dict -}}
{{- if not $ref.name -}}
{{- $fromEnv := index (.envVars | default dict) "PROMETHEUS_API_KEY" -}}
{{- $ref = (kindIs "map" $fromEnv) | ternary $fromEnv dict -}}
{{- $ref = $ref.secretKeyRef | default dict -}}
{{- end -}}
{{- if not (and $ref.name $ref.key) -}}
{{- fail (printf "%s: a monitor scrapes with the bearer token of PROMETHEUS_API_KEY, which has to come from a Secret. Give it as a secretKeyRef in the envVars of the component, or name the Secret in its metrics.apiKeySecret" .name) -}}
{{- end -}}
name: {{ $ref.name | quote }}
key: {{ $ref.key | quote }}
{{- end }}
{{/*
The components whose metrics are enabled, as the monitors see them: one entry
per pod kind to scrape, with the labels selecting it (its Service and its pods
carry the same ones), the name of the port — the same on the Service and on the
container — and the path the process serves on.
Requires top level scope
*/}}
{{- define "impress.metrics.targets" -}}
{{- $targets := list -}}
{{- if .Values.backend.metrics.enabled -}}
{{- $envVars := merge (dict) ((.Values.backend.django | default dict).envVars | default dict) (.Values.backend.envVars | default dict) -}}
{{- $targets = append $targets (dict "name" (include "impress.backend.fullname" .) "component" "backend" "port" "http" "path" "/metrics" "metrics" .Values.backend.metrics "envVars" $envVars) -}}
{{- end -}}
{{- if and .Values.yhub.enabled .Values.yhub.metrics.enabled -}}
{{- $targets = append $targets (dict "name" (include "impress.yhub.fullname" .) "component" "yhub" "port" "metrics" "path" .Values.yhub.metrics.path "metrics" .Values.yhub.metrics "envVars" (.Values.yhub.envVars | default dict)) -}}
{{- if .Values.yhub.worker.enabled -}}
{{- $envVars := merge (dict) ((.Values.yhub.worker | default dict).envVars | default dict) (.Values.yhub.envVars | default dict) -}}
{{- $targets = append $targets (dict "name" (include "impress.yhub.worker.fullname" .) "component" "yhub-worker" "port" "metrics" "path" .Values.yhub.metrics.workerPath "metrics" .Values.yhub.metrics "envVars" $envVars) -}}
{{- end -}}
{{- end -}}
{{- toJson $targets -}}
{{- end }}
{{/*
One endpoint of a ServiceMonitor or a PodMonitor: the port and path of a target,
the scrape settings of the monitor and the bearer token of the component.
Requires a dict with "target" (an entry of impress.metrics.targets) and
"monitor" (the serviceMonitor or podMonitor values)
*/}}
{{- define "impress.metrics.endpoint" -}}
- port: {{ .target.port }}
path: {{ .target.path | quote }}
scheme: http
{{- with .monitor.interval }}
interval: {{ . }}
{{- end }}
{{- with .monitor.scrapeTimeout }}
scrapeTimeout: {{ . }}
{{- end }}
honorLabels: {{ .monitor.honorLabels }}
authorization:
type: Bearer
credentials:
{{- include "impress.metrics.apiKeySecret" (dict "name" .target.name "metrics" .target.metrics "envVars" .target.envVars) | nindent 6 }}
{{- with .monitor.relabelings }}
relabelings:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .monitor.metricRelabelings }}
metricRelabelings:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
@@ -49,12 +49,14 @@ spec:
args:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if or $envVars .Values.jwtKeys.enabled }}
{{- $metricsEnv := include "impress.backend.metrics.env" . }}
{{- if or $envVars .Values.jwtKeys.enabled $metricsEnv }}
env:
{{- $envVars | indent 12 }}
{{- if .Values.jwtKeys.enabled }}
{{- include "impress.jwtKeys.backendEnv" . | nindent 12 }}
{{- end }}
{{- $metricsEnv | nindent 12 }}
{{- end }}
{{- $envFrom := concat (.Values.backend.envFrom | default list) ((.Values.backend.django | default dict).envFrom | default list) }}
{{- if $envFrom }}
@@ -0,0 +1,36 @@
{{- /*
One PodMonitor per component whose metrics are enabled — the backend, the yhub
server, the yhub worker — for a Prometheus Operator inside the cluster. The
same targets as the ServiceMonitors, found by the labels of the pods rather
than through their Services. The job is named after the component.
*/ -}}
{{- if .Values.podMonitor.enabled -}}
{{- $monitor := .Values.podMonitor -}}
{{- range $target := include "impress.metrics.targets" . | fromJsonArray }}
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: {{ $target.name }}
namespace: {{ $monitor.namespace | default $.Release.Namespace | quote }}
labels:
{{- include "impress.common.labels" (list $ $target.component) | nindent 4 }}
{{- with $monitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $monitor.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
jobLabel: app.kubernetes.io/component
namespaceSelector:
matchNames:
- {{ $.Release.Namespace | quote }}
selector:
matchLabels:
{{- include "impress.common.selectorLabels" (list $ $target.component) | nindent 6 }}
podMetricsEndpoints:
{{- include "impress.metrics.endpoint" (dict "target" $target "monitor" $monitor) | nindent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,37 @@
{{- /*
One ServiceMonitor per component whose metrics are enabled — the backend, the
yhub server, the yhub worker — for a Prometheus Operator inside the cluster.
Each pod behind the Service becomes a target of its own, scraped with the bearer
token the component checks, so nothing goes through the ingress and no replica
is missed. The job is named after the component.
*/ -}}
{{- if .Values.serviceMonitor.enabled -}}
{{- $monitor := .Values.serviceMonitor -}}
{{- range $target := include "impress.metrics.targets" . | fromJsonArray }}
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ $target.name }}
namespace: {{ $monitor.namespace | default $.Release.Namespace | quote }}
labels:
{{- include "impress.common.labels" (list $ $target.component) | nindent 4 }}
{{- with $monitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $monitor.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
jobLabel: app.kubernetes.io/component
namespaceSelector:
matchNames:
- {{ $.Release.Namespace | quote }}
selector:
matchLabels:
{{- include "impress.common.selectorLabels" (list $ $target.component) | nindent 6 }}
endpoints:
{{- include "impress.metrics.endpoint" (dict "target" $target "monitor" $monitor) | nindent 4 }}
{{- end }}
{{- end }}
+73 -1
View File
@@ -186,7 +186,7 @@ ingressAdmin:
secretName: null
additional: []
## @param ingressMetrics.enabled whether to enable the Ingress publishing the Prometheus metrics of the backend (requires PROMETHEUS_METRICS_ENABLED and PROMETHEUS_API_KEY in backend.envVars) and, with yhub.metrics.enabled, those of yhub
## @param ingressMetrics.enabled whether to enable the Ingress publishing the Prometheus metrics of the backend (backend.metrics.enabled) and of yhub (yhub.metrics.enabled) to a Prometheus outside of the cluster. One inside it scrapes the pods directly with serviceMonitor or podMonitor instead
## @param ingressMetrics.className IngressClass to use for the Ingress
## @param ingressMetrics.host Host for the Ingress. Use a host of its own, and add it to DJANGO_ALLOWED_HOSTS
## @param ingressMetrics.path Path of the backend metrics, matched exactly. The yhub ones are published at yhub.metrics.path and yhub.metrics.workerPath
@@ -213,6 +213,60 @@ ingressMetrics:
## nginx.ingress.kubernetes.io/whitelist-source-range: "203.0.113.10/32"
annotations: {}
## Prometheus Operator. A monitor is created for each component whose metrics
## are enabled — the backend (backend.metrics.enabled), the yhub server and the
## yhub worker (yhub.metrics.enabled) — so that a Prometheus inside the cluster
## scrapes every pod directly, each pod a target of its own, rather than one
## replica at random through the ingress. The scrape presents the bearer token
## of the component, read from the Secret its PROMETHEUS_API_KEY comes from
## (backend.metrics.apiKeySecret, yhub.metrics.apiKeySecret). The Prometheus
## Operator reads that Secret itself: it has to live in the namespace of the
## monitors, and the operator's service account be allowed to read it, as the
## kube-prometheus-stack one is.
##
## A ServiceMonitor finds the pods through their Services, a PodMonitor through
## their labels. They give the same targets: pick the kind your Prometheus is
## configured to select, or both.
## @param serviceMonitor.enabled Create a ServiceMonitor for each component whose metrics are enabled
## @param serviceMonitor.namespace Namespace the ServiceMonitors are created in, the release one when empty
## @param serviceMonitor.labels Labels of the ServiceMonitors, which the Prometheus Operator selects them by (e.g. release: kube-prometheus-stack)
## @param serviceMonitor.annotations Annotations of the ServiceMonitors
## @param serviceMonitor.interval Scrape interval, the Prometheus default when empty
## @param serviceMonitor.scrapeTimeout Scrape timeout, the Prometheus default when empty
## @param serviceMonitor.honorLabels Keep the labels of the scraped samples when they clash with the target ones
## @param serviceMonitor.relabelings Relabelings of the targets, before the scrape
## @param serviceMonitor.metricRelabelings Relabelings of the samples, after the scrape
serviceMonitor:
enabled: false
namespace: ""
labels: {}
annotations: {}
interval: ""
scrapeTimeout: ""
honorLabels: false
relabelings: []
metricRelabelings: []
## @param podMonitor.enabled Create a PodMonitor for each component whose metrics are enabled
## @param podMonitor.namespace Namespace the PodMonitors are created in, the release one when empty
## @param podMonitor.labels Labels of the PodMonitors, which the Prometheus Operator selects them by (e.g. release: kube-prometheus-stack)
## @param podMonitor.annotations Annotations of the PodMonitors
## @param podMonitor.interval Scrape interval, the Prometheus default when empty
## @param podMonitor.scrapeTimeout Scrape timeout, the Prometheus default when empty
## @param podMonitor.honorLabels Keep the labels of the scraped samples when they clash with the target ones
## @param podMonitor.relabelings Relabelings of the targets, before the scrape
## @param podMonitor.metricRelabelings Relabelings of the samples, after the scrape
podMonitor:
enabled: false
namespace: ""
labels: {}
annotations: {}
interval: ""
scrapeTimeout: ""
honorLabels: false
relabelings: []
metricRelabelings: []
## @param ingressMedia.enabled whether to enable the Ingress or not
## @param ingressMedia.className IngressClass to use for the Ingress
## @param ingressMedia.host Host for the Ingress
@@ -319,6 +373,19 @@ backend:
envVars: {}
envFrom: []
## @param backend.metrics.enabled Serve the prometheus metrics of the backend on /metrics of the web pods, scraped over plain http inside the cluster. Sets PROMETHEUS_METRICS_ENABLED and PROMETHEUS_METRICS_SSL_REDIRECT_EXEMPT on the django container, and not on celery, unless backend.envVars sets them. Requires PROMETHEUS_API_KEY in backend.envVars
## @param backend.metrics.apiKeySecret.name Secret the monitors read the bearer token from. Defaults to the secretKeyRef of backend.envVars.PROMETHEUS_API_KEY
## @param backend.metrics.apiKeySecret.key Key of the bearer token in that Secret
##
## The token has to come from a Secret for a monitor to present it: either a
## secretKeyRef in backend.envVars.PROMETHEUS_API_KEY, which is enough, or
## PROMETHEUS_API_KEY_FILE pointing at a mounted one, named here.
metrics:
enabled: false
apiKeySecret:
name: ""
key: ""
## @param backend.podAnnotations Annotations to add to the backend Pod
podAnnotations: {}
@@ -1002,11 +1069,16 @@ yhub:
## @param yhub.metrics.port Port the metrics are served on. Added to the yhub Service, and to a Service of its own for the worker
## @param yhub.metrics.path Path the server serves its metrics on, which is the path ingressMetrics publishes them at
## @param yhub.metrics.workerPath Path the worker serves its metrics on, which is the path ingressMetrics publishes them at
## @param yhub.metrics.apiKeySecret.name Secret the monitors read the bearer token from. Defaults to the secretKeyRef of PROMETHEUS_API_KEY in yhub.envVars (yhub.worker.envVars for the worker)
## @param yhub.metrics.apiKeySecret.key Key of the bearer token in that Secret
metrics:
enabled: false
port: 9464
path: /metrics/yhub
workerPath: /metrics/yhub-worker
apiKeySecret:
name: ""
key: ""
## @param yhub.worker.enabled Deploy the worker apart from the server, each scaling on its own
## @param yhub.worker.replicas Amount of yhub worker replicas