gabriel / musehub public
Dockerfile
62 lines 2.0 KB
Raw
sha256:9590cee1e0ccd6c76528f005b95d634d80f5019f0dcb7c371e149adc31d1fb65 refactor: enforce gRPC framing on all MWP wire traffic Sonnet 4.6 minor ⚠ breaking 154 days ago
1 # MuseHub — Production Dockerfile
2 # Build context: ~/ecosystem (parent of musehub/ and muse/).
3 # Multi-stage build: builder installs deps into wheels; runtime copies only the wheels.
4 #
5 # Layer invalidation guide (when to rebuild):
6 # requirements.txt changed → docker compose build musehub
7 # muse/ source changed → rebuild (muse is bundled as a wheel)
8 # Python code changed → no rebuild (override.yml bind-mounts musehub/ tests/ etc.)
9
10 FROM python:3.14-slim AS builder
11
12 WORKDIR /app
13
14 RUN apt-get update && apt-get install -y --no-install-recommends \
15 build-essential \
16 && rm -rf /var/lib/apt/lists/*
17
18 # Build the muse package wheel from source (it lives alongside musehub in the ecosystem).
19 COPY muse/ /tmp/muse/
20 RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels /tmp/muse
21
22 COPY musehub/requirements.txt .
23 RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt
24
25
26 FROM python:3.14-slim AS runtime
27
28 WORKDIR /app
29
30 RUN groupadd -r musehub && useradd -r -g musehub musehub
31
32 RUN apt-get update && apt-get install -y --no-install-recommends \
33 libpq5 \
34 git \
35 && rm -rf /var/lib/apt/lists/*
36
37 COPY --from=builder /app/wheels /wheels
38 RUN pip install --no-cache-dir /wheels/*
39
40 COPY --chown=musehub:musehub musehub/musehub/ ./musehub/
41 COPY --chown=musehub:musehub musehub/alembic/ ./alembic/
42 COPY --chown=musehub:musehub musehub/alembic.ini musehub/pyproject.toml ./
43 COPY --chown=musehub:musehub musehub/docs/ ./docs/
44 COPY --chown=musehub:musehub musehub/deploy/ ./deploy/
45
46 COPY --chown=musehub:musehub musehub/entrypoint.sh ./entrypoint.sh
47 RUN chmod +x ./entrypoint.sh
48
49 RUN mkdir -p /data && chown -R musehub:musehub /data && chmod 755 /data
50
51 USER musehub
52
53 ENV PYTHONPATH=/app
54 ENV PYTHONDONTWRITEBYTECODE=1
55 ENV PYTHONUNBUFFERED=1
56
57 EXPOSE 1337
58
59 HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \
60 CMD python3 -c "import urllib.request; r=urllib.request.urlopen('http://localhost:1337/healthz'); exit(0 if r.status==200 else 1)" || exit 1
61
62 ENTRYPOINT ["./entrypoint.sh"]
File History 1 commit
sha256:9590cee1e0ccd6c76528f005b95d634d80f5019f0dcb7c371e149adc31d1fb65 refactor: enforce gRPC framing on all MWP wire traffic Sonnet 4.6 minor ⚠ 154 days ago