gabriel / musehub public
Dockerfile
61 lines 2.3 KB
Raw
sha256:bb2baaabdd19320bde50cb69d447fd1c1e571467df729be1a23b5e93064b046a feat(intel): standardize headers, gauge icon, velocity card… Sonnet 4.6 minor ⚠ breaking 137 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 && rm -rf /var/lib/apt/lists/*
35
36 COPY --from=builder /app/wheels /wheels
37 RUN pip install --no-cache-dir /wheels/*
38
39 COPY --chown=musehub:musehub musehub/musehub/ ./musehub/
40 COPY --chown=musehub:musehub musehub/alembic/ ./alembic/
41 COPY --chown=musehub:musehub musehub/alembic.ini musehub/pyproject.toml ./
42 COPY --chown=musehub:musehub musehub/docs/ ./docs/
43 COPY --chown=musehub:musehub musehub/deploy/ ./deploy/
44
45 COPY --chown=musehub:musehub musehub/entrypoint.sh ./entrypoint.sh
46 RUN chmod +x ./entrypoint.sh
47
48 RUN mkdir -p /data && chown -R musehub:musehub /data && chmod 755 /data
49
50 USER musehub
51
52 ENV PYTHONPATH=/app
53 ENV PYTHONDONTWRITEBYTECODE=1
54 ENV PYTHONUNBUFFERED=1
55
56 EXPOSE 1337
57
58 HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \
59 CMD python3 -c "import urllib.request, ssl, os; url='https://localhost:1337/healthz' if os.path.exists('/tls/localhost.crt') else 'http://localhost:1337/healthz'; ctx=(lambda c: (setattr(c,'check_hostname',False), setattr(c,'verify_mode',ssl.CERT_NONE), c)[-1])(ssl.create_default_context()) if url.startswith('https') else None; r=urllib.request.urlopen(url, context=ctx); exit(0 if r.status==200 else 1)" || exit 1
60
61 ENTRYPOINT ["./entrypoint.sh"]
File History 1 commit
sha256:bb2baaabdd19320bde50cb69d447fd1c1e571467df729be1a23b5e93064b046a feat(intel): standardize headers, gauge icon, velocity card… Sonnet 4.6 minor 137 days ago