2026-03-31 03:39:52 +00:00
|
|
|
# syntax=docker/dockerfile:1
|
|
|
|
|
# ── Stage 1: Build ──────────────────────────────────────────────────────────────
|
|
|
|
|
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder
|
|
|
|
|
|
|
|
|
|
WORKDIR /app
|
|
|
|
|
|
|
|
|
|
# Install dependencies first (cached layer)
|
|
|
|
|
COPY pyproject.toml uv.lock ./
|
|
|
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
|
|
|
uv sync --frozen --no-install-project --no-dev
|
|
|
|
|
|
|
|
|
|
# Copy source and install project
|
|
|
|
|
COPY unraid_mcp/ unraid_mcp/
|
2026-04-03 05:09:21 +00:00
|
|
|
RUN touch README.md LICENSE
|
2026-03-31 03:39:52 +00:00
|
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
|
|
|
uv sync --frozen --no-dev
|
|
|
|
|
|
|
|
|
|
# ── Stage 2: Runtime ────────────────────────────────────────────────────────────
|
|
|
|
|
FROM python:3.12-slim-bookworm AS runtime
|
|
|
|
|
|
|
|
|
|
RUN groupadd --gid 1000 mcp && \
|
|
|
|
|
useradd --uid 1000 --gid mcp --create-home mcp
|
|
|
|
|
|
|
|
|
|
WORKDIR /app
|
|
|
|
|
|
|
|
|
|
# Copy the virtual environment from builder
|
|
|
|
|
COPY --from=builder /app/.venv /app/.venv
|
|
|
|
|
COPY --from=builder /app/unraid_mcp /app/unraid_mcp
|
|
|
|
|
|
|
|
|
|
# Ensure .venv/bin is on PATH
|
|
|
|
|
ENV PATH="/app/.venv/bin:$PATH" \
|
|
|
|
|
PYTHONUNBUFFERED=1 \
|
|
|
|
|
PYTHONDONTWRITEBYTECODE=1
|
|
|
|
|
|
2026-03-31 03:52:04 +00:00
|
|
|
# Create directories with correct ownership.
|
|
|
|
|
# /home/mcp/.unraid-mcp is pre-created so Docker named volume mounts inherit mcp ownership.
|
|
|
|
|
RUN mkdir -p /app/logs /app/backups /home/mcp/.unraid-mcp && \
|
|
|
|
|
chown -R mcp:mcp /app/logs /app/backups /home/mcp/.unraid-mcp && \
|
|
|
|
|
chmod 700 /home/mcp/.unraid-mcp
|
2026-03-31 03:39:52 +00:00
|
|
|
|
|
|
|
|
# Default env — overridden by .env / docker-compose
|
|
|
|
|
ENV UNRAID_MCP_TRANSPORT=streamable-http \
|
|
|
|
|
UNRAID_MCP_HOST=0.0.0.0 \
|
|
|
|
|
UNRAID_MCP_PORT=6970 \
|
|
|
|
|
UNRAID_MCP_LOG_LEVEL=INFO
|
|
|
|
|
|
|
|
|
|
EXPOSE 6970
|
|
|
|
|
|
fix(hooks): align sync-env/ensure-ignore-files with plugin spec (cw1.1, ova)
- sync-env.sh: replace sed with awk for safe value replacement, add flock
on /tmp/unraid-sync-env.lock, remove auto-token-generation (fail with
clear error if UNRAID_MCP_BEARER_TOKEN not set)
- ensure-ignore-files.sh: rename from ensure-gitignore.sh, add --check mode
that exits non-zero without modifying file (for CI/pre-commit use)
- hooks.json: update both references to new ensure-ignore-files.sh name
- docker-compose.yaml: add user PUID/PGID, external network, deploy.resources
limits (1024M/1cpu), wget healthcheck, start_period=30s
- Dockerfile: install wget, use wget healthcheck, start_period=30s,
add entrypoint.sh, ENTRYPOINT points to /entrypoint.sh
- entrypoint.sh: env validation (UNRAID_API_URL, UNRAID_API_KEY,
UNRAID_MCP_BEARER_TOKEN) with exec for signal forwarding
- .env.example: add PUID, PGID, DOCKER_NETWORK, UNRAID_MCP_ALLOW_DESTRUCTIVE,
UNRAID_MCP_ALLOW_YOLO; fix UNRAID_MCP_BEARER_TOKEN key name
2026-03-31 21:58:48 +00:00
|
|
|
RUN apt-get update && apt-get install -y --no-install-recommends wget && rm -rf /var/lib/apt/lists/*
|
|
|
|
|
|
|
|
|
|
COPY entrypoint.sh /entrypoint.sh
|
|
|
|
|
RUN chmod +x /entrypoint.sh
|
|
|
|
|
|
2026-03-31 03:39:52 +00:00
|
|
|
USER mcp
|
|
|
|
|
|
fix(hooks): align sync-env/ensure-ignore-files with plugin spec (cw1.1, ova)
- sync-env.sh: replace sed with awk for safe value replacement, add flock
on /tmp/unraid-sync-env.lock, remove auto-token-generation (fail with
clear error if UNRAID_MCP_BEARER_TOKEN not set)
- ensure-ignore-files.sh: rename from ensure-gitignore.sh, add --check mode
that exits non-zero without modifying file (for CI/pre-commit use)
- hooks.json: update both references to new ensure-ignore-files.sh name
- docker-compose.yaml: add user PUID/PGID, external network, deploy.resources
limits (1024M/1cpu), wget healthcheck, start_period=30s
- Dockerfile: install wget, use wget healthcheck, start_period=30s,
add entrypoint.sh, ENTRYPOINT points to /entrypoint.sh
- entrypoint.sh: env validation (UNRAID_API_URL, UNRAID_API_KEY,
UNRAID_MCP_BEARER_TOKEN) with exec for signal forwarding
- .env.example: add PUID, PGID, DOCKER_NETWORK, UNRAID_MCP_ALLOW_DESTRUCTIVE,
UNRAID_MCP_ALLOW_YOLO; fix UNRAID_MCP_BEARER_TOKEN key name
2026-03-31 21:58:48 +00:00
|
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
|
|
|
|
CMD wget --quiet --tries=1 --spider \
|
|
|
|
|
"http://localhost:${UNRAID_MCP_PORT:-6970}/health" || exit 1
|
2026-03-31 03:39:52 +00:00
|
|
|
|
fix(hooks): align sync-env/ensure-ignore-files with plugin spec (cw1.1, ova)
- sync-env.sh: replace sed with awk for safe value replacement, add flock
on /tmp/unraid-sync-env.lock, remove auto-token-generation (fail with
clear error if UNRAID_MCP_BEARER_TOKEN not set)
- ensure-ignore-files.sh: rename from ensure-gitignore.sh, add --check mode
that exits non-zero without modifying file (for CI/pre-commit use)
- hooks.json: update both references to new ensure-ignore-files.sh name
- docker-compose.yaml: add user PUID/PGID, external network, deploy.resources
limits (1024M/1cpu), wget healthcheck, start_period=30s
- Dockerfile: install wget, use wget healthcheck, start_period=30s,
add entrypoint.sh, ENTRYPOINT points to /entrypoint.sh
- entrypoint.sh: env validation (UNRAID_API_URL, UNRAID_API_KEY,
UNRAID_MCP_BEARER_TOKEN) with exec for signal forwarding
- .env.example: add PUID, PGID, DOCKER_NETWORK, UNRAID_MCP_ALLOW_DESTRUCTIVE,
UNRAID_MCP_ALLOW_YOLO; fix UNRAID_MCP_BEARER_TOKEN key name
2026-03-31 21:58:48 +00:00
|
|
|
ENTRYPOINT ["/entrypoint.sh"]
|