# syntax=docker/dockerfile:1 FROM node:20-alpine AS base RUN corepack enable WORKDIR /app # ---- deps: gesamten Workspace-Kontext installieren ------------------------- FROM base AS deps COPY pnpm-workspace.yaml package.json pnpm-lock.yaml* tsconfig.base.json ./ COPY packages/shared/package.json packages/shared/package.json COPY packages/ui/package.json packages/ui/package.json COPY apps/backend/package.json apps/backend/package.json COPY apps/frontend/package.json apps/frontend/package.json # better-sqlite3 braucht Build-Tools für den nativen Modulbau RUN apk add --no-cache python3 make g++ RUN pnpm install --frozen-lockfile || pnpm install # ---- build: Backend + Shared bauen ------------------------------------------ FROM deps AS build COPY packages/shared packages/shared COPY apps/backend apps/backend RUN pnpm --filter @launchpad/shared build RUN pnpm --filter @launchpad/backend build # nur Production-Dependencies fürs Runtime-Image behalten RUN pnpm deploy --filter @launchpad/backend --prod /app/deploy # ---- runtime: schlankes Laufzeit-Image -------------------------------------- FROM node:20-alpine AS runtime WORKDIR /app ENV NODE_ENV=production ENV DATABASE_PATH=/data/launchpad.db ENV PORT=3001 ENV HOST=0.0.0.0 # iputils-ping stellt einen "echten" ping-Befehl mit ICMP-Unterstützung # bereit (nicht nur die BusyBox-Variante) - für den optionalen Live-Status- # Heartbeat (siehe src/liveStatus.ts, standardmäßig deaktiviert). # masscan beschleunigt den vollständigen Portscan (1-65535, siehe # scanner/masscan.ts) erheblich gegenüber reinem TCP-Connect-Scanning - wird # automatisch genutzt, falls vorhanden, sonst fällt der Scanner auf die # eingebaute (langsamere, aber ohne Zusatzrechte auskommende) Methode zurück. RUN apk add --no-cache iputils-ping masscan # httpx (ProjectDiscovery) prüft eine Liste offener Ports und liefert NUR # die, die tatsächlich HTTP/HTTPS sprechen, inkl. Status/Titel/Server-Header # in einem einzigen, hochparallelen Durchlauf (siehe scanner/httpx.ts) - # deutlich schneller als eigenes Protokoll-Raten pro Port, und verhindert, # dass Nicht-Web-Ports (SSH, SMB, NFS, ...) überhaupt erst per HTTP # angesprochen werden. Kein Alpine-Paket vorhanden, daher als # Binary-Release von GitHub geladen. Bei Fehlschlag (z. B. kein # Internetzugang beim Bauen des Images) läuft der Build trotzdem durch - # der Scanner erkennt ein fehlendes httpx zur Laufzeit automatisch und # fällt auf die eingebaute Methode zurück. RUN apk add --no-cache --virtual .httpx-build curl unzip && \ ( \ HTTPX_URL=$(curl -fsSL https://api.github.com/repos/projectdiscovery/httpx/releases/latest \ | grep -o 'https://[^"]*httpx_[0-9][^"]*_linux_amd64\.zip' | head -n1) && \ test -n "$HTTPX_URL" && \ curl -fsSL "$HTTPX_URL" -o /tmp/httpx.zip && \ unzip -o /tmp/httpx.zip -d /usr/local/bin httpx && \ chmod +x /usr/local/bin/httpx \ || echo "httpx-Installation fehlgeschlagen - Scanner nutzt automatisch die eingebaute Methode" \ ) && \ rm -f /tmp/httpx.zip && \ apk del .httpx-build COPY --from=build /app/deploy/ ./ COPY --from=build /app/apps/backend/dist ./dist COPY --from=build /app/packages/shared/dist ./node_modules/@launchpad/shared/dist RUN mkdir -p /data VOLUME ["/data"] EXPOSE 3001 CMD ["node", "dist/index.js"]