# Build wymaga submodułu vendor/Rex-EMoolator — composite build kompiluje :core # ze źródeł. Jeśli katalog jest pusty, settings.gradle przerwie z komunikatem. FROM eclipse-temurin:21-jdk AS build WORKDIR /src # najpierw sam opis buildu: zmiana w kodzie nie unieważnia pobranych zależności COPY gradlew settings.gradle build.gradle gradle.properties ./ COPY gradle ./gradle COPY vendor ./vendor RUN ./gradlew --no-daemon dependencies --configuration runtimeClasspath > /dev/null 2>&1 || true COPY src ./src # installDist zamiast build: pomija check, a więc i verifyCoreVersion, które # potrzebowałoby gita w obrazie. Wersję i tak przypina submoduł. RUN ./gradlew --no-daemon installDist \ && grep '^coreVersion=' gradle.properties | cut -d= -f2 > /src/core-version # whisper.cpp budowany ze źródeł: w repozytoriach Debiana go nie ma, a binarka # z hosta jest nie do użycia — tam macOS, tu Linux. # # GGML_NATIVE=OFF, bo domyślnie ggml stroi kod pod procesor maszyny budującej # (na arm64 przekazuje -mcpu=native+nodotprod..., czego GCC 12 nie rozumie), # a obraz i tak ma chodzić także na innym sprzęcie niż ten, na którym powstał FROM debian:bookworm-slim AS whisper RUN apt-get update \ && apt-get install -y --no-install-recommends git cmake build-essential ca-certificates \ && git clone --depth 1 --branch v1.7.4 https://github.com/ggerganov/whisper.cpp /src \ && cmake -S /src -B /src/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \ -DGGML_NATIVE=OFF -DWHISPER_BUILD_TESTS=OFF -DWHISPER_BUILD_EXAMPLES=ON \ && cmake --build /src/build --target whisper-cli -j "$(nproc)" \ && mkdir -p /out/bin /out/lib \ && cp /src/build/bin/whisper-cli /out/bin/ \ && find /src/build \( -name 'libwhisper.so*' -o -name 'libggml*.so' \) \ -exec cp -P {} /out/lib/ \; \ && rm -rf /var/lib/apt/lists/* /src FROM eclipse-temurin:21-jre WORKDIR /app # obrazy płyt montowane z zewnątrz, tylko do odczytu; katalog danych to wolumen VOLUME ["/data"] # whisper.cpp i ffmpeg wchodzą do obrazu, bo to kilkadziesiąt megabajtów. # Model NIE wchodzi: waży kilkaset megabajtów do kilku gigabajtów, każdy trzyma # inny i wybór należy do użytkownika — montuje się go pod /models i wskazuje # przez WHISPER_MODEL. Bez modelu katalog działa normalnie, a front mówi wprost, # czego brakuje: mówcę i kontekst kwestii bierzemy z dialogi.dta, nie z modelu. RUN apt-get update \ && apt-get install -y --no-install-recommends ffmpeg \ && rm -rf /var/lib/apt/lists/* # kopiujemy wprost z drzewa budowania: `cmake --install` chciałby zainstalować # wszystkie przykłady, a budujemy tylko whisper-cli COPY --from=whisper /out/bin/whisper-cli /usr/local/bin/whisper-cli COPY --from=whisper /out/lib/ /usr/local/lib/ RUN ldconfig ENV WHISPER_BIN=/usr/local/bin/whisper-cli # file.encoding ustawia entrypoint przez JAVA_OPTS; JAVA_TOOL_OPTIONS robiłoby # to samo, ale JVM wypisuje wtedy "Picked up..." przy każdym uruchomieniu ENV CATALOG_DATA=/data COPY --from=build /src/build/install/rex-catalog /app COPY --from=build /src/core-version /app/core-version COPY docker-entrypoint.sh /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh \ && useradd --uid 10001 --create-home katalog \ && mkdir -p /data /media \ && chown katalog:katalog /data USER katalog EXPOSE 8765 ENTRYPOINT ["/app/entrypoint.sh"] # domyślnie wstajemy jako serwer; front i MCP dzielą port CMD ["serve", "--host", "0.0.0.0"]