From 1db0167bfcd0c236bbc7fd9d8f5652a1417a3d79 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 14 May 2026 07:42:04 -0400 Subject: [PATCH] feat: add Dockerfile for web/worker/scheduler roles and entrypoint script Multi-stage build: node:20 builds the SPA, python:3.12-slim runs the app. Same image handles web, worker, scheduler roles via entrypoint.sh's first arg. ffmpeg + unar are baked in for FC-2's transcode + archive paths. Co-Authored-By: Claude Opus 4.7 (1M context) --- Dockerfile | 44 +++++++++++++++++++++++++++++++++++++ entrypoint.sh | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 Dockerfile create mode 100755 entrypoint.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..78620da --- /dev/null +++ b/Dockerfile @@ -0,0 +1,44 @@ +# syntax=docker/dockerfile:1.7 + +FROM node:20-alpine AS frontend-builder +WORKDIR /build +COPY frontend/package.json frontend/package-lock.json* ./ +RUN npm ci --no-audit --no-fund +COPY frontend/ ./ +RUN npm run build + +FROM python:3.12-slim AS runtime +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + PIP_NO_CACHE_DIR=1 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 + +# System deps: ffmpeg (transcode + thumbnails, used in FC-2), unar (archives, FC-2), +# libpq for psycopg, image libs. +RUN apt-get update && apt-get install -y --no-install-recommends \ + ffmpeg \ + unar \ + libpq5 \ + libjpeg62-turbo \ + libwebp7 \ + libpng16-16 \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY requirements.txt ./ +RUN pip install -r requirements.txt + +COPY backend/ ./backend/ +COPY alembic/ ./alembic/ +COPY alembic.ini ./ +COPY entrypoint.sh ./ +RUN chmod +x entrypoint.sh + +COPY --from=frontend-builder /build/dist ./frontend/dist + +EXPOSE 8080 + +ENTRYPOINT ["./entrypoint.sh"] +CMD ["web"] diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..53a6f6a --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROLE="${1:-web}" +shift || true + +case "$ROLE" in + web) + echo "[entrypoint] Running alembic upgrade head" + alembic upgrade head + echo "[entrypoint] Starting hypercorn on :8080" + exec hypercorn \ + --bind 0.0.0.0:8080 \ + --workers "${HYPERCORN_WORKERS:-2}" \ + --access-logfile - \ + backend.app:create_app + ;; + + worker) + QUEUES="${CELERY_QUEUES:-default,import,thumbnail}" + CONCURRENCY="${CELERY_CONCURRENCY:-2}" + echo "[entrypoint] Starting Celery worker queues=$QUEUES concurrency=$CONCURRENCY" + exec celery -A backend.app.celery_app:celery worker \ + --loglevel=info \ + -Q "$QUEUES" \ + --concurrency="$CONCURRENCY" + ;; + + scheduler) + QUEUES="${CELERY_QUEUES:-maintenance,scan}" + echo "[entrypoint] Starting Celery beat+worker queues=$QUEUES" + exec celery -A backend.app.celery_app:celery worker \ + --beat \ + --loglevel=info \ + -Q "$QUEUES" \ + --concurrency=1 + ;; + + ml-worker) + echo "[entrypoint] Starting ML Celery worker (ml queue)" + exec celery -A backend.app.celery_app:celery worker \ + --loglevel=info \ + -Q ml \ + --concurrency=1 + ;; + + shell|bash) + exec /bin/bash "$@" + ;; + + alembic) + exec alembic "$@" + ;; + + *) + echo "[entrypoint] Unknown role: $ROLE" >&2 + echo "[entrypoint] Valid roles: web | worker | scheduler | ml-worker | shell | alembic" >&2 + exit 1 + ;; +esac