fix: enable uvx/PyPI deployments without Docker assumptions
Two bugs made `uvx --from . nextcloud-mcp-server run` (and any pip install) unusable outside Docker: 1. Dynaconf was configured with ignore_unknown_envvars=True and relied on settings.toml to declare the key schema. With no settings.toml in a wheel install, every env var (NEXTCLOUD_HOST, MCP_DEPLOYMENT_MODE, ...) was silently dropped. Moved the schema into a Python _DEFAULTS dict passed directly to Dynaconf, kept settings.toml as an optional external override (renamed to settings.toml.example, gitignored), and pointed docker-compose at the example file. 2. Token SQLite DB defaulted to /app/data/tokens.db in multiple places (auth/storage.py, migrations.py, alembic/env.py, cli.py db subcommands), which blew up at uvicorn startup with FileNotFoundError on non-Docker hosts. Replaced with a new config.get_token_db_path() helper that resolves TOKEN_STORAGE_DB if explicitly set, otherwise allocates a per-process tempfile cleaned up at interpreter exit via atexit — mirroring the "ephemeral by default" pattern used for QDRANT_LOCATION=:memory:. Containers are unaffected: docker-compose services now explicitly set TOKEN_STORAGE_DB=/app/data/tokens.db (the fourth service that was missing this pin has been brought in line with the other three). Verified end-to-end in an isolated /tmp venv: env-var-only startup, Alembic migrations run against the tempfile, Application startup complete, /health/live returns 200, tempfile deleted on SIGTERM. Unit tests (464) + ruff + ty pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
fd1846de03
commit
146b622ebf
@@ -39,6 +39,7 @@ import httpx
|
||||
from anyio import to_thread
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
from nextcloud_mcp_server.config import get_token_db_path, is_ephemeral_token_db
|
||||
from nextcloud_mcp_server.migrations import stamp_database, upgrade_database
|
||||
from nextcloud_mcp_server.observability.metrics import record_db_operation
|
||||
|
||||
@@ -82,7 +83,10 @@ class RefreshTokenStorage:
|
||||
Create storage instance from environment variables.
|
||||
|
||||
Environment variables:
|
||||
TOKEN_STORAGE_DB: Path to database file (default: /app/data/tokens.db)
|
||||
TOKEN_STORAGE_DB: Path to database file. If unset, a per-process
|
||||
tempfile is allocated and deleted at interpreter exit —
|
||||
tokens are ephemeral and wiped on restart. Set this to a
|
||||
filesystem path to persist tokens across restarts.
|
||||
TOKEN_ENCRYPTION_KEY: Optional base64-encoded Fernet key (required for token storage)
|
||||
|
||||
Returns:
|
||||
@@ -92,7 +96,13 @@ class RefreshTokenStorage:
|
||||
If TOKEN_ENCRYPTION_KEY is not set, token storage operations will fail,
|
||||
but webhook tracking will still work.
|
||||
"""
|
||||
db_path = os.getenv("TOKEN_STORAGE_DB", "/app/data/tokens.db")
|
||||
db_path = get_token_db_path()
|
||||
if is_ephemeral_token_db(db_path):
|
||||
logger.info(
|
||||
"Using ephemeral token storage at %s "
|
||||
"(set TOKEN_STORAGE_DB to persist tokens across restarts)",
|
||||
db_path,
|
||||
)
|
||||
encryption_key_b64 = os.getenv("TOKEN_ENCRYPTION_KEY")
|
||||
|
||||
encryption_key = None
|
||||
|
||||
Reference in New Issue
Block a user