gabriel / musehub public
Dockerfile
76 lines 2.9 KB
Raw
sha256:3ff9c9863a9891bdcde71b4a43228f66d0493e38b7cc1d09fe9eb7de774046b2 feat: add repair-commit wire endpoint (API parity with repa… Opus 4.8 minor ⚠ breaking 1 day 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 cargo \
17 libssl-dev \
18 pkg-config \
19 && rm -rf /var/lib/apt/lists/*
20
21 # Build the muse package wheel from source (it lives alongside musehub in the ecosystem).
22 COPY muse/ /tmp/muse/
23 RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels /tmp/muse
24
25 COPY musehub/requirements.txt .
26
27 # Build cryptography from source with a generic aarch64 CPU target so the Rust
28 # backend avoids optional instructions (sha512, sm3, etc.) that Docker Desktop's
29 # ARM VM doesn't expose. --no-binary forces a source build; the flag has no effect
30 # on x86_64 where the pre-built wheel works fine.
31 RUN RUSTFLAGS="-C target-cpu=generic" \
32 pip wheel --no-cache-dir --no-deps --no-binary cryptography \
33 --wheel-dir /app/wheels cryptography==48.0.0
34
35 # Build all remaining dependencies from pre-built wheels where available.
36 # Exclude cryptography — already built from source above.
37 RUN grep -v '^cryptography' requirements.txt \
38 | pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r /dev/stdin
39
40
41 FROM python:3.14-slim AS runtime
42
43 WORKDIR /app
44
45 RUN groupadd -r musehub && useradd -r -g musehub musehub
46
47 RUN apt-get update && apt-get install -y --no-install-recommends \
48 libpq5 \
49 && rm -rf /var/lib/apt/lists/*
50
51 COPY --from=builder /app/wheels /wheels
52 RUN pip install --no-cache-dir /wheels/*
53
54 COPY --chown=musehub:musehub musehub/musehub/ ./musehub/
55 COPY --chown=musehub:musehub musehub/alembic/ ./alembic/
56 COPY --chown=musehub:musehub musehub/alembic.ini musehub/pyproject.toml ./
57 COPY --chown=musehub:musehub musehub/docs/ ./docs/
58 COPY --chown=musehub:musehub musehub/deploy/ ./deploy/
59
60 COPY --chown=musehub:musehub musehub/entrypoint.sh ./entrypoint.sh
61 RUN chmod +x ./entrypoint.sh
62
63 RUN mkdir -p /data && chown -R musehub:musehub /data && chmod 755 /data
64
65 USER musehub
66
67 ENV PYTHONPATH=/app
68 ENV PYTHONDONTWRITEBYTECODE=1
69 ENV PYTHONUNBUFFERED=1
70
71 EXPOSE 1337
72
73 HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \
74 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
75
76 ENTRYPOINT ["./entrypoint.sh"]
File History 1 commit
sha256:3ff9c9863a9891bdcde71b4a43228f66d0493e38b7cc1d09fe9eb7de774046b2 feat: add repair-commit wire endpoint (API parity with repa… Opus 4.8 minor 1 day ago