Files
demo-monolith/Dockerfile
T
Liosha84andClaude Opus 5.5 3f5a6c26bb feat: finish demo — Angular 22 + Material UI, role management, schema and Docker cleanup
Frontend
- Upgrade Angular 19 -> 22 (TypeScript 6, new control flow), drop unused
  packages (bootstrap, jquery, popper, ng-bootstrap, webpack)
- Move the UI to Angular Material: toolbar with user menu, tutorials list,
  add/edit forms, admin users table with role editing dialog, profile,
  home page with published tutorials, registration form, login dialog
- Guard routes: login required for add/edit/profile, admin role for /admin
- Remove the /login, Moderator and User pages, event bus, auth interceptor
  and other dead code

Backend
- Add PUT /api/users/{id}/roles (admin only) that keeps at least one admin
  and does not let an admin drop their own admin role
- Tighten security: read tutorials publicly, change them only when logged
  in, users/roles API for admins only; hide password hashes in JSON
- Remove unused Settings and Test endpoints, DTO mappers, commented code
- Flyway V2 aligns the schema with the entities (bigint ids, tutorials PK,
  identity ids); Hibernate now runs with ddl-auto: validate

Docker
- Three-stage Dockerfile (Node build, Gradle build, JRE runtime) with
  layer caching, non-root user and healthcheck; add .dockerignore
- docker-compose waits for a healthy Postgres, always rebuilds the image,
  no longer mounts the Docker socket

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:03:58 +02:00

67 lines
2.7 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# syntax=docker/dockerfile:1
# 1. Сборка Angular
FROM node:24-alpine AS ui
WORKDIR /ui
# Сначала только манифесты — слой с зависимостями пересобирается лишь при их изменении.
# npm install, а не npm ci: сборка не должна падать, если package-lock.json разошёлся с package.json
COPY spring-angular-ui/package*.json ./
RUN --mount=type=cache,target=/root/.npm \
npm install --legacy-peer-deps --no-audit --no-fund
COPY spring-angular-ui/ ./
RUN npx ng build
# 2. Сборка jar
FROM eclipse-temurin:26-jdk-jammy AS build
WORKDIR /app
# Сначала Gradle-обвязка — зависимости скачиваются заново лишь при изменении build.gradle
COPY gradlew settings.gradle build.gradle ./
COPY gradle ./gradle
RUN chmod +x gradlew
RUN --mount=type=cache,target=/root/.gradle \
./gradlew dependencies --no-daemon -q > /dev/null
COPY src ./src
# Свежесобранный фронт кладём туда же, куда его копирует задача copyAngularBuild
COPY --from=ui /ui/static/browser ./src/main/resources/static
RUN --mount=type=cache,target=/root/.gradle \
./gradlew bootJar -x test --no-daemon \
&& cp "$(ls build/libs/*.jar | grep -v -- '-plain.jar' | head -n 1)" app.jar
# Раскладываем jar по слоям: зависимости меняются редко и кэшируются отдельно от кода
RUN java -Djarmode=tools -jar app.jar extract --layers --launcher --destination extracted
# 3. Запуск
FROM eclipse-temurin:26-jre-jammy
# curl нужен для healthcheck
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*
# Непривилегированный пользователь; InitDataService пишет начальные данные в /jambotron_data
RUN groupadd --system app \
&& useradd --system --gid app --home-dir /app app \
&& mkdir -p /jambotron_data \
&& chown app:app /jambotron_data
WORKDIR /app
COPY --from=build --chown=app:app /app/extracted/dependencies/ ./
COPY --from=build --chown=app:app /app/extracted/spring-boot-loader/ ./
COPY --from=build --chown=app:app /app/extracted/snapshot-dependencies/ ./
COPY --from=build --chown=app:app /app/extracted/application/ ./
USER app
EXPOSE 8080
HEALTHCHECK --interval=15s --timeout=5s --start-period=60s --retries=5 \
CMD curl -fs http://localhost:8080/actuator/health || exit 1
# JVM ориентируется на лимит памяти контейнера, а не на память хоста
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75", "org.springframework.boot.loader.launch.JarLauncher"]