Dockerfile
| 1 | # MuseHub — Production Dockerfile |
| 2 | # Multi-stage build: builder installs deps into wheels; runtime copies only the wheels. |
| 3 | # |
| 4 | # Layer invalidation guide (when to rebuild): |
| 5 | # requirements.txt changed → docker compose build musehub |
| 6 | # Python code changed → no rebuild (override.yml bind-mounts musehub/ tests/ etc.) |
| 7 | |
| 8 | FROM python:3.14-slim AS builder |
| 9 | |
| 10 | WORKDIR /app |
| 11 | |
| 12 | RUN apt-get update && apt-get install -y --no-install-recommends \ |
| 13 | build-essential \ |
| 14 | && rm -rf /var/lib/apt/lists/* |
| 15 | |
| 16 | COPY requirements.txt . |
| 17 | RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt |
| 18 | |
| 19 | |
| 20 | FROM python:3.14-slim AS runtime |
| 21 | |
| 22 | WORKDIR /app |
| 23 | |
| 24 | RUN groupadd -r musehub && useradd -r -g musehub musehub |
| 25 | |
| 26 | RUN apt-get update && apt-get install -y --no-install-recommends \ |
| 27 | libpq5 \ |
| 28 | git \ |
| 29 | && rm -rf /var/lib/apt/lists/* |
| 30 | |
| 31 | COPY --from=builder /app/wheels /wheels |
| 32 | RUN pip install --no-cache-dir /wheels/* |
| 33 | |
| 34 | COPY --chown=musehub:musehub musehub/ ./musehub/ |
| 35 | COPY --chown=musehub:musehub alembic/ ./alembic/ |
| 36 | COPY --chown=musehub:musehub tourdeforce/ ./tourdeforce/ |
| 37 | COPY --chown=musehub:musehub alembic.ini pyproject.toml ./ |
| 38 | |
| 39 | COPY --chown=musehub:musehub entrypoint.sh ./entrypoint.sh |
| 40 | RUN chmod +x ./entrypoint.sh |
| 41 | |
| 42 | RUN mkdir -p /data && chown -R musehub:musehub /data && chmod 755 /data |
| 43 | |
| 44 | USER musehub |
| 45 | |
| 46 | ENV PYTHONPATH=/app |
| 47 | ENV PYTHONDONTWRITEBYTECODE=1 |
| 48 | ENV PYTHONUNBUFFERED=1 |
| 49 | |
| 50 | EXPOSE 10003 |
| 51 | |
| 52 | HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \ |
| 53 | CMD python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:10003/api/v1/openapi.json')" || exit 1 |
| 54 | |
| 55 | ENTRYPOINT ["./entrypoint.sh"] |