diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4f6fa86 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +target/ +.git/ +.gitignore +.idea/ +.vscode/ +*.log +*.class +.env +.DS_Store +lefthook.yml +setup.ps1 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5b39d1a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +# JavaFX десктоп-клиент. Для GUI нужен X-сервер, иначе окно не отобразится: +# Linux: xhost +local:docker && docker run --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro desktop-client +# macOS: XQuartz + xhost +localhost, затем docker run --rm -e DISPLAY=host.docker.internal:0 desktop-client +# Подробности — в README («Запуск фронта в Docker»). + +# ---------- stage 1: сборка jar ---------- +FROM maven:3-eclipse-temurin-25 AS build +WORKDIR /app + +COPY pom.xml ./ +COPY .mvn/ .mvn/ +RUN mvn -B dependency:go-offline -DskipTests + +# spotless/checkstyle привязаны к verify, поэтому package достаточно. +COPY src/ src/ +COPY checkstyle.xml ./ +RUN mvn -B package -DskipTests \ + && mvn -B dependency:copy-dependencies -DoutputDirectory=target/libs -DincludeScope=runtime + +# ---------- stage 2: запуск ---------- +FROM eclipse-temurin:25-jre-jammy +LABEL org.opencontainers.image.description="JavaFX desktop-клиент" + +# Нативные зависимости JavaFX (GTK/GL/X11/шрифты) для Ubuntu Jammy. +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + libgtk-3-0 \ + libgl1 \ + libxtst6 \ + libxi6 \ + libxrender1 \ + libxrandr2 \ + libxinerama1 \ + libxcursor1 \ + libxcomposite1 \ + libxdamage1 \ + libasound2 \ + libatk1.0-0 \ + libatk-bridge2.0-0 \ + libcups2 \ + libdrm2 \ + libxkbcommon0 \ + libpango-1.0-0 \ + libcairo2 \ + fontconfig \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY --from=build /app/target/*.jar ./app.jar +COPY --from=build /app/target/libs/ ./libs/ + +# Дефолты переопределяются через -e (напр. MOCK_DATA=true для работы без бэкенда). +ENV INITIAL_PAGE_PATH=/fxml/LoginForm.fxml \ + MOCK_DATA=false \ + JAVA_OPTS="-Dprism.order=sw -Djava.awt.headless=false --enable-native-access=ALL-UNNAMED" +# prism.order=sw: в контейнере нет GPU; native-access: доступ JavaFX к нативным либам, обязательный на JDK 25. +# classpath: собранный jar + runtime-зависимости из target/libs (см. copy-dependencies выше). +ENTRYPOINT ["sh", "-c", "exec java ${JAVA_OPTS} -cp '/app/app.jar:/app/libs/*' com.DesktopApplicationClientJava.Main"] diff --git a/README.md b/README.md index 98b8dbb..bee569f 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,43 @@ MOCK_DATA=true mvn javafx:run Откроется окно 800×600 со стартовой страницы (по умолчанию вход, `LoginForm.fxml`). +### Запуск фронта в Docker + +Образ (`Dockerfile`): сборка в `maven:3-eclipse-temurin-25` +(`mvn -B package -DskipTests`; spotless/checkstyle живут в `verify`, +поэтому `package` достаточно), запуск в `eclipse-temurin:25-jre` +с нативными библиотеками JavaFX для Jammy (GTK/GL/X11/звук/шрифты). +Точка входа запускает `com.DesktopApplicationClientJava.Main`, +classpath — собранный jar + `target/libs` (runtime-зависимости, +разложенные через `dependency:copy-dependencies`). + +```bash +# Сборка образа: +docker build -t desktop-client . + +# Запуск GUI на Linux (нужен X-сервер): +xhost +local:docker +docker run --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro desktop-client + +# Запуск GUI на macOS (XQuartz с разрешёнными подключениями): +xhost +localhost +docker run --rm -e DISPLAY=host.docker.internal:0 desktop-client + +# Через compose (профиль gui, тест-инфра по умолчанию не затрагивается): +docker compose --profile gui run --rm client +``` + +Переменные окружения (`-e`): `INITIAL_PAGE_PATH` (стартовая страница), +`MOCK_DATA=true` (работа без бэкенда), `JAVA_OPTS` (по умолчанию +`-Dprism.order=sw` — в контейнере нет GPU — и +`--enable-native-access=ALL-UNNAMED` — доступ JavaFX к нативным либам, +обязательный на JDK 25). + +Ограничения: JavaFX — оконный GUI, в headless-контейнере без проброса +`DISPLAY`/X11-сокета окно не отобразится (процесс при этом стартует). +Клиент ходит в бэкенд по HTTP (порт `APP_PORT` на хосте), напрямую +к postgres/redis из `compose.yaml` не подключается. + ## Git hooks Перед каждым коммитом автоматически проверяются: линт (`checkstyle:check`), diff --git a/compose.yaml b/compose.yaml index 4d689b3..744b1cd 100644 --- a/compose.yaml +++ b/compose.yaml @@ -8,8 +8,21 @@ # docker compose up -d # With object storage (for file/export ITs): # docker compose --profile files up -d +# Desktop client (GUI: нужен X-сервер, подробности в README; к бэкенду ходит по HTTP, поэтому без depends_on): +# docker compose --profile gui run --rm client services: + client: + build: . + image: desktop-client + profiles: [gui] + environment: + - INITIAL_PAGE_PATH=${INITIAL_PAGE_PATH:-/fxml/LoginForm.fxml} + - MOCK_DATA=${MOCK_DATA:-false} + - DISPLAY=${DISPLAY:-} + volumes: + - /tmp/.X11-unix:/tmp/.X11-unix:ro + postgres: image: postgres:16-alpine environment: