fix(docker): make instance directory configurable and writable
- Add INSTANCE_BASE_PATH config option (defaults to /data/instances) - Update docker.py to use configured path instead of hardcoded 'data/instances' - Update Dockerfile to create /data/instances and chown to appuser - Add instance_data volume to docker-compose.traefik.yml and docker-compose.yml - Set INSTANCE_BASE_PATH env var in both compose files This fixes the PermissionError when creating tool instances because appuser can now write to /data/instances.
This commit is contained in:
+2
-2
@@ -35,8 +35,8 @@ ENV PATH=/home/appuser/.local/bin:$PATH
|
|||||||
# Copy application code
|
# Copy application code
|
||||||
COPY --chown=appuser:appgroup . .
|
COPY --chown=appuser:appgroup . .
|
||||||
|
|
||||||
# Create directories for repo storage
|
# Create directories for repo and instance storage
|
||||||
RUN mkdir -p /data/repos && chown -R appuser:appgroup /data/repos
|
RUN mkdir -p /data/repos /data/instances && chown -R appuser:appgroup /data
|
||||||
|
|
||||||
# Copy wait-for-db script
|
# Copy wait-for-db script
|
||||||
COPY wait-for-db.sh /usr/local/bin/wait-for-db.sh
|
COPY wait-for-db.sh /usr/local/bin/wait-for-db.sh
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ class Settings(BaseSettings):
|
|||||||
# Repository storage
|
# Repository storage
|
||||||
repo_base_path: str = "/data/repos"
|
repo_base_path: str = "/data/repos"
|
||||||
|
|
||||||
|
# Tool instance storage
|
||||||
|
instance_base_path: str = "/data/instances"
|
||||||
|
|
||||||
model_config = SettingsConfigDict(env_file=".env", extra="ignore", populate_by_name=True)
|
model_config = SettingsConfigDict(env_file=".env", extra="ignore", populate_by_name=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -23,16 +23,19 @@ def render_compose_template(template: str, variables: dict[str, Any]) -> str:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def ensure_instance_directory(instance_id: str, base_path: str = "data/instances") -> str:
|
def ensure_instance_directory(instance_id: str, base_path: str | None = None) -> str:
|
||||||
"""Create and return the instance directory path.
|
"""Create and return the instance directory path.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
instance_id: Unique instance identifier
|
instance_id: Unique instance identifier
|
||||||
base_path: Base directory for all instances
|
base_path: Base directory for all instances (defaults to Settings.instance_base_path)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Absolute path to instance directory
|
Absolute path to instance directory
|
||||||
"""
|
"""
|
||||||
|
if base_path is None:
|
||||||
|
from src.config import Settings
|
||||||
|
base_path = Settings().instance_base_path
|
||||||
instance_dir = Path(base_path) / instance_id
|
instance_dir = Path(base_path) / instance_id
|
||||||
instance_dir.mkdir(parents=True, exist_ok=True)
|
instance_dir.mkdir(parents=True, exist_ok=True)
|
||||||
return str(instance_dir.absolute())
|
return str(instance_dir.absolute())
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ services:
|
|||||||
SESSION_SECRET: ${SESSION_SECRET:-change-me-in-production}
|
SESSION_SECRET: ${SESSION_SECRET:-change-me-in-production}
|
||||||
SESSION_TTL_HOURS: ${SESSION_TTL_HOURS:-24}
|
SESSION_TTL_HOURS: ${SESSION_TTL_HOURS:-24}
|
||||||
REPO_BASE_PATH: /data/repos
|
REPO_BASE_PATH: /data/repos
|
||||||
|
INSTANCE_BASE_PATH: /data/instances
|
||||||
API_DOMAIN: ${API_DOMAIN}
|
API_DOMAIN: ${API_DOMAIN}
|
||||||
WEB_DOMAIN: ${WEB_DOMAIN}
|
WEB_DOMAIN: ${WEB_DOMAIN}
|
||||||
AUTHENTIK_DOMAIN: ${AUTHENTIK_DOMAIN}
|
AUTHENTIK_DOMAIN: ${AUTHENTIK_DOMAIN}
|
||||||
@@ -92,6 +93,7 @@ services:
|
|||||||
AUTHENTIK_TOKEN_URL: ${AUTHENTIK_TOKEN_URL:-}
|
AUTHENTIK_TOKEN_URL: ${AUTHENTIK_TOKEN_URL:-}
|
||||||
volumes:
|
volumes:
|
||||||
- repo_data:/data/repos
|
- repo_data:/data/repos
|
||||||
|
- instance_data:/data/instances
|
||||||
- avatar_uploads:/app/uploads
|
- avatar_uploads:/app/uploads
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
@@ -114,6 +116,7 @@ volumes:
|
|||||||
postgres_data:
|
postgres_data:
|
||||||
redis_data:
|
redis_data:
|
||||||
repo_data:
|
repo_data:
|
||||||
|
instance_data:
|
||||||
avatar_uploads:
|
avatar_uploads:
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
+4
-1
@@ -53,10 +53,12 @@ services:
|
|||||||
POSTGRES_HOST: postgres
|
POSTGRES_HOST: postgres
|
||||||
POSTGRES_PORT: 5432
|
POSTGRES_PORT: 5432
|
||||||
REDIS_URL: redis://redis:6379/0
|
REDIS_URL: redis://redis:6379/0
|
||||||
JWT_SECRET: ${JWT_SECRET:-change-me-in-production}
|
SESSION_SECRET: ${SESSION_SECRET:-change-me-in-production}
|
||||||
REPO_BASE_PATH: /data/repos
|
REPO_BASE_PATH: /data/repos
|
||||||
|
INSTANCE_BASE_PATH: /data/instances
|
||||||
volumes:
|
volumes:
|
||||||
- repo_data:/data/repos
|
- repo_data:/data/repos
|
||||||
|
- instance_data:/data/instances
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -90,6 +92,7 @@ volumes:
|
|||||||
postgres_data:
|
postgres_data:
|
||||||
redis_data:
|
redis_data:
|
||||||
repo_data:
|
repo_data:
|
||||||
|
instance_data:
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
backend:
|
backend:
|
||||||
|
|||||||
Reference in New Issue
Block a user