From 2c77532d35599b002a79265ca8cff4f1192e30c9 Mon Sep 17 00:00:00 2001 From: Holden Date: Fri, 12 Jun 2026 00:21:01 +0000 Subject: [PATCH] refactor: slim image with proper multi-stage build and --no-dev deps - Dockerfile: separate runtime stage from build stage so g++, python3.12-dev, curl, gnupg are excluded from the final image - uv sync --no-dev: drop ruff/pytest from production image - Remove build.sh (replaced by CI) and root-level upload_tracker.py (stale duplicate) - .gitignore: add *.log Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 3 +- Dockerfile | 30 +++++++++++++----- build.sh | 20 ------------ upload_tracker.py | 78 ----------------------------------------------- 4 files changed, 25 insertions(+), 106 deletions(-) delete mode 100755 build.sh delete mode 100644 upload_tracker.py diff --git a/.gitignore b/.gitignore index b104c37..8248ec9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -# Custom +# Custom frigate_train/ +*.log runs/ yolov9c.pt .insightface/ diff --git a/Dockerfile b/Dockerfile index a358115..98e767c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,14 +16,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ curl \ gnupg \ - && rm -rf /var/lib/apt/lists/* - -RUN apt-get update && apt-get install -y --no-install-recommends \ software-properties-common \ && add-apt-repository ppa:deadsnakes/ppa -y \ && apt-get update && apt-get install -y --no-install-recommends \ python3.12 python3.12-venv python3.12-dev \ - libgl1 libglib2.0-0 libxext6 g++ tini \ + libgl1 libglib2.0-0 libxext6 g++ \ && rm -rf /var/lib/apt/lists/* \ && ln -sf /usr/bin/python3.12 /usr/bin/python3 @@ -33,7 +30,7 @@ RUN curl -LsSf https://astral.sh/uv/install.sh | sh \ WORKDIR /app COPY pyproject.toml uv.lock ./ -RUN uv sync --frozen \ +RUN uv sync --frozen --no-dev \ && uv cache clean COPY if_curator/ if_curator/ @@ -41,7 +38,27 @@ COPY entrypoint.sh scheduler.py ./ RUN chmod +x /app/entrypoint.sh # ── Runtime stage ───────────────────────────────────────────────────────── -FROM build AS runtime +# Starts fresh from the base image — excludes build tools (g++, +# python3.12-dev, curl, gnupg) that are not needed at runtime. + +FROM base-${TARGETARCH} AS runtime + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + software-properties-common \ + tini \ + && add-apt-repository ppa:deadsnakes/ppa -y \ + && apt-get update && apt-get install -y --no-install-recommends \ + python3.12 python3.12-venv \ + libgl1 libglib2.0-0 libxext6 \ + && rm -rf /var/lib/apt/lists/* \ + && ln -sf /usr/bin/python3.12 /usr/bin/python3 + +# Copy app (with .venv) and uv from build stage +COPY --from=build /app /app +COPY --from=build /usr/local/bin/uv /usr/local/bin/uv # Expose CUDA/cuDNN libraries from pip packages so onnxruntime-gpu # can find libcublasLt.so.12 and libcudnn.so.9 at runtime @@ -56,4 +73,3 @@ ENV HF_HOME=/models/huggingface INSIGHTFACE_HOME=/models HEALTHCHECK CMD test -f /app/entrypoint.sh || exit 1 ENTRYPOINT ["tini", "--", "/app/entrypoint.sh"] - diff --git a/build.sh b/build.sh deleted file mode 100755 index e2daf0b..0000000 --- a/build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -set -e - -# --- Configuration --- -COMMIT_MSG="automated update: $(date '+%Y-%m-%d %H:%M:%S')" - -# --- Git Sync --- -echo "💾 Committing and pushing changes to GitHub..." - -git add . - -# Only proceed if there are actual changes to commit -if ! git diff-index --quiet HEAD --; then - git commit -m "$COMMIT_MSG" - git push - echo "✅ Changes pushed. GitHub Actions will now build and deploy the image." -else - echo "ℹ️ No changes detected; nothing to push." -fi - diff --git a/upload_tracker.py b/upload_tracker.py deleted file mode 100644 index 1bbbe68..0000000 --- a/upload_tracker.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Persistent tracker for Immich asset IDs already uploaded to Frigate. - -Prevents duplicate uploads across runs by recording each successfully -uploaded asset ID in a JSON file within the configured CACHE_DIR. -""" - -import json -import logging -from pathlib import Path - -logger = logging.getLogger(__name__) - -UPLOAD_TRACKER_FILE = "frigate_uploaded_ids.json" - - -def _tracker_path() -> Path: - """Return path to the tracker file, using Config.CACHE_DIR if available.""" - try: - from .config import Config - - return Path(Config.CACHE_DIR) / UPLOAD_TRACKER_FILE - except (ImportError, AttributeError): - return Path(UPLOAD_TRACKER_FILE) - - -def load_uploaded_ids() -> set[str]: - """Load the set of Immich asset IDs already uploaded to Frigate.""" - path = _tracker_path() - if not path.exists(): - return set() - try: - with open(path) as f: - data = json.load(f) - return set(data.get("uploaded_asset_ids", [])) - except (json.JSONDecodeError, OSError) as e: - logger.warning(f"Could not load upload tracker: {e}") - return set() - - -def save_uploaded_ids(uploaded_ids: set[str]) -> None: - """Persist the set of uploaded Immich asset IDs to disk.""" - path = _tracker_path() - path.parent.mkdir(parents=True, exist_ok=True) - with open(path, "w") as f: - json.dump({"uploaded_asset_ids": sorted(uploaded_ids)}, f, indent=2) - - -def mark_uploaded(asset_id: str) -> None: - """Mark a single Immich asset ID as uploaded to Frigate.""" - ids = load_uploaded_ids() - ids.add(asset_id) - save_uploaded_ids(ids) - logger.debug(f"Marked asset {asset_id} as uploaded to Frigate") - - -def is_uploaded(asset_id: str) -> bool: - """Check if an Immich asset ID has already been uploaded to Frigate.""" - return asset_id in load_uploaded_ids() - - -def filter_already_uploaded(asset_ids: list[str]) -> list[str]: - """Return only asset IDs that have NOT yet been uploaded to Frigate. - - Logs how many were skipped so the user knows dedup is working. - """ - uploaded = load_uploaded_ids() - new_ids = [aid for aid in asset_ids if aid not in uploaded] - skipped = len(asset_ids) - len(new_ids) - if skipped: - logger.info(f"Skipping {skipped} assets already uploaded to Frigate") - return new_ids - - -def reset_uploaded_ids() -> None: - """Clear the tracker — useful for re-training from scratch.""" - save_uploaded_ids(set()) - logger.info("Cleared Frigate upload tracker") -