Move the server to car.k8s.stinnesbeck.com
The server's host is car.k8s.stinnesbeck.com, not car.stinnesbeck.com: IngressRoute, PUBLIC_URL (so the pairing QR code points there), the app's pre-filled server URL and hint, and the docs. Grafana's placeholder host follows to car-grafana.k8s.stinnesbeck.com, so one *.k8s.stinnesbeck.com default certificate covers both. App 2.4.1 for the new default; the server image is unchanged (its URL comes from the manifest). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
This commit is contained in:
@@ -7,17 +7,17 @@ what has been changed, and what is still to do.
|
||||
- Upstream: https://github.com/fatihdonmezdev/FatihsMG4 (itself a fork of malys / EVABRPUploader
|
||||
and Leon Kernan / ABRP_Uploader). Credited in the app's About dialog.
|
||||
|
||||
## Architecture: car server at car.stinnesbeck.com
|
||||
## Architecture: car server at car.k8s.stinnesbeck.com
|
||||
|
||||
The car sends everything to our own server. The server stores it in InfluxDB 2 and forwards live
|
||||
telemetry to ABRP, so the ABRP token lives only on the server, never in the APK. Grafana reads
|
||||
InfluxDB directly for the dashboards.
|
||||
|
||||
```
|
||||
car ──live telemetry───▶ car.stinnesbeck.com (Go) ──▶ ABRP api.iternio.com/1/tlm/send
|
||||
car ──live telemetry───▶ car.k8s.stinnesbeck.com (Go) ──▶ ABRP api.iternio.com/1/tlm/send
|
||||
──daily chunks─────▶ │
|
||||
──charging sessions▶ ▼
|
||||
InfluxDB 2 ◀── Grafana (car-grafana.stinnesbeck.com)
|
||||
InfluxDB 2 ◀── Grafana (car-grafana.k8s.stinnesbeck.com)
|
||||
```
|
||||
|
||||
- **Server:** `server/`, Go 1.26, API only — see `server/README.md` for endpoints, configuration
|
||||
@@ -42,7 +42,7 @@ car ──live telemetry───▶ car.stinnesbeck.com (Go) ──▶ ABRP ap
|
||||
- [x] Image `mg4-server:2.1.0` (with pairing) pushed to git.stinnesbeck.com (public; pinned by
|
||||
digest `sha256:e5f6e2d2…` in `k8s/kustomization.yaml`).
|
||||
- [ ] Check in `k8s/ingress.yaml`: the Traefik ingress class (placeholder `traefik-external`) and
|
||||
Grafana's host (placeholder `car-grafana.stinnesbeck.com`).
|
||||
Grafana's host (placeholder `car-grafana.k8s.stinnesbeck.com`).
|
||||
- [ ] First pairing and drive with 2.4.0: telemetry arrives in InfluxDB, Grafana and ABRP.
|
||||
|
||||
## To do
|
||||
|
||||
+2
-2
@@ -34,8 +34,8 @@ android {
|
||||
applicationId "com.stinnesbeck.nilsmg4"
|
||||
minSdk 27
|
||||
targetSdk 36
|
||||
versionCode 58
|
||||
versionName "2.4.0"
|
||||
versionCode 59
|
||||
versionName "2.4.1"
|
||||
|
||||
// Nothing about the server ships in the APK: its URL and ingest token are entered in
|
||||
// the app's Server tab (ServerConfig), and the database is only reachable by the server.
|
||||
|
||||
@@ -7,7 +7,7 @@ package com.evsuite.abrp;
|
||||
*
|
||||
* <pre>
|
||||
* # Nils' MG4 config
|
||||
* server_url = https://car.stinnesbeck.com
|
||||
* server_url = https://car.k8s.stinnesbeck.com
|
||||
* token = 0123abcd... (the server's INGEST_TOKEN)
|
||||
* installation_id = 6f1a2b3c-4d5e-4f60-8a9b-0c1d2e3f4a5b
|
||||
* interval_sec = 60
|
||||
|
||||
@@ -28,7 +28,7 @@ final class ServerConfig {
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/** Pre-filled so pairing needs no typing in the car; can still be changed. */
|
||||
static final String DEFAULT_URL = "https://car.stinnesbeck.com";
|
||||
static final String DEFAULT_URL = "https://car.k8s.stinnesbeck.com";
|
||||
|
||||
/** The server refuses shorter ingest tokens outright. */
|
||||
static final int MIN_TOKEN_LENGTH = 24;
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<!-- Server page -->
|
||||
<string name="server_card_title">Car server</string>
|
||||
<string name="hint_server_url">Server URL</string>
|
||||
<string name="helper_server_url">For example https://car.stinnesbeck.com</string>
|
||||
<string name="helper_server_url">For example https://car.k8s.stinnesbeck.com</string>
|
||||
<string name="hint_server_token">Ingest token</string>
|
||||
<string name="helper_server_token">The server\'s INGEST_TOKEN, at least 24 characters</string>
|
||||
<string name="hint_installation_id">Installation ID</string>
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
# Kubernetes manifests — car.stinnesbeck.com
|
||||
# Kubernetes manifests — car.k8s.stinnesbeck.com
|
||||
|
||||
Plain manifests for the car server, InfluxDB 2 and Grafana. They are only files: nothing here
|
||||
is applied automatically. Apply them yourself.
|
||||
@@ -10,7 +10,7 @@ is applied automatically. Apply them yourself.
|
||||
| `server.yaml` | Go server Deployment (1 replica, non-root, read-only root filesystem) and Service |
|
||||
| `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 |
|
||||
| `ingress.yaml` | Traefik `IngressRoute`s for car.k8s.stinnesbeck.com and Grafana, TLS from Traefik's default certificate |
|
||||
| `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 |
|
||||
@@ -18,7 +18,7 @@ is applied automatically. Apply them yourself.
|
||||
## Before the first apply
|
||||
|
||||
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
|
||||
Traefik) and Grafana's host (placeholder `car-grafana.k8s.stinnesbeck.com`). Both hosts must be
|
||||
covered by Traefik's default certificate.
|
||||
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,
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ spec:
|
||||
containerPort: 3000
|
||||
env:
|
||||
- name: GF_SERVER_ROOT_URL
|
||||
value: https://car-grafana.stinnesbeck.com
|
||||
value: https://car-grafana.k8s.stinnesbeck.com
|
||||
- name: GF_SECURITY_ADMIN_USER
|
||||
value: admin
|
||||
- name: GF_SECURITY_ADMIN_PASSWORD
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ spec:
|
||||
- websecure
|
||||
routes:
|
||||
- kind: Rule
|
||||
match: Host(`car.stinnesbeck.com`)
|
||||
match: Host(`car.k8s.stinnesbeck.com`)
|
||||
services:
|
||||
- kind: Service
|
||||
name: mg4-server
|
||||
@@ -35,7 +35,7 @@ spec:
|
||||
routes:
|
||||
- kind: Rule
|
||||
# CHECK: placeholder host. It must be covered by Traefik's default certificate.
|
||||
match: Host(`car-grafana.stinnesbeck.com`)
|
||||
match: Host(`car-grafana.k8s.stinnesbeck.com`)
|
||||
services:
|
||||
- kind: Service
|
||||
name: grafana
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ spec:
|
||||
value: mg4
|
||||
# Where a phone reaches the server; the pairing QR code points here.
|
||||
- name: PUBLIC_URL
|
||||
value: https://car.stinnesbeck.com
|
||||
value: https://car.k8s.stinnesbeck.com
|
||||
- name: INFLUX_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
# Nils' MG4 — car server
|
||||
|
||||
A small Go service at car.stinnesbeck.com: the API the car writes to, and the ABRP
|
||||
A small Go service at car.k8s.stinnesbeck.com: the API the car writes to, and the ABRP
|
||||
forwarder. Data lives in InfluxDB 2; Grafana reads it from there for the dashboards
|
||||
(`../k8s/grafana/`).
|
||||
|
||||
@@ -61,8 +61,8 @@ the same bucket), and the device is persisted before the car can collect the tok
|
||||
restart never loses a paired car. Manage cars with the approval password:
|
||||
|
||||
```sh
|
||||
curl -H "Authorization: Bearer $APPROVAL_PASSWORD" https://car.stinnesbeck.com/v1/devices
|
||||
curl -X POST -H "Authorization: Bearer $APPROVAL_PASSWORD" https://car.stinnesbeck.com/v1/devices/<id>/revoke
|
||||
curl -H "Authorization: Bearer $APPROVAL_PASSWORD" https://car.k8s.stinnesbeck.com/v1/devices
|
||||
curl -X POST -H "Authorization: Bearer $APPROVAL_PASSWORD" https://car.k8s.stinnesbeck.com/v1/devices/<id>/revoke
|
||||
```
|
||||
|
||||
## Storage
|
||||
|
||||
Reference in New Issue
Block a user