Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
150 commits
Select commit Hold shift + click to select a range
5cbaa0b
switch to gradle 8.14.1
pythys Jun 1, 2025
d0eb377
address gradle 8 warnings
pythys Jun 1, 2025
bf240a4
more gradle 8.14 fixes
pythys Jun 1, 2025
221209a
fixed to gradle 8.14
pythys Jun 1, 2025
12e8c2d
equal assignment to descriptions, upgrade gradle 8.14
pythys Jun 1, 2025
c41cdfc
bump gradle to 8.14.3
pythys Oct 16, 2025
6c88418
apply fixes to gradle in moqui
pythys Oct 16, 2025
9504b94
Merge branch 'master' into upgrade-gradle
pythys Oct 23, 2025
2d566a1
bump to gradle 9.2
pythys Nov 5, 2025
6c5d0ce
ignore configuration cache for now
pythys Nov 5, 2025
2aca196
Migration to java 21 and postgres 18 with pgvector
hunterino Nov 25, 2025
3e1360d
switch to newest bitronix with jakarta JTA
pythys Nov 25, 2025
63d320f
fix stopSearch to work with gradle 9+
pythys Nov 26, 2025
bc445af
replace the rest of the exec commands
pythys Nov 26, 2025
26bf3e9
default to opensearch and fix issues
pythys Nov 27, 2025
b253105
default to JDK 21
pythys Nov 27, 2025
fcde3d3
upgrade first version of release notes
pythys Nov 27, 2025
dcdea88
already chucked out javassist from bitronix
pythys Nov 27, 2025
ef5132b
Merge pull request #672 from pythys/upgrade-gradle
acetousk Nov 29, 2025
302076a
Update commons-lang3 and commons-beanutils versions
acetousk Nov 29, 2025
870d4c1
allow unit tests to run under gradle 9
pythys Nov 29, 2025
f948de1
add convenience tasks for testing everything
pythys Nov 29, 2025
a8d80f8
fix failing cache facade test
pythys Nov 29, 2025
8f6b287
[SEC-001] Fix XXE vulnerability in XML parser
hunterino Dec 1, 2025
916af81
[SEC-002] Upgrade password hashing to BCrypt
hunterino Dec 1, 2025
979b19e
[SEC-003] Fix session fixation vulnerability
hunterino Dec 1, 2025
80ffd7b
[SEC-004] Remove credentials from log statements
hunterino Dec 1, 2025
bfc2697
[SEC-005] Add security headers (CSP, HSTS, X-Frame-Options)
hunterino Dec 1, 2025
5de67ff
[SHIRO-001..004] Upgrade Apache Shiro to 2.0.6
hunterino Dec 1, 2025
f50378b
[SHIRO-005] Add comprehensive authentication tests for Shiro 2.x
hunterino Dec 1, 2025
827bbb8
Add Java 21 module system compatibility and system evaluation docs
hunterino Dec 1, 2025
d0b9547
[CICD-001..005] Setup CI/CD pipeline with GitHub Actions
hunterino Dec 1, 2025
c9d7ab3
[SEC-006, SEC-007] Strengthen CSRF tokens and add SameSite cookie sup…
hunterino Dec 1, 2025
cfe9c8d
[SEC-008] Remove API key authentication from URL parameters
hunterino Dec 1, 2025
9c25cd0
[SEC-009] Add safe deserialization with class filtering
hunterino Dec 1, 2025
833d789
[SEC-010] Add path traversal protection for file resources
hunterino Dec 1, 2025
6d1c301
[DEP-001..005] Update dependencies to latest versions
hunterino Dec 2, 2025
23afe6e
[TXM-001] Replace Bitronix with Narayana for Java 21 compatibility
hunterino Dec 5, 2025
e74c88e
[SEC-011] Fix Shiro 2.x null salt compatibility for legacy passwords
hunterino Dec 5, 2025
efd0f03
[TEST-001] Skip EntityNoSqlCrud tests when OpenSearch not available
hunterino Dec 5, 2025
cb729bb
[TEST-002] Fix test failures for Java 21 + Narayana migration
hunterino Dec 5, 2025
d9f3c0b
[SEC-004] Remove credentials from email template log statements
hunterino Dec 5, 2025
06aeefe
[JAVA21-001, JAVA21-002] Update Java 21 compatibility and compiler wa…
hunterino Dec 6, 2025
f0c86d0
Merge remote-tracking branch 'origin/upgrade'
hunterino Dec 6, 2025
cea349e
[JAVA21-003] Replace System.out with proper logging
hunterino Dec 6, 2025
3bd8301
[JAVA21-004] Replace synchronized collections with CopyOnWriteArrayList
hunterino Dec 6, 2025
5cc5598
[JAVA21-005] Adopt Records for immutable DTOs
hunterino Dec 6, 2025
8c79668
[TEST-001] Add EntityFacade characterization tests
hunterino Dec 6, 2025
886c177
[TEST-002] Add ServiceFacade characterization tests
hunterino Dec 6, 2025
9adfbf2
[TEST-003] Add ScreenFacade characterization tests
hunterino Dec 6, 2025
5003ce3
[TEST-004] Add security/auth integration tests
hunterino Dec 6, 2025
2231d48
[TEST-005] Add REST API contract tests
hunterino Dec 6, 2025
fc6f02a
[TEST-006] Enable configurable parallel test execution
hunterino Dec 6, 2025
a2e2a07
[TEST-007] Simplify security tests and add MCP requirements doc
hunterino Dec 6, 2025
b9e11b5
[JETTY-001] Update Jetty dependencies to 12.1.4
hunterino Dec 6, 2025
93cfa71
Merge branch 'main' into p1-security-cicd-dependencies
hunterino Dec 7, 2025
adfd72d
Merge pull request #52 from hunterino/p1-security-cicd-dependencies
hunterino Dec 7, 2025
39728f4
Merge pull request #53 from hunterino/jetty-12-migration
hunterino Dec 7, 2025
f54f830
[JETTY-002] Migrate javax.* to jakarta.* namespace for Jakarta EE 10
hunterino Dec 7, 2025
8140ce1
[JETTY-002] Fix test failures from Jakarta EE 10 migration
hunterino Dec 7, 2025
eb5d401
[JETTY-003] Update web.xml for Jakarta EE 10 compatibility
hunterino Dec 7, 2025
b470d77
[JETTY-004] Add Jetty 12 integration tests
hunterino Dec 7, 2025
e03b44f
[ARCH-001] Expand ExecutionContextFactory interface for dependency in…
hunterino Dec 7, 2025
f6a0f3b
[ARCH-002] Extract FormValidator from ScreenForm
hunterino Dec 8, 2025
6e93f45
Merge pull request #54 from hunterino/arch-001-ecf-interface
hunterino Dec 8, 2025
4a8baa8
Merge pull request #55 from hunterino/arch-002-form-renderer
hunterino Dec 8, 2025
d64f583
[ARCH-001] Create ExecutionContextFactory interface enhancements
hunterino Dec 8, 2025
9ae89c5
[ARCH-003] Consolidate cache warming logic in EntityCache
hunterino Dec 8, 2025
9668b26
[ARCH-004] Extract SequenceGenerator from EntityFacade
hunterino Dec 8, 2025
dadfd7f
Merge branch 'p1-security-cicd-dependencies' into arch-001-ecf-interface
hunterino Dec 8, 2025
edabfe2
Merge pull request #56 from hunterino/arch-001-ecf-interface
hunterino Dec 8, 2025
409a54e
[ARCH-005] Decouple Service-Entity circular dependency
hunterino Dec 8, 2025
1093898
Merge pull request #57 from hunterino/arch-003-entity-cache-manager
hunterino Dec 8, 2025
e78a3ca
Merge pull request #58 from hunterino/arch-004-sequence-generator
hunterino Dec 8, 2025
9d52bd5
Merge branch 'main' into arch-005-service-entity-decoupling
hunterino Dec 8, 2025
509d999
Merge pull request #59 from hunterino/arch-005-service-entity-decoupling
hunterino Dec 8, 2025
eca4158
Fix duplicate getConfXmlRoot() method in ExecutionContextFactory inte…
hunterino Dec 8, 2025
4db6b4b
Merge branch 'p1-security-cicd-dependencies'
hunterino Dec 8, 2025
427b04f
Add comprehensive project status evaluation document
hunterino Dec 8, 2025
0229e35
[DOCKER] Complete Docker epic with containerization support
hunterino Dec 8, 2025
f20de10
Merge pull request #60 from hunterino/docker-epic
hunterino Dec 8, 2025
fee818f
Add upstream moqui/moqui-framework issues prioritization plan
hunterino Dec 8, 2025
78c437d
Add PostgreSQL schema migration plan: moqui.public to fivex.moqui
hunterino Dec 8, 2025
7f2921d
[JAKARTA-EE10] Complete Jakarta EE 10 migration with Jetty 12 and Shi…
hunterino Dec 8, 2025
c7a9d0d
added mcp ignore
hunterino Dec 8, 2025
9840a65
Merge branch 'docker-epic'
hunterino Dec 8, 2025
7b9f42c
Merge pull request #61 from hunterino/jakarta-ee10-migration
hunterino Dec 8, 2025
f27912b
Merge remote-tracking branch 'origin/pre-jakarta-base'
hunterino Dec 8, 2025
ced4986
docs: Update SYSTEM_EVALUATION.md with Jakarta EE 10 migration results
hunterino Dec 8, 2025
466dc82
Merge pull request #673 from pythys/upgrade-gradle
acetousk Dec 8, 2025
4066498
Missing Details
hunterino Dec 8, 2025
45f163b
Merge remote-tracking branch 'origin/upgrade'
hunterino Dec 8, 2025
2307769
fix(ci): Update gradle-wrapper-validation action to v4
hunterino Dec 8, 2025
5b998ff
fix(tests): Skip entity REST tests that require WebFacadeStub.handleE…
hunterino Dec 8, 2025
dc70931
fix(tests): Implement handleEntityRestCall in WebFacadeStub to enable…
hunterino Dec 8, 2025
63dbb44
Tests Passing
hunterino Dec 10, 2025
e69f36e
Merge remote-tracking branch 'origin/master'
hunterino Dec 11, 2025
5ee60d9
remove redundant finalize methods, destroy exists
pythys Dec 12, 2025
5e12437
remove finalize, nothing to cleanup just a boolean
pythys Dec 12, 2025
2c25438
remove finalize, already cleaned up correctly
pythys Dec 12, 2025
0b1c221
remove deprecated finalize
pythys Dec 12, 2025
a0c8459
fix: Move ElasticFacade init before postFacadeInit to prevent NPE
hunterino Dec 12, 2025
de08646
centralize dependencyUpdates and gradle 9 formatting
pythys Dec 15, 2025
b207aaf
upgrade all libraries, shiro now version 2
pythys Dec 15, 2025
f94d88b
Merge pull request #675 from pythys/upgrade-gradle
acetousk Dec 15, 2025
878e28d
remove incorrect implementation of remember me
pythys Dec 15, 2025
1c81039
Merge branch 'upgrade' into upgrade-gradle
pythys Dec 15, 2025
bf790a2
remove shiro.ini from tests, it's no longer needed
pythys Dec 15, 2025
bd28058
upgrade libraries and handle changes to API
pythys Dec 16, 2025
0130aa5
update changelog to incorporate all the work
pythys Dec 16, 2025
59aec1f
go back to INI
pythys Dec 17, 2025
e959cfd
fix typo now that we switched to env INI
pythys Dec 17, 2025
88964f5
breakout statements to make @CompileStatic happy
pythys Dec 17, 2025
4933716
no fallback to empty string again
pythys Dec 17, 2025
baeeb31
return shiro.ini to tests
pythys Dec 17, 2025
16373bf
fix remaining shiro2 bugs
pythys Dec 19, 2025
d169f2c
fix(auth): Add deadlock-safe login key creation API
hunterino Dec 20, 2025
ca4a68a
[P0] Fix deadlock in login operations (#27)
hunterino Dec 20, 2025
112bed8
fix: Move ElasticFacade init before postFacadeInit to prevent NPE (#26)
hunterino Dec 20, 2025
f9d2ca7
Merge branch 'fix/issue-1-es-npe-startup'
hunterino Dec 20, 2025
9ea08ce
Merge branch 'fix/issue-5-login-deadlock'
hunterino Dec 20, 2025
a7afbdc
Merge remote-tracking branch 'origin/upgrade'
hunterino Dec 20, 2025
0655db2
genui progress.
hunterino Dec 21, 2025
c9148cc
Merge fork fixes (PRs #26, #27) back into master after submodule tran…
hunterino Dec 21, 2025
3f612b1
fix: Correct thruUpdateStamp parameter name mismatch (#7)
hunterino Dec 21, 2025
8bef284
Merge pull request #28 from hunterino/fix/issue-7-thru-update-stamp
hunterino Dec 21, 2025
8aff611
Add support for CSV escape character to EntityDataLoaderImpl
puru-khedre Aug 21, 2024
0d2de91
Added method to set custom escape character
puru-khedre Aug 22, 2024
f9f9d3c
Merge pull request #29 from hunterino/fix/issue-8-csv-escape-char
hunterino Dec 21, 2025
b22e836
fix: Preserve non-PK conditions in entity find when full PK present (…
hunterino Dec 21, 2025
eec5156
Merge pull request #30 from hunterino/fix/issue-14-entity-find-non-pk…
hunterino Dec 21, 2025
dae8ee3
fix: Add audit logging for entity delete operations (#9)
hunterino Dec 21, 2025
24d2315
Merge pull request #31 from hunterino/fix/issue-9-audit-log-delete
hunterino Dec 21, 2025
1631e82
Fix searchFormMap to use defaultParameters for _op fallback (#12)
hunterino Dec 21, 2025
978b860
Reduce lock conflict log noise from warn to info level (#15)
hunterino Dec 21, 2025
87872d9
Add retry logic for Elasticsearch bulk indexing failures (#16)
hunterino Dec 21, 2025
5888beb
Reduce default job lock expiration from 24h to 2h (#17)
hunterino Dec 21, 2025
01d7f0f
upgrade to groovy 5
pythys Dec 25, 2025
39886e1
Merge pull request #676 from pythys/upgrade-gradle
acetousk Dec 28, 2025
e86db2d
Merge branch 'upgrade-gradle' into upgrade-gradle2
pythys Dec 28, 2025
654b794
add missing comment on license
pythys Dec 28, 2025
00074f2
remove useless comments
pythys Dec 28, 2025
1cf55d0
code self explanatory
pythys Dec 28, 2025
87160c4
add comments on groovy 5
pythys Dec 28, 2025
2e6ec2a
Run Groovy shell evaluations on a dedicated executor thread
pythys Dec 29, 2025
98362ab
absolutely no need to check against null
pythys Dec 29, 2025
15cf885
restore signature of flush and close
pythys Dec 29, 2025
b377d11
Merge pull request #682 from pythys/upgrade-gradle
acetousk Jan 2, 2026
eccf067
Merge remote-tracking branch 'upstream/upgrade'
hunterino Jan 3, 2026
ca5e37f
forward
hunterino Jan 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Git
.git
.gitignore

# IDE
.idea
*.iml
.vscode
*.swp
*.swo

# Build artifacts
build/
*/build/
*.war
wartemp/
out/

# Gradle
.gradle/
gradle-app.setting

# Runtime data (will be mounted as volumes)
runtime/db/
runtime/log/
runtime/txlog/
runtime/sessions/
runtime/opensearch/
runtime/elasticsearch/

# Logs
logs/
*.log

# Documentation
docs/
*.md
!README.md

# Docker
docker/
Dockerfile*
docker-compose*.yml
.dockerignore

# CI/CD
.github/
.travis.yml

# Testing
ObjectStore/

# macOS
.DS_Store
94 changes: 94 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
name: CI

on:
push:
branches: [ main, master, develop ]
pull_request:
branches: [ main, master, develop ]

env:
GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.parallel=true"

jobs:
build:
name: Build and Test
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: ${{ github.ref != 'refs/heads/main' }}

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build framework
run: ./gradlew framework:build -x test --no-daemon

- name: Run framework tests
run: ./gradlew framework:test --no-daemon
continue-on-error: true

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: |
framework/build/reports/tests/
framework/build/test-results/
retention-days: 14

- name: Upload build artifacts
uses: actions/upload-artifact@v4
if: success()
with:
name: build-artifacts
path: |
framework/build/libs/
retention-days: 7

security-scan:
name: Security Scan
runs-on: ubuntu-latest
needs: build

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Run OWASP Dependency Check
run: ./gradlew dependencyCheckAnalyze --no-daemon || true
continue-on-error: true

- name: Upload OWASP report
uses: actions/upload-artifact@v4
if: always()
with:
name: owasp-report
path: build/reports/dependency-check-report.html
retention-days: 14
4 changes: 2 additions & 2 deletions .github/workflows/gradle-wrapper-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ jobs:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v4
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ nb-configuration.xml
# VSCode files
.vscode

# Emacs files
.projectile

# Version managers (sdkman, mise, asdf)
mise.toml
.tool-versions

# OSX auto files
.DS_Store
.AppleDouble
Expand All @@ -70,3 +77,8 @@ Desktop.ini

# Linux auto files
*~

logs/
ObjectStore/

.playwright-mcp/
123 changes: 123 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Moqui Framework is an enterprise application development framework based on Groovy and Java. It provides a complete runtime environment with built-in database management, service-oriented architecture, web framework, and business logic components.

## Common Development Commands

### Build and Run
- `gradle build` - Build the framework and all components
- `gradle run` - Run Moqui with development configuration
- `gradle runProduction` - Run with production configuration
- `gradle clean` - Clean build artifacts
- `gradle cleanAll` - Clean everything including database, logs, and sessions

### Data Management
- `gradle load` - Load all data types (default)
- `gradle load -Ptypes=seed` - Load only seed data
- `gradle load -Ptypes=seed,seed-initial` - Load seed and seed-initial data
- `gradle loadProduction` - Load production data (seed, seed-initial, install)
- `gradle cleanDb` - Clean database files (Derby, H2, OrientDB, ElasticSearch/OpenSearch)

### Testing
- `gradle test` - Run all tests
- `gradle framework:test` - Run framework tests only
- To run a single test: Use standard JUnit/Spock test runners with system properties from MoquiDefaultConf.xml

### Component Management
- `gradle getComponent -Pcomponent=<name>` - Get a component and its dependencies
- `gradle createComponent -Pcomponent=<name>` - Create new component from template
- Components are located in `runtime/component/`

### Deployment
- `gradle addRuntime` - Create moqui-plus-runtime.war with embedded runtime
- `gradle deployTomcat` - Deploy to Tomcat (requires tomcatHome configuration)

### ElasticSearch/OpenSearch
- `gradle downloadOpenSearch` - Download and install OpenSearch
- `gradle downloadElasticSearch` - Download and install ElasticSearch
- `gradle startElasticSearch` - Start search service
- `gradle stopElasticSearch` - Stop search service

## Architecture and Structure

### Core Framework (`/framework`)
The framework provides the foundational services and APIs:
- **Entity Engine** (`/framework/entity/`) - ORM and database abstraction layer supporting multiple databases
- **Service Engine** (`/framework/service/`) - Service-oriented architecture with synchronous/asynchronous execution
- **Screen/Web** (`/framework/screen/`) - XML-based screen rendering with support for various output formats
- **Resource Facade** - Unified resource access for files, classpath, URLs, and content repositories
- **Security** - Built-in authentication, authorization, and artifact-based permissions
- **L10n/I18n** - Localization and internationalization support
- **Cache** - Distributed caching with Hazelcast support

### Runtime Structure (`/runtime`)
- **base-component/** - Core business logic components (webroot, tools, etc.)
- **component/** - Add-on components (HiveMind, SimpleScreens, PopCommerce, Mantle)
- **conf/** - Configuration files (MoquiDevConf.xml, MoquiProductionConf.xml)
- **db/** - Database files for embedded databases
- **elasticsearch/ or opensearch/** - Search engine installation
- **lib/** - Additional JAR libraries
- **log/** - Application logs
- **sessions/** - Web session data

### Component Architecture
Components are modular units containing:
- **entity/** - Data model definitions (XML)
- **service/** - Service definitions and implementations (XML/Groovy/Java)
- **screen/** - Screen definitions (XML)
- **data/** - Seed and demo data (XML/JSON)
- **template/** - FreeMarker templates
- **build.gradle** - Component-specific build configuration

### Key Design Patterns
1. **Service Facade Pattern** - All business logic exposed through services
2. **Entity-Control-Boundary** - Clear separation between data, logic, and presentation
3. **Convention over Configuration** - Sensible defaults with override capability
4. **Resource Abstraction** - Uniform access to different resource types
5. **Context Management** - ExecutionContext provides access to all framework features

### Configuration System
- **MoquiDefaultConf.xml** - Default framework configuration
- **MoquiDevConf.xml** - Development overrides
- **MoquiProductionConf.xml** - Production settings
- Configuration can be overridden via system properties, environment variables, or external config files

### Transaction Management
- Default: Bitronix Transaction Manager (BTM)
- Alternative: JNDI/JTA from application server
- Automatic transaction boundaries for services
- Support for multiple datasources with XA transactions

### Web Framework
- RESTful service automation from service definitions
- Screen rendering with transitions and actions
- Support for multiple render modes (HTML, JSON, XML, PDF, etc.)
- Built-in CSRF protection and security headers
- WebSocket support for real-time features

## Development Workflow

### Setting Up IDE
- `gradle setupIntellij` - Configure IntelliJ IDEA with XML catalogs for autocomplete

### Database Selection
Default is H2. To use PostgreSQL or MySQL:
1. Configure datasource in Moqui configuration
2. Add JDBC driver to runtime/lib
3. Update entity definitions if needed for database-specific features

### Component Development
1. Create component: `gradle createComponent -Pcomponent=myapp`
2. Define entities in `component/myapp/entity/`
3. Implement services in `component/myapp/service/`
4. Create screens in `component/myapp/screen/`
5. Add seed data in `component/myapp/data/`

### Hot Reload Support
- Groovy scripts and services reload automatically in development mode
- Screen definitions reload on change
- Entity definitions require restart
86 changes: 86 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Moqui Framework Production Dockerfile
# Multi-stage build for optimized image size
# Uses Java 21 LTS with Eclipse Temurin

# ============================================================================
# Build Stage - Compiles the application and creates the WAR
# ============================================================================
FROM eclipse-temurin:21-jdk-alpine AS builder

# Install build dependencies
RUN apk add --no-cache bash git

WORKDIR /build

# Copy Gradle wrapper and build files first (for better caching)
COPY gradlew gradlew.bat gradle.properties settings.gradle build.gradle ./
COPY gradle/ gradle/

# Copy source code
COPY framework/ framework/
COPY runtime/ runtime/

# Build the WAR file with runtime included
RUN chmod +x gradlew && \
./gradlew --no-daemon addRuntime && \
# Unzip the WAR for faster startup
mkdir -p /app && \
cd /app && \
unzip /build/moqui-plus-runtime.war

# ============================================================================
# Runtime Stage - Minimal production image
# ============================================================================
FROM eclipse-temurin:21-jre-alpine

LABEL maintainer="Moqui Framework <moqui@googlegroups.com>" \
version="3.0.0" \
description="Moqui Framework - Enterprise Application Development" \
org.opencontainers.image.source="https://github.com/moqui/moqui-framework"

# Install runtime dependencies
RUN apk add --no-cache \
curl \
tzdata \
&& rm -rf /var/cache/apk/*

# Create non-root user for security
RUN addgroup -g 1000 -S moqui && \
adduser -u 1000 -S moqui -G moqui

WORKDIR /opt/moqui

# Copy application from builder
COPY --from=builder --chown=moqui:moqui /app/ .

# Create necessary directories with correct permissions
RUN mkdir -p runtime/log runtime/txlog runtime/sessions runtime/db && \
chown -R moqui:moqui runtime/

# Switch to non-root user
USER moqui

# Configuration volumes
VOLUME ["/opt/moqui/runtime/conf", "/opt/moqui/runtime/lib", "/opt/moqui/runtime/classes", "/opt/moqui/runtime/ecomponent"]

# Data persistence volumes
VOLUME ["/opt/moqui/runtime/log", "/opt/moqui/runtime/txlog", "/opt/moqui/runtime/sessions", "/opt/moqui/runtime/db"]

# Main application port
EXPOSE 8080

# Environment variables with sensible defaults
ENV JAVA_TOOL_OPTIONS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=100" \
MOQUI_RUNTIME_CONF="conf/MoquiProductionConf.xml" \
TZ="UTC"

# Health check using the /health/ready endpoint
# start-period allows for slow startup (loading data, etc.)
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
CMD curl -f http://localhost:8080/health/ready || exit 1

# Start Moqui using the MoquiStart class
ENTRYPOINT ["java", "-cp", ".", "MoquiStart"]

# Default command (can be overridden)
CMD ["port=8080", "conf=conf/MoquiProductionConf.xml"]
Loading