generated from Dicken/dickendock
91 lines
4.3 KiB
Docker
91 lines
4.3 KiB
Docker
# 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
|
|
# node:dns/promises (lookup/reverse, siehe scanner/dns.ts) läuft NICHT über
|
|
# normales nicht-blockierendes I/O, sondern über getaddrinfo() im
|
|
# Betriebssystem - Node schickt das über den libuv-Threadpool ab, der
|
|
# standardmäßig nur 4 Threads hat. Beim Sammel-Scan mit bis zu 10 parallel
|
|
# gescannten Geräten (siehe routes/scan.ts CONCURRENT_DEVICES) und je bis zu
|
|
# 4 DNS-Abfragen pro Gerät reichte das nicht annähernd und führte zu einem
|
|
# Rückstau, der wie ein hängender Sammel-Scan aussah (siehe Bugreport - Scan
|
|
# blieb nach erfolgreichem masscan-/httpx-Vorabscan minutenlang in der
|
|
# eigentlichen Geräte-Schleife stehen). MUSS hier als Umgebungsvariable
|
|
# gesetzt werden, nicht im JS-Code selbst: das Projekt läuft als natives ESM
|
|
# ("type": "module"), dort werden alle import-Anweisungen VOR jeglichem
|
|
# sonstigen Code im Modul ausgeführt (auch wenn dieser Code textuell davor
|
|
# steht) - ein Setzen von process.env.UV_THREADPOOL_SIZE am Dateianfang von
|
|
# index.ts käme damit zu spät.
|
|
ENV UV_THREADPOOL_SIZE=32
|
|
|
|
# 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"]
|