gabriel / musehub public
Dockerfile
86 lines 3.3 KB
Raw
sha256:6ad6d62107bbd6940c52d63327966b8a65c6391f4a3da6cd9e7548ba4b38bc48 feat(musehub#129): OG repo preview cards — endpoint, cache,… Human minor ⚠ breaking 14 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 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 libcairo2 \
50 libpango-1.0-0 \
51 libpangocairo-1.0-0 \
52 libgdk-pixbuf-2.0-0 \
53 && rm -rf /var/lib/apt/lists/*
54
55 # Playwright Chromium for OG card rendering (musehub#129).
56 ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
57
58 COPY --from=builder /app/wheels /wheels
59 RUN pip install --no-cache-dir /wheels/* \
60 && playwright install --with-deps chromium \
61 && mkdir -p /ms-playwright \
62 && chown -R musehub:musehub /ms-playwright
63
64 COPY --chown=musehub:musehub musehub/musehub/ ./musehub/
65 COPY --chown=musehub:musehub musehub/alembic/ ./alembic/
66 COPY --chown=musehub:musehub musehub/alembic.ini musehub/pyproject.toml ./
67 COPY --chown=musehub:musehub musehub/docs/ ./docs/
68 COPY --chown=musehub:musehub musehub/deploy/ ./deploy/
69
70 COPY --chown=musehub:musehub musehub/entrypoint.sh ./entrypoint.sh
71 RUN chmod +x ./entrypoint.sh
72
73 RUN mkdir -p /data && chown -R musehub:musehub /data && chmod 755 /data
74
75 USER musehub
76
77 ENV PYTHONPATH=/app
78 ENV PYTHONDONTWRITEBYTECODE=1
79 ENV PYTHONUNBUFFERED=1
80
81 EXPOSE 1337
82
83 HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \
84 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
85
86 ENTRYPOINT ["./entrypoint.sh"]
File History 2 commits
sha256:6ad6d62107bbd6940c52d63327966b8a65c6391f4a3da6cd9e7548ba4b38bc48 feat(musehub#129): OG repo preview cards — endpoint, cache,… Human minor 14 days ago
sha256:0521dce9aca20da6ab4d9ebee6de75ab876bd82cddbc6bd4897d1ac6ecd11d3d docs(musehub#129): freeze Phase 1 OG repo card design Human 14 days ago