The async engine needs greenlet at runtime, which the asyncio extra provides. Test-only deps (aiosqlite, pytest-asyncio) stay out of the image. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
50 lines
1.3 KiB
Docker
50 lines
1.3 KiB
Docker
FROM python:3.14-slim
|
|
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
PIP_NO_CACHE_DIR=1 \
|
|
APP_DIR=/home/richie/dotfiles \
|
|
EBOOK_SEARCH_HOST=0.0.0.0 \
|
|
EBOOK_SEARCH_PORT=8070 \
|
|
EBOOK_SEARCH_BM25_INDEX_DIR=/data/bm25
|
|
|
|
WORKDIR ${APP_DIR}
|
|
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends build-essential curl \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY pyproject.toml README.md LICENSE ./
|
|
COPY python ./python
|
|
|
|
RUN python -m pip install --upgrade pip \
|
|
&& python -m pip install \
|
|
"alembic" \
|
|
"beautifulsoup4" \
|
|
"bm25s" \
|
|
"ebooklib" \
|
|
"fastapi" \
|
|
"httpx" \
|
|
"jinja2" \
|
|
"pgvector" \
|
|
"psycopg[binary]" \
|
|
"pydantic" \
|
|
"pydantic-settings" \
|
|
"python-multipart" \
|
|
"sqlalchemy[asyncio]" \
|
|
"tiktoken" \
|
|
"typer" \
|
|
"uvicorn[standard]" \
|
|
"yake" \
|
|
&& python -m pip install --no-deps --editable "${APP_DIR}"
|
|
|
|
RUN useradd --create-home --uid 10001 app \
|
|
&& mkdir -p /data \
|
|
&& chown -R app:app /home/richie /data
|
|
|
|
USER app
|
|
|
|
EXPOSE 8070
|
|
|
|
CMD ["sh", "-c", "exec python -m python.ebook_search.api.main --host \"${EBOOK_SEARCH_HOST}\" --port \"${EBOOK_SEARCH_PORT}\" --log-level \"${EBOOK_SEARCH_LOG_LEVEL:-INFO}\""]
|