fix(docker): Geocode-Cache-Volume war funktionslos (EISDIR)

Beim Hochfahren des echten Stacks aufgefallen: d9fecb6 mountet ein Named
Volume auf einen DATEIpfad (geocode-cache:/app/geocode-cache.json). Ein Named
Volume ist immer ein Verzeichnis — im laufenden Container liegt an der Stelle
also ein Ordner. Jeder Lese- und Schreibversuch lief in EISDIR und wurde von
den try/catch-Bloecken in utils/geocode.js still verschluckt: der Cache wurde
nie geladen und nie gespeichert.

Im laufenden drohnenfuehrer-backend nachgestellt:
  Schreiben schlaegt fehl: EISDIR - illegal operation on a directory
  Lesen schlaegt fehl:     EISDIR

- Der Cache-Pfad ist jetzt ueber GEOCODE_CACHE_FILE konfigurierbar und faellt
  ohne die Variable auf den bisherigen Ort zurueck.
- Das Volume wird als Verzeichnis unter /app/cache gemountet, die Compose-
  Dateien setzen GEOCODE_CACHE_FILE=/app/cache/geocode-cache.json.
- .dockerignore schliesst geocode-cache.json aus: eine bei lokalen Tests
  entstandene Datei war ueber COPY . . ins Image gewandert und liess den
  Container gar nicht mehr starten ("not a directory").

Geprueft: im neu gebauten nachsuche-backend ist /app/cache/geocode-cache.json
schreibbar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
thomas 2026-09-01 08:25:25 +02:00
parent 6984689c56
commit f3b4b309b6
10 changed files with 35 additions and 7 deletions

View File

@ -39,3 +39,6 @@ docs/
*.swp *.swp
*.swo *.swo
.DS_Store .DS_Store
# Laufzeit-Cache, gehoert nicht ins Image
geocode-cache.json

View File

@ -4,7 +4,12 @@ const path = require('path');
const config = require('../config/env'); const config = require('../config/env');
const logger = require('./logger'); const logger = require('./logger');
const CACHE_FILE = path.join(__dirname, '..', 'geocode-cache.json'); // Pfad konfigurierbar: im Container zeigt GEOCODE_CACHE_FILE in ein
// Verzeichnis-Volume. Ein Named Volume ist immer ein Verzeichnis und kann
// nicht auf einen Dateipfad gemountet werden — vorher lief jeder Lese- und
// Schreibversuch in EISDIR, still verschluckt vom try/catch.
const CACHE_FILE = process.env.GEOCODE_CACHE_FILE
|| path.join(__dirname, '..', 'geocode-cache.json');
const CACHE_SAVE_INTERVAL = 60000; // Save every 60 seconds const CACHE_SAVE_INTERVAL = 60000; // Save every 60 seconds
const CACHE_MAX_ENTRIES = 1000; const CACHE_MAX_ENTRIES = 1000;

View File

@ -28,9 +28,10 @@ services:
- default - default
- jagd-network - jagd-network
volumes: volumes:
- geocode-cache:/app/geocode-cache.json - geocode-cache:/app/cache
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- GEOCODE_CACHE_FILE=/app/cache/geocode-cache.json
- MONGO_URI=mongodb://drohnenfuehrer:${MONGO_PASSWORD}@mongo:27017/drohnenfuehrer?authSource=admin - MONGO_URI=mongodb://drohnenfuehrer:${MONGO_PASSWORD}@mongo:27017/drohnenfuehrer?authSource=admin
# :? statt stiller Leerersetzung — sonst startet das Backend mit # :? statt stiller Leerersetzung — sonst startet das Backend mit
# leerem Secret und beendet sich sofort wieder (Crash-Loop). # leerem Secret und beendet sich sofort wieder (Crash-Loop).

View File

@ -39,3 +39,6 @@ docs/
*.swp *.swp
*.swo *.swo
.DS_Store .DS_Store
# Laufzeit-Cache, gehoert nicht ins Image
geocode-cache.json

View File

@ -4,7 +4,12 @@ const path = require('path');
const config = require('../config/env'); const config = require('../config/env');
const logger = require('./logger'); const logger = require('./logger');
const CACHE_FILE = path.join(__dirname, '..', 'geocode-cache.json'); // Pfad konfigurierbar: im Container zeigt GEOCODE_CACHE_FILE in ein
// Verzeichnis-Volume. Ein Named Volume ist immer ein Verzeichnis und kann
// nicht auf einen Dateipfad gemountet werden — vorher lief jeder Lese- und
// Schreibversuch in EISDIR, still verschluckt vom try/catch.
const CACHE_FILE = process.env.GEOCODE_CACHE_FILE
|| path.join(__dirname, '..', 'geocode-cache.json');
const CACHE_SAVE_INTERVAL = 60000; // Save every 60 seconds const CACHE_SAVE_INTERVAL = 60000; // Save every 60 seconds
const CACHE_MAX_ENTRIES = 1000; const CACHE_MAX_ENTRIES = 1000;

View File

@ -30,9 +30,10 @@ services:
- default - default
- jagd-network - jagd-network
volumes: volumes:
- geocode-cache:/app/geocode-cache.json - geocode-cache:/app/cache
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- GEOCODE_CACHE_FILE=/app/cache/geocode-cache.json
- MONGO_URI=mongodb://nachsuche:${MONGO_PASSWORD}@mongo:27017/nachsuche?authSource=admin - MONGO_URI=mongodb://nachsuche:${MONGO_PASSWORD}@mongo:27017/nachsuche?authSource=admin
# :? statt stiller Leerersetzung — sonst startet das Backend mit # :? statt stiller Leerersetzung — sonst startet das Backend mit
# leerem Secret und beendet sich sofort wieder (Crash-Loop). # leerem Secret und beendet sich sofort wieder (Crash-Loop).

View File

@ -4,7 +4,8 @@ services:
container_name: jagd-portal container_name: jagd-portal
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8090:80" # Port konfigurierbar, damit der Aufbau nicht an einer Belegung scheitert
- "${PORTAL_PORT:-8090}:80"
networks: networks:
- default - default
- jagd-network - jagd-network

View File

@ -39,3 +39,6 @@ docs/
*.swp *.swp
*.swo *.swo
.DS_Store .DS_Store
# Laufzeit-Cache, gehoert nicht ins Image
geocode-cache.json

View File

@ -4,7 +4,12 @@ const path = require('path');
const config = require('../config/env'); const config = require('../config/env');
const logger = require('./logger'); const logger = require('./logger');
const CACHE_FILE = path.join(__dirname, '..', 'geocode-cache.json'); // Pfad konfigurierbar: im Container zeigt GEOCODE_CACHE_FILE in ein
// Verzeichnis-Volume. Ein Named Volume ist immer ein Verzeichnis und kann
// nicht auf einen Dateipfad gemountet werden — vorher lief jeder Lese- und
// Schreibversuch in EISDIR, still verschluckt vom try/catch.
const CACHE_FILE = process.env.GEOCODE_CACHE_FILE
|| path.join(__dirname, '..', 'geocode-cache.json');
const CACHE_SAVE_INTERVAL = 60000; // Save every 60 seconds const CACHE_SAVE_INTERVAL = 60000; // Save every 60 seconds
const CACHE_MAX_ENTRIES = 1000; const CACHE_MAX_ENTRIES = 1000;

View File

@ -28,9 +28,10 @@ services:
- default - default
- jagd-network - jagd-network
volumes: volumes:
- geocode-cache:/app/geocode-cache.json - geocode-cache:/app/cache
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- GEOCODE_CACHE_FILE=/app/cache/geocode-cache.json
- MONGO_URI=mongodb://stoeberhunde:${MONGO_PASSWORD}@mongo:27017/stoeberhunde?authSource=admin - MONGO_URI=mongodb://stoeberhunde:${MONGO_PASSWORD}@mongo:27017/stoeberhunde?authSource=admin
# :? statt stiller Leerersetzung — sonst startet das Backend mit # :? statt stiller Leerersetzung — sonst startet das Backend mit
# leerem Secret und beendet sich sofort wieder (Crash-Loop). # leerem Secret und beendet sich sofort wieder (Crash-Loop).