Replace named Docker volume with local bind-mount folders

config/ and logs/ are now host directories visible on the filesystem.

- docker-compose.yml: ./config → /home/app/.config/tts-voice-creator:rw
                      ./logs   → /logs:rw
  Named volume tts-voice-creator-clone-and-design-2 removed.
- portainer-stack.yml: same change with absolute host paths.
- server.py: RotatingFileHandler writes INFO+ to /logs/app.log
  (maxBytes=5MB, backupCount=3). Falls back gracefully if /logs
  is not writable.
- .gitignore: track config/ and logs/ dirs via .gitkeep but exclude
  settings.json, *.log and backups from version control.

Benefits:
- Settings and logs are human-readable on the host at any time
- Survives docker-compose down -v (was lost with named volume)
- Easy backup: cp -r config/ logs/ to any destination
- Can edit settings.json directly if needed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mARTin-B78 2026-05-29 15:31:46 +02:00
parent 2ee3432bbc
commit 7f35d32f3e
7 changed files with 48 additions and 8 deletions

7
.gitignore vendored
View File

@ -31,3 +31,10 @@ voice_design_presets.json
# Personal documentation (not part of the public repo)
APP_ERKLÄRUNG.md
# Local bind-mount data — keep directory, ignore contents
config/settings.json
config/voice_design_presets.json
config/tts_routes.json
logs/*.log
logs/*.log.*

View File

@ -7,6 +7,20 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
## [Unreleased]
### Changed
- **Config and logs are now bind-mounted local folders** — replaced the
opaque named Docker volume (`tts-voice-creator-clone-and-design-2`) with
two transparent host directories:
- `./config/``/home/app/.config/tts-voice-creator` — holds
`settings.json`, `voice_design_presets.json`, `tts_routes.json`
- `./logs/``/logs` — holds `app.log` (rotates at 5 MB, 3 backups)
Both directories are tracked in git (via `.gitkeep`) but their runtime
contents are excluded from version control via `.gitignore`.
`portainer-stack.yml` updated with absolute host paths.
- **Server writes a rotating log file**`RotatingFileHandler` added to
`server.py`; writes `INFO`-level and above to `./logs/app.log`.
### Fixed
- **Engine settings lost after container recreate** — container names and

0
config/.gitkeep Normal file
View File

View File

@ -16,7 +16,8 @@ services:
volumes:
- ${VOICE_HOST_DIR:-./voices}:/voices:rw
- tts-voice-creator-clone-and-design-2:/home/app/.config/tts-voice-creator
- ./config:/home/app/.config/tts-voice-creator:rw # settings, presets, routes
- ./logs:/logs:rw # application logs
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./static:/app/static:ro
- ./server.py:/app/server.py:ro
@ -37,9 +38,6 @@ services:
networks:
- dgx_net
volumes:
tts-voice-creator-clone-and-design-2:
networks:
dgx_net:
external: true

0
logs/.gitkeep Normal file
View File

View File

@ -27,7 +27,8 @@ services:
volumes:
- /home/sparky/Projekte/TTS_Voices:/voices:rw
- tts-voice-creator-clone-and-design-2:/home/app/.config/tts-voice-creator
- /home/sparky/Docker/tts-voice-creator-clone-and-design-2/config:/home/app/.config/tts-voice-creator:rw
- /home/sparky/Docker/tts-voice-creator-clone-and-design-2/logs:/logs:rw
- /var/run/docker.sock:/var/run/docker.sock:ro
# ── Hot-reload mounts (changes apply on container recreate, not restart) ──
- /home/sparky/Docker/tts-voice-creator-clone-and-design-2/server.py:/app/server.py:ro
@ -48,9 +49,6 @@ services:
networks:
- dgx_net
volumes:
tts-voice-creator-clone-and-design-2:
networks:
dgx_net:
external: true

View File

@ -2,6 +2,9 @@
from __future__ import annotations
import logging
import os
from logging.handlers import RotatingFileHandler
from pathlib import Path
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
@ -21,6 +24,26 @@ _buf_handler = _BufferHandler()
_buf_handler.setLevel(logging.DEBUG)
logging.getLogger().addHandler(_buf_handler)
# ── File log handler (rotates at 5 MB, keeps 3 files) ────────────────────────
_LOG_DIR = Path(os.environ.get("LOG_DIR", "/logs"))
try:
_LOG_DIR.mkdir(parents=True, exist_ok=True)
_file_handler = RotatingFileHandler(
_LOG_DIR / "app.log",
maxBytes=5 * 1024 * 1024,
backupCount=3,
encoding="utf-8",
)
_file_handler.setLevel(logging.INFO)
_file_handler.setFormatter(logging.Formatter(
"%(asctime)s %(levelname)-8s %(name)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
))
logging.getLogger().addHandler(_file_handler)
except Exception as _log_err:
logger.warning("Could not set up file logging at %s: %s", _LOG_DIR, _log_err)
# ── Routers ───────────────────────────────────────────────────────────────────
app.include_router(admin.router)