# syntax=docker/dockerfile:1 # --------------------------------------------------------------------------- # danbooru-mcp — Dockerfile # # Stages: # base – Python 3.12 slim + system deps # scraper – runs scripts/scrape_tags.py to build db/tags.db # (only executes if no pre-built DB is bind-mounted) # runtime – minimal image that runs src/server.py (MCP stdio server) # # Usage: # Build (includes fresh DB scrape — takes ~15 min first time): # docker build -t danbooru-mcp . # # Run (MCP clients invoke via stdio): # docker run --rm -i danbooru-mcp # # Or use docker-compose (recommended — mounts a persistent DB volume): # docker compose up # --------------------------------------------------------------------------- ARG PYTHON_VERSION=3.12 # --------------------------------------------------------------------------- # Stage 1: base — shared deps # --------------------------------------------------------------------------- FROM python:${PYTHON_VERSION}-slim AS base WORKDIR /app # System deps: sqlite3 is already in python:slim # gcc needed for some wheels; curl for healthcheck RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY scripts/ scripts/ COPY src/ src/ # --------------------------------------------------------------------------- # Stage 2: scraper — build the SQLite database # --------------------------------------------------------------------------- FROM base AS scraper ARG DANBOORU_USER="" ARG DANBOORU_API_KEY="" ENV DANBOORU_USER=${DANBOORU_USER} ENV DANBOORU_API_KEY=${DANBOORU_API_KEY} # Run the scraper — will create db/tags.db with all tags ≥10 posts RUN mkdir -p db && \ python scripts/scrape_tags.py --no-fts && \ echo "Scrape complete. Rebuilding FTS5 index…" && \ python - <<'EOF' import sqlite3, pathlib conn = sqlite3.connect("db/tags.db") conn.execute("INSERT INTO tags_fts(tags_fts) VALUES('rebuild')") conn.commit() conn.close() print("FTS5 index built.") EOF # --------------------------------------------------------------------------- # Stage 3: runtime — lean image with pre-built DB # --------------------------------------------------------------------------- FROM python:${PYTHON_VERSION}-slim AS runtime WORKDIR /app # Install only runtime deps (no gcc) COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copy source COPY src/ src/ # Copy the scraped database from the scraper stage COPY --from=scraper /app/db/tags.db db/tags.db # The MCP server communicates via stdio — no ports needed ENV DANBOORU_TAGS_DB=/app/db/tags.db # Non-root user for security RUN useradd --no-create-home --shell /bin/false mcpuser && \ chown -R mcpuser:mcpuser /app USER mcpuser # Health check: verify the DB is readable HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ CMD python -c "import sqlite3; c=sqlite3.connect('/app/db/tags.db'); print(c.execute('SELECT COUNT(*) FROM tags').fetchone()[0]); c.close()" ENTRYPOINT ["python", "src/server.py"]