diff --git a/backend/Dockerfile b/backend/Dockerfile index f7bfa8c..fe7a5fe 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -23,8 +23,10 @@ RUN npm ci --omit=dev COPY . . # Create a non-root user for security +# Grant write access to /app so the auto-updater can extract files RUN adduser --system --uid 1001 backenduser \ - && chown -R backenduser /app + && chown -R backenduser /app \ + && chmod -R u+w /app # Switch to the non-root user USER backenduser diff --git a/backend/main.py b/backend/main.py index 3c3bdc1..42c1e49 100644 --- a/backend/main.py +++ b/backend/main.py @@ -498,7 +498,14 @@ from services.updater import perform_update, schedule_restart @limiter.limit("1/minute") async def system_update(request: Request): """Download latest release, backup current files, extract update, and restart.""" - project_root = str(Path(__file__).resolve().parent.parent) + # In Docker, __file__ is /app/main.py so .parent.parent resolves to / + # which causes PermissionError. Use cwd as fallback when parent.parent + # doesn't contain frontend/ or backend/ (i.e. we're already at project root). + candidate = Path(__file__).resolve().parent.parent + if (candidate / "frontend").is_dir() or (candidate / "backend").is_dir(): + project_root = str(candidate) + else: + project_root = os.getcwd() result = perform_update(project_root) if result.get("status") == "error": return Response(