fix: move Alembic to package submodule for Docker compatibility
- Move alembic/ directory to nextcloud_mcp_server/alembic/ subpackage - Update migrations.py to use package location instead of alembic.ini - Update env.py to set script_location dynamically - Update alembic.ini for development CLI usage - Fix Dockerfile typo: .vnev -> .venv This fixes FileNotFoundError when running in Docker with non-editable install. The alembic package is now installed with the main package, making it work in both development and production environments. Resolves: Docker startup error 'alembic.ini not found at /app/.venv/lib/python3.12/site-packages/alembic.ini' 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -22,7 +22,7 @@ RUN uv sync --locked --no-dev --no-editable --no-cache
|
|||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
ENV VIRTUAL_ENV=/app/.venv
|
ENV VIRTUAL_ENV=/app/.venv
|
||||||
ENV PATH=/app/.vnev/bin:$PATH
|
ENV PATH=/app/.venv/bin:$PATH
|
||||||
ENV TESSDATA_PREFIX=/usr/share/tesseract-ocr/5/tessdata
|
ENV TESSDATA_PREFIX=/usr/share/tesseract-ocr/5/tessdata
|
||||||
|
|
||||||
ENTRYPOINT ["/app/.venv/bin/nextcloud-mcp-server", "run", "--host", "0.0.0.0"]
|
ENTRYPOINT ["/app/.venv/bin/nextcloud-mcp-server", "run", "--host", "0.0.0.0"]
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[alembic]
|
[alembic]
|
||||||
# Path to migration scripts
|
# Path to migration scripts
|
||||||
script_location = alembic
|
script_location = nextcloud_mcp_server/alembic
|
||||||
|
|
||||||
# Template used to generate migration file names
|
# Template used to generate migration file names
|
||||||
# Default: %%(rev)s_%%(slug)s
|
# Default: %%(rev)s_%%(slug)s
|
||||||
@@ -26,7 +26,7 @@ timezone = utc
|
|||||||
|
|
||||||
# Version location specification
|
# Version location specification
|
||||||
# Supports single or multiple directories
|
# Supports single or multiple directories
|
||||||
version_locations = alembic/versions
|
version_locations = nextcloud_mcp_server/alembic/versions
|
||||||
|
|
||||||
# Path separator for version locations (required to suppress deprecation warning)
|
# Path separator for version locations (required to suppress deprecation warning)
|
||||||
# Use os (for cross-platform compatibility)
|
# Use os (for cross-platform compatibility)
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ logger = logging.getLogger("alembic.env")
|
|||||||
# access to the values within the .ini file in use.
|
# access to the values within the .ini file in use.
|
||||||
config = context.config
|
config = context.config
|
||||||
|
|
||||||
|
# Update script location to point to package location
|
||||||
|
# This allows alembic to find migrations when installed in site-packages
|
||||||
|
script_location = Path(__file__).parent
|
||||||
|
config.set_main_option("script_location", str(script_location))
|
||||||
|
|
||||||
# We don't use SQLAlchemy models, so target_metadata is None
|
# We don't use SQLAlchemy models, so target_metadata is None
|
||||||
# Migrations will be written manually using op.execute() for raw SQL
|
# Migrations will be written manually using op.execute() for raw SQL
|
||||||
target_metadata = None
|
target_metadata = None
|
||||||
@@ -19,33 +19,39 @@ def get_alembic_config(database_path: str | Path | None = None) -> Config:
|
|||||||
"""
|
"""
|
||||||
Get Alembic configuration for programmatic use.
|
Get Alembic configuration for programmatic use.
|
||||||
|
|
||||||
|
Works in both development and installed (Docker) modes by using
|
||||||
|
package location instead of alembic.ini file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
database_path: Path to SQLite database file. If None, uses default
|
database_path: Path to SQLite database file. If None, uses default
|
||||||
from alembic.ini (/app/data/tokens.db)
|
(/app/data/tokens.db for Docker)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Alembic Config object configured for the specified database
|
Alembic Config object configured for the specified database
|
||||||
"""
|
"""
|
||||||
# Get path to alembic.ini (in project root)
|
from nextcloud_mcp_server import alembic as alembic_package
|
||||||
project_root = Path(__file__).parent.parent
|
|
||||||
alembic_ini_path = project_root / "alembic.ini"
|
|
||||||
|
|
||||||
if not alembic_ini_path.exists():
|
# Use package location (works in both editable and installed modes)
|
||||||
raise FileNotFoundError(
|
if alembic_package.__file__ is None:
|
||||||
f"alembic.ini not found at {alembic_ini_path}. "
|
raise RuntimeError("alembic package __file__ is None")
|
||||||
"Ensure Alembic is properly initialized."
|
script_location = Path(alembic_package.__file__).parent
|
||||||
)
|
|
||||||
|
|
||||||
# Create Alembic config
|
# Create config programmatically (no alembic.ini needed at runtime)
|
||||||
config = Config(str(alembic_ini_path))
|
config = Config()
|
||||||
|
config.set_main_option("script_location", str(script_location))
|
||||||
|
config.set_main_option("path_separator", "os") # Suppress deprecation warning
|
||||||
|
|
||||||
# Override database URL if provided
|
# Set database URL
|
||||||
if database_path:
|
if database_path:
|
||||||
db_path = Path(database_path).resolve()
|
db_path = Path(database_path).resolve()
|
||||||
# Use sqlite+aiosqlite:// for async support
|
else:
|
||||||
url = f"sqlite+aiosqlite:///{db_path}"
|
db_path = Path("/app/data/tokens.db") # Default for Docker
|
||||||
config.set_main_option("sqlalchemy.url", url)
|
|
||||||
logger.debug(f"Alembic configured with database: {db_path}")
|
url = f"sqlite+aiosqlite:///{db_path}"
|
||||||
|
config.set_main_option("sqlalchemy.url", url)
|
||||||
|
|
||||||
|
logger.debug(f"Alembic script location: {script_location}")
|
||||||
|
logger.debug(f"Database: {db_path}")
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user