# syntax=docker/dockerfile:1.7

# Service-flavored image. Includes the [server] extra (aiosqlite, Starlette,
# uvicorn, authlib, cryptography, jinja2, itsdangerous) so the same image
# can run either:
#   docker run … inoreader-mcp serve              # stdio (single-user)
#   docker run … inoreader-mcp serve --http       # multi-user HTTP
#
# For the multi-user mode, a real deployment runs this behind a reverse
# proxy (Caddy/nginx) that handles TLS — see compose.yml + Caddyfile.

FROM python:3.12-slim AS base

# `uv` ships as a tiny static binary; copy it from the official image to avoid
# re-resolving it inside this layer.
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

WORKDIR /app

# Dependencies first so the layer is cacheable on source-only changes.
COPY pyproject.toml uv.lock README.md LICENSE /app/
COPY src /app/src

# `--frozen` pins the exact versions from uv.lock. `--all-extras` pulls the
# [server] dependencies; if you only need stdio, build a derivative image
# with `--no-default-groups` and the deps will be skipped.
RUN uv sync --frozen --no-dev --all-extras

# Required for stdio: tokens live under XDG. Mount this dir from the host
# so refresh tokens persist across container restarts.
#   docker run -v ~/.config/inoreader-mcp:/root/.config/inoreader-mcp \
#     -e INOREADER_APP_ID=... -e INOREADER_APP_KEY=... \
#     ghcr.io/ibrapk/inoreader-mcp serve
#
# Required for HTTP: see README + compose.yml.
ENV INOREADER_APP_ID=""
ENV INOREADER_APP_KEY=""

# When running in --http mode, the service binds to $PORT (default 8765).
EXPOSE 8765

# `/healthz` returns 200 unconditionally — works as soon as the process is up,
# even if INOREADER_MCP_ENCRYPTION_KEY etc. are misconfigured (so the operator
# can debug a stuck container instead of just looking at "unhealthy").
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
    CMD wget -qO- http://127.0.0.1:8765/healthz || exit 1

ENTRYPOINT ["uv", "run", "--frozen", "inoreader-mcp"]
CMD ["serve"]
