Files
mg4/k8s/server.yaml
T
nilsandClaude Opus 5.5 6be2ba5193 App 2.39.1, server 2.8.0: map roads from OpenFreeMap, on demand
The public Overpass answered 429/502 and needs ~40 s a tile while the
car gives up after 8 s, so the server cancelled its queries and the
car's retries added load. Now the server fetches only the tiles a car
asks for, as OpenStreetMap vector tiles from OpenFreeMap (MAP_TILES_URL),
decodes the transportation layer with a small reader of its own, and
keeps each tile 30 days on a volume (MAP_CACHE_DIR). A fetch finishes
even after the car has stopped waiting; the car hears 503 with
Retry-After and gets the tile on its next try.

App: OpenFreeMap/OpenMapTiles attribution on the map, retry after 15 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
2026-10-26 23:54:30 +01:00

130 lines
3.8 KiB
YAML

# The car server (Go). One replica on purpose: pending pairing requests and the wrong-password
# counters are kept in memory.
# The roads of the app's Grid map, fetched on demand, are kept on this small volume.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mg4-server-maps
namespace: mg4
labels:
app.kubernetes.io/name: mg4-server
app.kubernetes.io/part-of: mg4
spec:
accessModes: ["ReadWriteOnce"]
# No storageClassName: the cluster's default class is used.
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mg4-server
namespace: mg4
labels:
app.kubernetes.io/name: mg4-server
app.kubernetes.io/part-of: mg4
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: mg4-server
template:
metadata:
labels:
app.kubernetes.io/name: mg4-server
app.kubernetes.io/part-of: mg4
spec:
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
containers:
- name: server
# Pinned by digest so a re-pushed tag cannot change what runs (version in SPECS.md).
image: git.stinnesbeck.com/nils/mg4-server@sha256:e5da9452a9dbdfabe3340766cc51f18bb1418b2588ab534714550470abe1ce29
ports:
- name: http
containerPort: 8080
env:
- name: INFLUX_URL
value: http://influxdb.mg4.svc:8086
- name: INFLUX_ORG
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.k8s.stinnesbeck.com
# App updates: the releases of this repository, relayed to the car. Read with
# FORGE_TOKEN from the mg4-server Secret; leave that empty to switch updates off.
- name: FORGE_URL
value: https://git.stinnesbeck.com
- name: FORGE_REPO
value: nils/mg4
# The roads for the app's Grid map: OpenStreetMap vector tiles, fetched only for the
# tiles a car asks for and kept on the volume below; "off" switches maps off.
- name: MAP_TILES_URL
value: https://tiles.openfreemap.org/planet
- name: MAP_CACHE_DIR
value: /var/cache/mg4-maps
- name: INFLUX_TOKEN
valueFrom:
secretKeyRef:
name: influxdb-auth
key: admin-token
# INGEST_TOKEN, APPROVAL_PASSWORD, FORGE_TOKEN.
envFrom:
- secretRef:
name: mg4-server
readinessProbe:
httpGet:
path: /v1/health
port: http
periodSeconds: 10
livenessProbe:
httpGet:
path: /v1/health
port: http
initialDelaySeconds: 5
periodSeconds: 30
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 128Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: maps
mountPath: /var/cache/mg4-maps
volumes:
- name: maps
persistentVolumeClaim:
claimName: mg4-server-maps
---
apiVersion: v1
kind: Service
metadata:
name: mg4-server
namespace: mg4
labels:
app.kubernetes.io/name: mg4-server
app.kubernetes.io/part-of: mg4
spec:
selector:
app.kubernetes.io/name: mg4-server
ports:
- name: http
port: 80
targetPort: http