Files
OPENBUREAU/cms/api/Dockerfile
T
karim 2650913050 security: Härtung der CMS-API + Deployment
App-Level:
- Security-Header (secureHeaders) global; /images/* mit strikter CSP+sandbox
  → bösartiges SVG kann kein JS im Origin ausführen
- Body-Limit 256 KB auf /api/*; Login-Rate-Limit (10/5min) gegen Brute-Force
- Upload: 8-MB-Limit + Format-Verifikation (sharp-Metadaten, SVG/GIF-Signatur)
- Comment-Längenlimit (10k) gegen DB-Bloat
- DB-Fehler nicht mehr roh ausliefern (serverError-Helper)
- Profil-PUT koalesziert Hugo-Builds (kein Build-Sturm)

Infra:
- Container läuft non-root (USER node, uid 1000) + Proxmox-Repo-chown
- Ports binden per Default auf 127.0.0.1 (BIND_ADDR-Escape-Hatch)
- Kong-CORS auf SITE_URL beschränkt statt "*"
- README: Härtungs- + Migrationshinweise

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 22:05:57 +02:00

52 lines
1.8 KiB
Docker

# --- Stage 1: Admin-SPA bauen ---
# (Build-Context ist cms/, siehe docker-compose.yml)
FROM node:24-bookworm-slim AS admin
WORKDIR /admin
COPY admin/package.json admin/package-lock.json* ./
RUN npm install --no-audit --no-fund
COPY admin/ ./
# Öffentliche Browser-Werte, zur Build-Zeit eingesetzt.
ARG VITE_SUPABASE_URL
ARG VITE_SUPABASE_ANON_KEY
ENV VITE_SUPABASE_URL=$VITE_SUPABASE_URL
ENV VITE_SUPABASE_ANON_KEY=$VITE_SUPABASE_ANON_KEY
RUN npm run build
# --- Stage 2: API + Hugo + serviert Site/Admin ---
# Debian-slim statt Alpine: Hugo "extended" ist glibc-gelinkt.
FROM node:24-bookworm-slim
ARG HUGO_VERSION=0.161.1
# Von BuildKit automatisch auf die Ziel-Arch gesetzt (amd64 auf dem LXC,
# arm64 z.B. auf Apple-Silicon) — kein fester Default, sonst falsche Binary.
ARG TARGETARCH
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates git curl \
&& rm -rf /var/lib/apt/lists/* \
&& case "${TARGETARCH}" in \
arm64) HUGO_ARCH=linux-arm64 ;; \
*) HUGO_ARCH=linux-amd64 ;; \
esac \
&& curl -sSL "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_${HUGO_ARCH}.tar.gz" \
| tar -xz -C /usr/local/bin hugo \
&& hugo version
WORKDIR /app
COPY api/package.json api/package-lock.json* ./
RUN npm install --omit=dev --no-audit --no-fund
COPY api/src ./src
COPY api/entrypoint.sh ./entrypoint.sh
COPY --from=admin /admin/dist ./admin-dist
ENV NODE_ENV=production
ENV ADMIN_DIR=/app/admin-dist
# Als non-root laufen (das node-Image bringt den User `node`, uid/gid 1000 mit).
# /app gehört dem Build (root, read-only zur Laufzeit — reicht zum Servieren).
# Das gemountete Repo unter /site muss uid 1000 gehören (siehe Proxmox-Script:
# chown -R 1000:1000), damit Hugo dort public/ bauen und content/ schreiben kann.
USER node
EXPOSE 3000
CMD ["sh", "/app/entrypoint.sh"]