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>
67 lines
2.9 KiB
Python
67 lines
2.9 KiB
Python
"""TTS Voice Creator - Clone and Design — FastAPI entry point (thin wrapper)."""
|
|
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
|
|
|
|
from core.constants import STATIC_DIR, _BufferHandler
|
|
from routes import admin, settings, library, stt, sources, docker, tts, conversation
|
|
|
|
logger = logging.getLogger("uvicorn.error")
|
|
|
|
# ── App ───────────────────────────────────────────────────────────────────────
|
|
|
|
app = FastAPI(title="TTS Voice Creator - Clone and Design")
|
|
|
|
# ── In-memory log buffer handler ──────────────────────────────────────────────
|
|
|
|
_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)
|
|
app.include_router(settings.router)
|
|
app.include_router(library.router)
|
|
app.include_router(stt.router)
|
|
app.include_router(sources.router)
|
|
app.include_router(docker.router)
|
|
app.include_router(tts.router)
|
|
app.include_router(conversation.router)
|
|
|
|
# ── Static files ──────────────────────────────────────────────────────────────
|
|
|
|
app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static")
|
|
|
|
# ── Dev runner ────────────────────────────────────────────────────────────────
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
uvicorn.run(app, host="0.0.0.0", port=7890, log_level="info")
|