# vibe_erp — single shipping image (architecture spec section 10). # # This produces ghcr.io/vibeerp/vibe-erp:: one Spring Boot fat-jar, # one mounted volume at /opt/vibe-erp, one mandatory dependency # (PostgreSQL). Customer extensions live OUTSIDE the image. # ─── Stage 1: build ──────────────────────────────────────────────────── # NOTE: this stage assumes ./gradlew and gradle/wrapper/* exist at the # repo root. They are generated by Gradle itself (not hand-written) and # will be added before anyone tries to build this image. FROM eclipse-temurin:21-jdk-alpine AS build # Node + npm are required for the :web Gradle subproject's npm-based # Vite build. The bootJar wires the SPA bundle into Spring Boot's # classpath:/static/ via processResources, so a clean container build # of `:distribution:bootJar` transitively runs `:web:npmInstall` and # `:web:npmBuild` and needs npm on PATH. Apk's nodejs/npm packages # track v22.x on Alpine 3.21, which Vite 5 + React 18 are happy with. RUN apk add --no-cache nodejs npm WORKDIR /workspace COPY . . RUN chmod +x ./gradlew \ && ./gradlew :distribution:bootJar --no-daemon # ─── Stage 2: runtime ────────────────────────────────────────────────── FROM eclipse-temurin:21-jre-alpine AS runtime # Non-root user — never run the JVM as root inside the container. RUN addgroup -S vibeerp -g 10001 \ && adduser -S -u 10001 -G vibeerp vibeerp # Customer-mounted volume layout from architecture spec section 10. RUN mkdir -p /opt/vibe-erp/config \ /opt/vibe-erp/plugins \ /opt/vibe-erp/i18n-overrides \ /opt/vibe-erp/files \ /opt/vibe-erp/logs \ && chown -R vibeerp:vibeerp /opt/vibe-erp \ && mkdir -p /app \ && chown -R vibeerp:vibeerp /app COPY --from=build --chown=vibeerp:vibeerp \ /workspace/distribution/build/libs/vibe-erp.jar /app/vibe-erp.jar WORKDIR /app ENV VIBEERP_PLUGINS_DIR=/opt/vibe-erp/plugins \ VIBEERP_FILES_DIR=/opt/vibe-erp/files EXPOSE 8080 VOLUME ["/opt/vibe-erp"] USER vibeerp HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \ CMD wget -q -O /dev/null http://localhost:8080/actuator/health || exit 1 ENTRYPOINT ["java", \ "-XX:+UseContainerSupport", \ "-XX:MaxRAMPercentage=75", \ "-Dfile.encoding=UTF-8", \ "-jar", "/app/vibe-erp.jar"]