From 643504d89bb851f866a368d9624b285e42e1f50e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 30 Mar 2026 23:35:12 +0000 Subject: [PATCH] fix: infrastructure hardening and documentation improvements - Add *.sqlite* patterns to .gitignore - Expand .dockerignore to exclude chart/, docs/, .github/, etc. - Add HEALTHCHECK instruction to Dockerfile - Fix Helm chart: preserve JWT secret across upgrades (lookup), add securityContext, conditional PVC creation, resource defaults - Remove hardcoded demo credentials from MCP.md - Complete .env.example with all configurable environment variables https://claude.ai/code/session_01SoQKcF5Rz9Y8Nzo4PzkxY8 --- .dockerignore | 18 ++++++++++++++++++ .gitignore | 3 +++ Dockerfile | 3 +++ MCP.md | 5 ----- chart/templates/deployment.yaml | 6 ++++++ chart/templates/pvc.yaml | 2 ++ chart/templates/secret.yaml | 8 +++++++- chart/values.yaml | 8 +++++++- server/.env.example | 33 +++++++++++++++++++++++++++++++-- 9 files changed, 77 insertions(+), 9 deletions(-) diff --git a/.dockerignore b/.dockerignore index 4ab0f62..d9ee946 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,6 +5,24 @@ client/dist data uploads .git +.github .env +.env.* *.log *.md +!client/**/*.md +chart/ +docs/ +docker-compose.yml +unraid-template.xml +*.sqlite +*.sqlite-shm +*.sqlite-wal +*.db +*.db-shm +*.db-wal +coverage +.DS_Store +Thumbs.db +.vscode +.idea diff --git a/.gitignore b/.gitignore index 44d3160..595a6b5 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ client/public/icons/*.png *.db *.db-shm *.db-wal +*.sqlite +*.sqlite-shm +*.sqlite-wal # User data server/data/ diff --git a/Dockerfile b/Dockerfile index 8a301c7..332e545 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,5 +39,8 @@ ENV PORT=3000 EXPOSE 3000 +HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \ + CMD wget -qO- http://localhost:3000/api/health || exit 1 + # Entrypoint: fix volume permissions then start as node CMD ["sh", "-c", "chown -R node:node /app/data /app/uploads 2>/dev/null; exec su-exec node node --import tsx src/index.ts"] diff --git a/MCP.md b/MCP.md index 0b64b52..8fe54a4 100644 --- a/MCP.md +++ b/MCP.md @@ -229,11 +229,6 @@ Currency: CHF. Use get_trip_summary at the end and give me a quick recap of everything that was added. ``` -Database file: https://share.jubnl.ch/s/S7bBpj42mB - -Email: admin@admin.com \ -Password: admin123 - PDF of the generated trip: [./docs/TREK-Generated-by-MCP.pdf](./docs/TREK-Generated-by-MCP.pdf) ![trip](./docs/screenshot-trip-mcp.png) \ No newline at end of file diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml index d10957e..25169f6 100644 --- a/chart/templates/deployment.yaml +++ b/chart/templates/deployment.yaml @@ -20,10 +20,16 @@ spec: - name: {{ .name }} {{- end }} {{- end }} + securityContext: + fsGroup: 1000 containers: - name: trek image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} ports: - containerPort: 3000 envFrom: diff --git a/chart/templates/pvc.yaml b/chart/templates/pvc.yaml index 663bff5..d68f693 100644 --- a/chart/templates/pvc.yaml +++ b/chart/templates/pvc.yaml @@ -1,3 +1,4 @@ +{{- if .Values.persistence.enabled }} apiVersion: v1 kind: PersistentVolumeClaim metadata: @@ -23,3 +24,4 @@ spec: resources: requests: storage: {{ .Values.persistence.uploads.size }} +{{- end }} diff --git a/chart/templates/secret.yaml b/chart/templates/secret.yaml index b27596a..6ead7f1 100644 --- a/chart/templates/secret.yaml +++ b/chart/templates/secret.yaml @@ -11,13 +11,19 @@ data: {{- end }} {{- if and (not .Values.existingSecret) (.Values.generateJwtSecret) }} +{{- $secretName := printf "%s-secret" (include "trek.fullname" .) }} +{{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace $secretName) }} apiVersion: v1 kind: Secret metadata: - name: {{ include "trek.fullname" . }}-secret + name: {{ $secretName }} labels: app: {{ include "trek.name" . }} type: Opaque stringData: + {{- if and $existingSecret $existingSecret.data }} + {{ .Values.existingSecretKey | default "JWT_SECRET" }}: {{ index $existingSecret.data (.Values.existingSecretKey | default "JWT_SECRET") | b64dec }} + {{- else }} {{ .Values.existingSecretKey | default "JWT_SECRET" }}: {{ randAlphaNum 32 }} + {{- end }} {{- end }} diff --git a/chart/values.yaml b/chart/values.yaml index f52f3de..0d9d0c9 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -38,7 +38,13 @@ persistence: uploads: size: 1Gi -resources: {} +resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi ingress: enabled: false diff --git a/server/.env.example b/server/.env.example index 4e2e99e..a4ffe68 100644 --- a/server/.env.example +++ b/server/.env.example @@ -1,4 +1,33 @@ -PORT=3001 -JWT_SECRET=your-super-secret-jwt-key-change-in-production +PORT=3000 NODE_ENV=development DEBUG=false + +# REQUIRED for production — generate with: openssl rand -hex 32 +JWT_SECRET=CHANGEME_GENERATE_WITH_openssl_rand_hex_32 + +# Timezone (defaults to system timezone) +# TZ=UTC + +# CORS — comma-separated origins (leave unset for same-origin in production, allow-all in development) +# ALLOWED_ORIGINS=https://trek.example.com + +# Force HTTPS redirect (set to true behind TLS-terminating proxy) +# FORCE_HTTPS=true + +# Trust proxy (set to number of proxy hops, e.g. 1 for single reverse proxy) +# TRUST_PROXY=1 + +# Application URL (used for OIDC callback validation) +# APP_URL=https://trek.example.com + +# Demo mode (enables demo login, disables registration) +# DEMO_MODE=false + +# --- OIDC / SSO --- +# OIDC_ISSUER=https://auth.example.com +# OIDC_CLIENT_ID= +# OIDC_CLIENT_SECRET= +# OIDC_DISPLAY_NAME=SSO +# OIDC_ONLY=false +# OIDC_ADMIN_CLAIM=groups +# OIDC_ADMIN_VALUE=app-trek-admins