# ---------- Stage 1: build frontend ---------- FROM node:20-bookworm-slim AS fe WORKDIR /fe RUN corepack enable && corepack prepare pnpm@9.12.0 --activate # deps COPY frontend/package.json ./ RUN pnpm install --no-frozen-lockfile # sources COPY frontend/index.html ./ COPY frontend/vite.config.ts ./ COPY frontend/src ./src # build to /fe/dist RUN pnpm run build # ---------- Stage 2: backend + slicer ---------- FROM node:20-bookworm-slim # OS deps: Qt libs for Orca + native build deps for better-sqlite3 + tini RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ libglib2.0-0 \ libx11-6 libxext6 libxrender1 libsm6 \ libxkbcommon0 libfontconfig1 libfreetype6 libnss3 libxi6 libxrandr2 \ libxfixes3 libdrm2 libxdamage1 libxcomposite1 libwayland-client0 libxcb1 \ python3 make g++ libsqlite3-dev \ curl tini \ && rm -rf /var/lib/apt/lists/* WORKDIR /app RUN corepack enable && corepack prepare pnpm@9.12.0 --activate # backend deps COPY backend/package.json ./ RUN pnpm install --no-frozen-lockfile # backend sources COPY backend/tsconfig.json ./ COPY backend/src ./src RUN pnpm exec tsc # copy built frontend from stage 1 COPY --from=fe /fe/dist /app/www # slicer AppImage (from repo root; compose build.context must be repo root) COPY slicer/ /app/slicer/ RUN set -eux; \ F="$(ls -1 /app/slicer | head -n1)"; \ test -n "$F"; \ chmod +x "/app/slicer/$F"; \ cd /app/slicer; \ "/app/slicer/$F" --appimage-extract; \ ln -sf /app/slicer/squashfs-root/AppRun /app/slicer/orca RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ libglib2.0-0 \ libx11-6 libxext6 libxrender1 libsm6 \ libxkbcommon0 libfontconfig1 libfreetype6 libnss3 libxi6 libxrandr2 \ libxfixes3 libdrm2 libxdamage1 libxcomposite1 libwayland-client0 libxcb1 \ python3 make g++ libsqlite3-dev \ curl tini \ libgl1 libgl1-mesa-dri libglu1-mesa \ && rm -rf /var/lib/apt/lists/* # runtime dirs RUN mkdir -p /app/data/uploads /app/data/outputs /app/profiles # env ENV QT_QPA_PLATFORM=offscreen ENV NODE_ENV=production ENV SLICER_CMD=/app/slicer/orca ENV LIBGL_ALWAYS_SOFTWARE=1 # Orca 2.3.1 CLI template (plate-sliced 3MF) ENV SLICER_ARGS="--debug 2 --arrange 1 --load-settings {MACHINE};{PROCESS} --load-filaments {FILAMENT} --slice 0 --export-3mf {OUTPUT} {INPUT}" ENV SUPPORTS_ON=--support-material ENV SUPPORTS_OFF=--no-support-material EXPOSE 8080 ENTRYPOINT ["/usr/bin/tini","--"] CMD ["node","dist/server.js"]