A Docker-based build system that compiles and packages the cohesive-cmdbuild source code into a production-ready WAR file.
This is a builder tool that takes the CMDBuild source code from https://github.com/genpat-it/cohesive-cmdbuild and produces a complete, deployable WAR file.
What it does:
- 📥 Clones the cohesive-cmdbuild source repository
- 🔨 Compiles Java backend with Maven (128 parallel threads)
- 🎨 Builds custom UI with Sencha Cmd
- 📦 Packages everything into a single WAR file
- ⚙️ Includes your configuration files automatically
What you get:
A production-ready cohesive-YYYYMMDD-HHMMSS.war (~390MB) that contains:
- ✅ CMDBuild application (compiled Java backend)
- ✅ Custom UI (compiled with Sencha Cmd)
- ✅ All configuration files (
WEB-INF/web.xml,WEB-INF/conf/*.conf) - ✅ Required directory structure (
WEB-INF/sql/functions/,WEB-INF/sql/patches/) - ✅ Your database configuration (from
WEB-INF/conf/database.conf)
Ready to deploy - just copy the WAR to your Tomcat server!
# Clone this repository
git clone https://github.com/genpat-it/cohesive-cmdbuild-builder.git
cd cohesive-cmdbuild-builder
# Configure database BEFORE building
nano WEB-INF/conf/database.conf
# Build the WAR (requires Docker)
GIT_REPO=https://github.com/genpat-it/cohesive-cmdbuild \
GIT_BRANCH=main \
./build-war.shThe build process will:
- Clone your CMDBuild source code repository
- Compile Java backend with Maven
- Build custom UI with Sencha Cmd
- Package everything into a single, cohesive WAR file
Output: ./output/cohesive-YYYYMMDD-HHMMSS.war (~368MB), symlinked as ./output/cohesive-latest.war
You have two deployment options:
- Copy
./output/cohesive-*.warto your Tomcatwebapps/directory - Start Tomcat (must run as non-root user, e.g.,
tomcatorubuntu) - The WAR already contains your database configuration from
WEB-INF/conf/database.conf
Use the deploy-war.sh script to automatically deploy to a Tomcat server with Manager enabled:
With username and password:
TOMCAT_URL=http://localhost:8080 \
TOMCAT_USER=admin \
TOMCAT_PASS=password \
APP_CONTEXT=cohesive \
./deploy-war.shWith pre-encoded Basic auth header (Jenkins style):
TOMCAT_URL=http://localhost:8080 \
TOMCAT_AUTH_HEADER="Basic YWRtaW46cGFzc3dvcmQ=" \
APP_CONTEXT=cohesive \
./deploy-war.shThe script will:
- Check if the application is already deployed
- Undeploy the existing version if present
- Deploy the new WAR file
- Verify successful deployment
Environment Variables:
| Variable | Required | Default | Description |
|---|---|---|---|
TOMCAT_URL |
No | http://localhost:8080 |
Tomcat server URL |
TOMCAT_USER |
Yes* | - | Tomcat Manager username |
TOMCAT_PASS |
Yes* | - | Tomcat Manager password |
TOMCAT_AUTH_HEADER |
Yes* | - | Pre-encoded Basic auth header |
APP_CONTEXT |
No | cohesive |
Application context path |
*Either TOMCAT_USER+TOMCAT_PASS OR TOMCAT_AUTH_HEADER must be provided.
The COHESIVE application requires external JavaScript libraries that are hardcoded to load from /res/js/* in the compiled HTML. These resources are provided by the cohesive-common-resources application.
How it works:
- The WAR file contains hardcoded references like
<script src="/res/js/hotkeys-3.10.0.min.js"></script> - These requests will go to
http://your-server/res/js/*(same server as the WAR) - You need to ensure
/res/*requests are served by the cohesive-common-resources application
Deployment options:
-
Same Tomcat server - Deploy both WARs on the same Tomcat instance:
webapps/ ├── cohesive.war → http://your-server/cohesive/ └── res.war → http://your-server/res/ -
Different servers with reverse proxy - Use Nginx to route
/res/*requests:location /cohesive/ { proxy_pass http://tomcat-server:8080/cohesive/; } location /res/ { proxy_pass http://resources-server:8080/res/; }
-
Different servers with redirect - Configure your web server to redirect
/res/to another domain.
Important: The /res/ path is hardcoded in the WAR and cannot be changed without recompiling the source code.
See cohesive-common-resources documentation for details on deploying the resources application.
| Variable | Description | Example |
|---|---|---|
GIT_REPO |
CMDBuild source repository URL | https://github.com/genpat-it/cohesive-cmdbuild |
GIT_BRANCH |
Branch to build from | main |
| Variable | Default | Description |
|---|---|---|
GIT_TOKEN |
(empty) | Authentication token for private repos (HTTP) |
GIT_COMMIT |
(empty) | Specific commit hash to checkout (omit for branch HEAD) |
GIT_SSH_PORT |
(empty) | Custom SSH port for git clone (e.g., 222 for Gitea) |
MAVEN_THREADS |
128 |
Maven parallel build threads |
SKIP_SENCHA_TESTING |
true |
Skip Sencha testing build (saves ~2:48 min, omits ui_dev/ from WAR) |
KEEP_BUILDS |
5 |
Number of old WAR builds to keep in output/ |
GIT_REPO=https://github.com/genpat-it/cohesive-cmdbuild \
GIT_BRANCH=main \
./build-war.shGIT_REPO=https://github.com/genpat-it/cohesive-cmdbuild \
GIT_BRANCH=main \
GIT_TOKEN=your_token_here \
./build-war.shGIT_REPO=git@gitea.example.com:org/cmdbuild-ui.git \
GIT_BRANCH=main \
GIT_SSH_PORT=222 \
./build-war.shNote: SSH builds use SSH agent forwarding via BuildKit. The script automatically starts
ssh-agentand loads your default key.
GIT_REPO=https://github.com/genpat-it/cohesive-cmdbuild \
GIT_BRANCH=main \
GIT_COMMIT=a1b2c3d \
./build-war.shNote: When
GIT_COMMITis set, the full branch history is cloned (no--depth 1) so the commit can be checked out. When omitted, a shallow clone is used for faster builds.
GIT_REPO=https://github.com/genpat-it/cohesive-cmdbuild \
GIT_BRANCH=main \
SKIP_SENCHA_TESTING=false \
./build-war.shNote: By default
SKIP_SENCHA_TESTING=true, which skips the Sencha testing build and omitsui_dev/from the WAR, saving ~2:48 minutes. Set tofalseif you need the debug UI with source maps.
GIT_REPO=https://github.com/genpat-it/cohesive-cmdbuild \
GIT_BRANCH=main \
MAVEN_THREADS=1 \
./build-war.shThe build system supports pre-build string replacements — find/replace operations applied to source files after cloning but before Maven compilation. This is useful for changing hardcoded values (URLs, hostnames, configuration strings) in the source code before it gets compiled into the WAR.
- The
pre-build-apply.shscript is executed inside the Docker build after the git clone step - By default, it's a no-op (does nothing)
- When managed by pg-diff-web, the script is auto-generated with the configured replacement rules before each build, and restored to no-op afterwards
- Each rule specifies a file glob pattern (e.g.,
*.json,*.properties) and a find/replace pair - Replacements use
perl -pi -ewith\Q...\Equoting for safe literal string matching
Each replacement rule can be configured as:
| Phase | When | Applied to |
|---|---|---|
| Pre-build | After git clone, before Maven | Source files (.java, .properties, .json, etc.) |
| Post-build | After WAR is generated | Files inside the WAR (extracted, modified, re-packed) |
Pre-build is useful when you need changes compiled into Java classes or processed by Maven resource filtering. Post-build is useful for config files and static resources that don't need recompilation.
For quick changes (locales, JS files, configuration) without a full Sencha/Maven rebuild:
# 1. Create a patch directory mirroring the WAR structure
mkdir -p patch/ui/app/locales
cp my-locale-it.js patch/ui/app/locales/locale-it.js
# 2. Apply the patch to an existing WAR
./hotpatch-war.sh ./output/cohesive-latest.war ./patch
# 3. Verify
unzip -p ./output/cohesive-latest.war ui/app/locales/locale-it.js | head -5The patch directory mirrors the WAR internal structure:
patch/
├── ui/ → production UI files
├── ui_dev/ → testing/debug UI files (if present in WAR)
└── WEB-INF/ → configuration files (web.xml, conf/, sql/)
This takes seconds instead of minutes — no Docker, Maven, or Sencha needed.
cohesive-cmdbuild-builder/
├── Dockerfile # Builds the WAR from source
├── build-war.sh # Build script
├── pre-build-apply.sh # Pre-build string replacements (auto-generated)
├── hotpatch-war.sh # Quick WAR patching (no rebuild)
├── deploy-war.sh # Automatic deployment script (optional)
├── WEB-INF/ # Template files included in WAR
│ ├── web.xml # Tomcat servlet configuration
│ ├── conf/ # CMDBuild configuration
│ │ └── database.conf # **Edit with your PostgreSQL config**
│ └── sql/ # SQL directories (empty but required)
│ ├── functions/
│ └── patches/
├── output/ # Build output directory
│ ├── cohesive-*.war # Timestamped WAR files
│ └── cohesive-latest.war # Symlink to latest build
└── README.md # This file
┌─ Stage 1: builder ──────────────────────────┐
│ Source Code (Git: configurable repo + branch)│
│ ↓ │
│ Pre-Build Replacements (optional) │
│ ↓ │
│ Maven Build (Java compilation, 128 threads) │
│ ↓ │
│ Sencha Cmd Build (UI production only) │
│ ↓ │
│ Inject WEB-INF (web.xml, conf/, sql/) │
│ ↓ │
│ cmdbuild-final.war │
└──────────────────────────────────────────────┘
↓ COPY --from=builder
┌─ Stage 2: export (Alpine, ~370MB) ──────────┐
│ cmdbuild-final.war → output/cohesive-*.war │
│ → output/cohesive-latest.war (symlink) │
└──────────────────────────────────────────────┘
Old builds are automatically cleaned up (keeps last 5 by default, configurable via KEEP_BUILDS).
- Docker 20.10+ with BuildKit enabled (enabled by default in Docker 23.0+)
- Disk Space: ~2-3GB free
- Build Time: ~3:30 min (default), ~6 min (with
SKIP_SENCHA_TESTING=false) - Network: Access to source repository and Maven Central
- CPU: More cores = faster builds (128 parallel Maven threads by default)
# Clean Docker cache
docker system prune -af --volumes# Provide a Git token for private repositories
GIT_REPO=https://... \
GIT_BRANCH=main \
GIT_TOKEN=your_token_here \
./build-war.shThis should not happen with the cohesive builder. If it does:
# Verify Dockerfile includes this line:
grep "cp -r /tmp/webinf-template/sql" DockerfileShould show: cp -r /tmp/webinf-template/sql /tmp/war/WEB-INF/
The WAR is missing WEB-INF/sql/{functions,patches} directories.
Solution: Rebuild the WAR with the latest Dockerfile.
CMDBuild 3.4.3+ requires non-root user for security.
Solution: Run Tomcat as tomcat, ubuntu, or any non-root user (UID > 0).
Check your WEB-INF/conf/database.conf and ensure the database host, port, username and password are correct before building the WAR.
Try single-threaded build for better error visibility:
MAVEN_THREADS=1 GIT_REPO=... GIT_BRANCH=... ./build-war.shYou can integrate the build and deployment process into Jenkins:
pipeline {
agent any
parameters {
string(name: 'GIT_REPO', defaultValue: 'https://github.com/genpat-it/cohesive-cmdbuild', description: 'CMDBuild repository')
string(name: 'GIT_BRANCH', defaultValue: 'main', description: 'Branch to build')
string(name: 'TOMCAT_URL', defaultValue: 'http://tomcat-server:8080', description: 'Tomcat Manager URL')
string(name: 'APP_CONTEXT', defaultValue: 'cohesive', description: 'Application context path')
}
stages {
stage('Build WAR') {
steps {
sh """
GIT_REPO=${params.GIT_REPO} \
GIT_BRANCH=${params.GIT_BRANCH} \
./build-war.sh
"""
}
}
stage('Deploy') {
steps {
withCredentials([string(credentialsId: 'TOMCAT_MANAGER_AUTH', variable: 'MANAGER_AUTH')]) {
sh """
TOMCAT_URL=${params.TOMCAT_URL} \
TOMCAT_AUTH_HEADER="Basic \${MANAGER_AUTH}" \
APP_CONTEXT=${params.APP_CONTEXT} \
./deploy-war.sh
"""
}
}
}
}
}Note: Store the Base64-encoded credentials in Jenkins as a Secret Text credential with ID TOMCAT_MANAGER_AUTH.
To generate the Base64 credential:
echo -n "username:password" | base64If you want to test COHESIVE with a local PostgreSQL database:
-
Set up PostgreSQL (if not already installed):
# Install PostgreSQL 13 or higher sudo apt-get install postgresql-13 -
Create database and restore your dump:
# Create database sudo -u postgres createdb cohesive # Restore your dump sudo -u postgres psql cohesive < your_dump.sql
-
Configure database connection in
WEB-INF/conf/database.conf:db.url=jdbc:postgresql://localhost:5432/cmdbuild db.username=postgres db.password=postgres
-
Build the WAR - The configuration will be included automatically
GIT_REPO=https://github.com/genpat-it/cohesive-cmdbuild \ GIT_BRANCH=main \ ./build-war.sh
-
Deploy to Tomcat - Copy the generated
cohesive-*.warto your Tomcatwebapps/directory
The WAR includes minimal configuration files in WEB-INF/:
web.xml- Tomcat servlet configuration (pre-configured)conf/database.conf- Edit this with your PostgreSQL connection details
All configuration files are automatically included in the WAR during build.
The build system uses Docker BuildKit cache mounts for maximum performance:
The Dockerfile is optimized with BuildKit cache mounts for:
-
Maven dependencies (
/root/.m2)- Dependencies are cached across builds
- Shared between containers with
sharing=locked - Survives container removal
-
APT packages (
/var/cache/apt,/var/lib/apt)- System packages are cached
- Faster dependency installation
-
Downloaded files (
/tmp/cache)- Sencha Cmd installer cached
- libssl package cached
- Default build (
SKIP_SENCHA_TESTING=true): ~3:30 min - Full build (
SKIP_SENCHA_TESTING=false): ~6 min - Hotpatch (JS/locale/config changes): seconds
- Clean rebuild: Use
docker builder pruneto clear cache
The build script prints a timing summary at the end:
=========================================
Build Timing
=========================================
Docker build: 3:10
WAR extract: 0:03
─────────────────────
Total: 3:14
=========================================
View cache usage:
docker buildx duClear build cache:
docker builder prune -afClear specific cache:
# Clear only Maven cache
docker builder prune --filter type=exec.cachemountThe old volume-based caching is no longer needed thanks to BuildKit. The following approach is deprecated:
Old volume-based approach (click to expand)
# OLD METHOD - Not recommended
docker volume create maven-repo
docker build -v maven-repo:/root/.m2 ...BuildKit cache mounts are superior because they:
- Don't require manual volume management
- Work automatically with
--mount=type=cache - Are cleaned up with
docker builder prune
This builder provides:
- Complete WAR → All configurations included
- Pre-configured → Edit database.conf before build
- Reproducible → Same inputs = same output
- Simple → One command to build
⚠️ Never commit real database credentials to version control⚠️ Never commit Git tokens in build scripts⚠️ Use environment variables for sensitive data- ✅ Run Tomcat as non-root user (CMDBuild requirement)
- ✅ Use HTTPS in production deployments
We welcome contributions! To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Test builds with different repositories and branches
- Document new features in README
- Maintain backward compatibility
- Follow existing code style
Q: Can I build from any CMDBuild repository?
A: Yes! Just set GIT_REPO and GIT_BRANCH to point to your source.
Q: Do I need to modify the Dockerfile for my project?
A: No. Use environment variables (GIT_REPO, GIT_BRANCH, etc.) to configure.
Q: What CMDBuild versions are supported? A: Currently tested with CMDBuild 3.4.3. May work with other 3.x versions.
Q: Can I use this for production deployments? A: Yes! The cohesive WAR is production-ready. Just configure your database properly.
Q: How do I update to a new version?
A: Change GIT_BRANCH to the new version branch and rebuild.
This build system is provided as-is for CMDBuild deployment automation.
CMDBuild itself is licensed under AGPL v3.
- CMDBuild: https://www.cmdbuild.org/
- GenPat Project: https://github.com/genpat-it
- Sencha Cmd: Required for ExtJS UI compilation
- Contributors: See GitHub contributors
For issues, questions, or suggestions:
- Open an issue on GitHub
- Check existing issues and documentation
- Provide detailed information (build logs, environment, steps to reproduce)
Built with ❤️ by the COHESIVE Team
Making COHESIVE deployment simple, reliable, and reproducible.