- Mehrstufige Dockerfiles je Dienst mit Stufen für Entwicklung und Betrieb, beide Images laufen als unprivilegierter Benutzer - Backend-Entrypoint wartet auf die Datenbank, migriert und seedt nur bei leerem Kategoriebaum (neues Flag --if-empty) - docker-compose.yml mit Netz-Trennung, Healthchecks und benannten Volumes; die Datenbank ist ausschließlich im internen Netz erreichbar - nginx liefert das Bundle aus und reicht /api weiter; index.html ungecacht, gehashte Assets ein Jahr - Gitea-Workflows: ci.yml für Lint, Tests und Bundle-Bau, build.yml für die Images nach linux/amd64 ohne Deploy-Schritt - docs/runner.md und docs/deployment.md, .dockerignore je Dienst Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014e7t8UpmoVNMtWivY5LiSH
48 lines
1.5 KiB
Docker
48 lines
1.5 KiB
Docker
# syntax=docker/dockerfile:1.7
|
||
#
|
||
# Frontend-Image für moneyfy: Vite-Bundle bauen, mit nginx ausliefern.
|
||
|
||
# --- Abhängigkeiten -----------------------------------------------------------
|
||
FROM node:22-bookworm-slim AS deps
|
||
|
||
WORKDIR /app
|
||
|
||
# Nur die Sperrdatei kopieren – die Schicht bleibt gültig, solange sich die
|
||
# Abhängigkeiten nicht ändern.
|
||
COPY package.json package-lock.json ./
|
||
RUN npm ci --no-audit --no-fund
|
||
|
||
# --- Entwicklung --------------------------------------------------------------
|
||
# Wird von docker-compose.override.yml genutzt; der Quellcode kommt per Volume.
|
||
FROM deps AS development
|
||
|
||
ENV NODE_ENV=development
|
||
COPY . .
|
||
|
||
# Vite legt seinen Cache unter node_modules/.vite ab – der Benutzer braucht Schreibrecht.
|
||
RUN chown -R node:node /app
|
||
|
||
USER node
|
||
EXPOSE 5173
|
||
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "5173"]
|
||
|
||
# --- Bau ----------------------------------------------------------------------
|
||
FROM deps AS build
|
||
|
||
COPY . .
|
||
|
||
# `npm run build` prüft zuerst die Typen und bricht bei Fehlern ab.
|
||
RUN npm run build
|
||
|
||
# --- Auslieferung -------------------------------------------------------------
|
||
# Das unprivilegierte Image läuft als Benutzer nginx und lauscht auf 8080.
|
||
FROM nginxinc/nginx-unprivileged:1.27-alpine AS production
|
||
|
||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||
COPY --from=build /app/dist /usr/share/nginx/html
|
||
|
||
EXPOSE 8080
|
||
|
||
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||
CMD wget -qO- http://127.0.0.1:8080/healthz >/dev/null || exit 1
|