Deploy server 2.1.0; keep filled-in secrets out of git

- kustomization pins mg4-server 2.1.0 by digest; server.yaml sets
  PUBLIC_URL for the pairing QR code; the secrets template gains
  APPROVAL_PASSWORD.
- Filled-in Secrets now go into k8s/secrets.yaml, which is gitignored;
  the template stays on placeholders. This follows a leak where real
  values typed into the template were committed and pushed (amended and
  force-pushed since; both values regenerated).
- SPECS.md records pairing and the incident.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
This commit is contained in:
2026-10-17 16:16:52 +02:00
co-authored by Claude Opus 5.5
parent c578a882bd
commit 59ee2cae3b
6 changed files with 34 additions and 15 deletions
+7 -5
View File
@@ -11,7 +11,8 @@ is applied automatically. Apply them yourself.
| `grafana.yaml` | Grafana 13.2.3 Deployment (1Gi PVC), Service; datasource and dashboards provisioned |
| `grafana/` | The provisioned InfluxDB datasource and the MG4 dashboards (Live, Consumption, Charging) |
| `ingress.yaml` | Traefik `IngressRoute`s for car.stinnesbeck.com and Grafana, TLS from Traefik's default certificate |
| `secrets.example.yaml` | **Template** for the Secrets; not in `kustomization.yaml` |
| `secrets.example.yaml` | **Template** for the Secrets; placeholders only, not in `kustomization.yaml` |
| `secrets.yaml` | Your filled-in copy — **gitignored**, never committed |
| `kustomization.yaml` | Everything except the Secrets; pins the server image, generates the Grafana ConfigMaps |
## Before the first apply
@@ -19,9 +20,10 @@ is applied automatically. Apply them yourself.
1. **Check `ingress.yaml`:** the ingress class (placeholder `traefik-external` for the public
Traefik) and Grafana's host (placeholder `car-grafana.stinnesbeck.com`). Both hosts must be
covered by Traefik's default certificate.
2. **Create the Secrets.** Copy `secrets.example.yaml` outside the repository, replace every
`CHANGE-ME` (`openssl rand -hex 32`), then apply the copy: `influxdb-auth`, `mg4-server`
(ingest token, your ABRP API key and user token) and `grafana-admin`.
2. **Create the Secrets.** `cp k8s/secrets.example.yaml k8s/secrets.yaml` (gitignored), replace
every `CHANGE-ME` there (`openssl rand -hex 32`): `influxdb-auth`, `mg4-server` (ingest token,
approval password for pairing, your ABRP API key and user token) and `grafana-admin`. Keep
`secrets.example.yaml` itself on placeholders only.
3. **Registry access.** The `mg4-server` package on git.stinnesbeck.com is public, so no pull
secret is needed. If you make it private, add an `imagePullSecrets` entry to `server.yaml`.
@@ -29,7 +31,7 @@ is applied automatically. Apply them yourself.
```sh
kubectl apply -f k8s/namespace.yaml
kubectl apply -f <your filled-in secrets file>
kubectl apply -f k8s/secrets.yaml
kubectl apply -k k8s/
```
+2 -2
View File
@@ -10,8 +10,8 @@ resources:
- ingress.yaml
images:
- name: git.stinnesbeck.com/nils/mg4-server
# 2.0.0, pinned by digest so a re-pushed tag cannot change what runs.
digest: sha256:6feea777c514b9488ffb0b49fad7c15423ee06f0e0e8d609cf31eb85755da815
# 2.1.0, pinned by digest so a re-pushed tag cannot change what runs.
digest: sha256:e5f6e2d2ef9dc2650055a0823a3f86d8903e46918a76e990540482edf819766d
generatorOptions:
labels:
app.kubernetes.io/part-of: mg4
+5 -2
View File
@@ -1,5 +1,5 @@
# TEMPLATE ONLY — not part of kustomization.yaml. Copy it outside the repository, fill in
# real values, and apply that copy yourself. Never commit the filled-in file.
# TEMPLATE ONLY — not part of kustomization.yaml. Copy it to k8s/secrets.yaml (gitignored),
# fill in real values there, and apply that file yourself. Never put real values in here.
#
# openssl rand -hex 32 for every token and password below
apiVersion: v1
@@ -22,6 +22,9 @@ stringData:
# The car's write token, entered in the app. At least 24 characters, or the server
# refuses to start.
INGEST_TOKEN: CHANGE-ME-openssl-rand-hex-32
# Approves a car on your phone when it pairs by QR code (at least 12 characters). Leave it
# empty to switch pairing off; then only the INGEST_TOKEN above works.
APPROVAL_PASSWORD: CHANGE-ME-at-least-12-characters
# Your ABRP credentials. Leave either empty to switch forwarding off.
ABRP_API_KEY: CHANGE-ME
ABRP_USER_TOKEN: CHANGE-ME
+5 -1
View File
@@ -40,12 +40,16 @@ spec:
value: mg4
- name: INFLUX_BUCKET
value: mg4
# Where a phone reaches the server; the pairing QR code points here.
- name: PUBLIC_URL
value: https://car.stinnesbeck.com
- name: INFLUX_TOKEN
valueFrom:
secretKeyRef:
name: influxdb-auth
key: admin-token
# INGEST_TOKEN, ABRP_API_KEY, ABRP_USER_TOKEN, ABRP_MIN_INTERVAL_SECONDS.
# INGEST_TOKEN, APPROVAL_PASSWORD, ABRP_API_KEY, ABRP_USER_TOKEN,
# ABRP_MIN_INTERVAL_SECONDS.
envFrom:
- secretRef:
name: mg4-server