7535feb445
Ships the production serving path (FastAPI upload/map UI + statistical device-category identification) as a lean, reproducible container: - Dockerfile: python:3.10-slim, non-root user, /health HEALTHCHECK, serves uvicorn src.api.main_simple:app. Bakes in the joblib category model and the static rtl_433 protocol table; excludes the 11 GB test corpora and the benched Phase 3B CNN binaries. Built image is 417 MB. - requirements-prod.txt: pins matched to the versions that actually train/serve the model (scikit-learn 1.6.1 / numpy 2.2.6) so joblib.load() stays valid. torch/onnx intentionally absent — the CNN is benched, not on the serving path. - docker-compose.yml: single service, named volume seeds from baked data/ on first run then persists captures_simple.json writes across restarts. - .dockerignore: keeps data/, venv/, vendored firmware, docs out of the image. Validated: image builds, container reports healthy, and the statistical classifier loads + predicts inside the container. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
42 lines
1.6 KiB
Docker
42 lines
1.6 KiB
Docker
# GigLez — production image for the live "simple mode" API.
|
|
# Serves: FastAPI upload/map UI + statistical device-category identification.
|
|
FROM python:3.10-slim
|
|
|
|
# Faster, quieter, unbuffered logs in containers.
|
|
ENV PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PIP_NO_CACHE_DIR=1
|
|
|
|
WORKDIR /app
|
|
|
|
# Dependencies first for layer caching — only re-runs when reqs change.
|
|
COPY requirements-prod.txt ./
|
|
RUN pip install --no-cache-dir -r requirements-prod.txt
|
|
|
|
# Application code + assets the live path needs.
|
|
COPY src/ ./src/
|
|
COPY static/ ./static/
|
|
COPY templates/ ./templates/
|
|
COPY config/ ./config/
|
|
COPY models/category_classifier.joblib ./models/category_classifier.joblib
|
|
|
|
# Seed data: the static rtl_433 protocol table (read-only) and an initial
|
|
# capture store. When /app/data is mounted as a *named volume*, Docker seeds
|
|
# the empty volume from these baked files on first run, then persists writes
|
|
# to captures_simple.json across restarts.
|
|
COPY data/rtl_433_protocols.json data/captures_simple.json data/weather_sensors_found.txt ./data/
|
|
|
|
# Run as a non-root user.
|
|
RUN useradd --create-home --uid 10001 giglez \
|
|
&& chown -R giglez:giglez /app
|
|
USER giglez
|
|
|
|
EXPOSE 8000
|
|
|
|
# Container-native healthcheck hits the app's /health endpoint.
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=15s --retries=3 \
|
|
CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8000/health').status==200 else 1)"
|
|
|
|
# Serve with uvicorn (module app object), not the __main__ dev banner.
|
|
CMD ["uvicorn", "src.api.main_simple:app", "--host", "0.0.0.0", "--port", "8000"]
|