From f004a81269af07a2dedaebd18b20cb7753a5e74e Mon Sep 17 00:00:00 2001 From: Hardy Jonck Date: Thu, 18 Jun 2026 22:31:30 +0200 Subject: [PATCH] docs: Running Mendix 9, 10 & 11 in Docker guides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete the per-version guide series (9.24/Java11 — why JDK21 fails + native mobile; 10.24 LTS/Java21 — DEVELOPMENT_MODE + large-app first-boot DDL; 11.x/Java21 — strict startup). Link all four from the README Guides section; note the MX8 guide follows once an MX8 crate ships. --- README.md | 16 ++++-- docs/running-mendix-10-in-docker.md | 70 ++++++++++++++++++++++++++ docs/running-mendix-11-in-docker.md | 69 ++++++++++++++++++++++++++ docs/running-mendix-9-in-docker.md | 76 +++++++++++++++++++++++++++++ 4 files changed, 226 insertions(+), 5 deletions(-) create mode 100644 docs/running-mendix-10-in-docker.md create mode 100644 docs/running-mendix-11-in-docker.md create mode 100644 docs/running-mendix-9-in-docker.md diff --git a/README.md b/README.md index 99609ed..2c8e4da 100644 --- a/README.md +++ b/README.md @@ -86,11 +86,17 @@ bind-mount layout, and a `docker compose` smoke example. Version-specific, step-by-step walkthroughs: -- **[Running Mendix 7 in Docker](docs/running-mendix-7-in-docker.md)** — boot a - legacy Mendix 7.23 app (Java 8) with no Studio Pro, covering the - model-default-constants gotcha and the m2ee boot path. - -Per-version guides for Mendix 8 / 9 / 10 / 11 are on the way. +- **[Running Mendix 7 in Docker](docs/running-mendix-7-in-docker.md)** — legacy + 7.23 (Java 8): the model-default-constants gotcha and the m2ee boot path. +- **[Running Mendix 9 in Docker](docs/running-mendix-9-in-docker.md)** — 9.24 + (Java 11): why JDK 21 fails, and native-mobile apps. +- **[Running Mendix 10 in Docker](docs/running-mendix-10-in-docker.md)** — 10.24 + LTS (Java 21): development mode and large-app first-boot DDL. +- **[Running Mendix 11 in Docker](docs/running-mendix-11-in-docker.md)** — latest + 11.x (Java 21): strict startup and `DEVELOPMENT_MODE`. + +A Mendix 8 guide will follow once an MX8 crate ships (pending a CDN-available +runtime version). ## How distribution works (and the Mendix IP line) diff --git a/docs/running-mendix-10-in-docker.md b/docs/running-mendix-10-in-docker.md new file mode 100644 index 0000000..833c8ae --- /dev/null +++ b/docs/running-mendix-10-in-docker.md @@ -0,0 +1,70 @@ +# Running Mendix 10 in Docker + +**Mendix 10** (the **10.24 LTS** line) is the current long-term-support release and the version most production apps target today. The **`mendix-10` runtime crate** boots *any* Mendix 10.x application you bind-mount into it — model-free, Studio-Pro-free, with no Mendix binaries in your repo. It's ideal for local testing, CI, and migration spikes against real production models. + +> **TL;DR** +> ```bash +> cd crates/mendix-10 +> docker build --platform linux/amd64 --build-arg MENDIX_VERSION=10.24.13.86719 \ +> -t ontologylabs/mendix-runtime:10 . +> unzip your-mx10-app.mda -d ./tests/mda +> docker compose -f tests/docker-compose.smoke.yml up # → http://localhost:8080 +> ``` + +## What you get + +* **Java 21 + the Mendix 10.24 runtime**, pulled from `cdn.mendix.com` at build time (never committed). Mendix 10.24 LTS supports JDK 21; the base image is `eclipse-temurin:21-jre-jammy`. +* **Your model bind-mounted**, not baked — `docker compose restart` to reload, zero dangling images. +* PostgreSQL-backed, driven through the **m2ee admin protocol**. +* Verified: this crate boots a **large production app — AdviserMarketplace (10.24.13)** — to a healthy **HTTP 200**, with 91 model-default constants and 9,647 first-boot DDL commands. + +## Build & run + +```bash +cd crates/mendix-10 +docker build --platform linux/amd64 --build-arg MENDIX_VERSION=10.24.13.86719 \ + -t ontologylabs/mendix-runtime:10.24.13.86719 -t ontologylabs/mendix-runtime:10 . +``` + +```yaml +# docker-compose.yml +services: + postgres: + image: postgres:14-alpine + environment: { POSTGRES_USER: mendix, POSTGRES_PASSWORD: mendix, POSTGRES_DB: mendix } + mendix: + image: ontologylabs/mendix-runtime:10.24.13.86719 + depends_on: [postgres] + environment: + ADMIN_PASSWORD: "ChangeMe2026!" + DATABASE_ENDPOINT: "postgres://mendix:mendix@postgres:5432/mendix" + DEVELOPMENT_MODE: "true" + ports: ["8080:8080", "8090:8090"] + volumes: ["./app:/opt/mendix/app", "mendix-data:/opt/mendix/data"] +volumes: { mendix-data: {} } +``` + +## Mendix-10-specific notes + +* **`DEVELOPMENT_MODE=true`** is the easy path for local runs: it forces `DTAPMode=D`, relaxing the strict project-security checks (`CheckFormsAndMicroflows` / `CheckEverything`) that otherwise block a non-production deploy. Drop it for production-faithful runs. +* **Large apps take a while on the *first* boot.** A real production model can run thousands of DDL commands to create its schema (AdviserMarketplace: 9,647). On native hardware that's quick; under **amd64 emulation on Apple Silicon** it can take ~10 minutes. The bundled smoke test's poll timeout is configurable — `SMOKE_TIMEOUT=1200 ./tests/smoke-test.sh `. Subsequent boots reuse the schema and are fast. +* **Model-default constants are auto-supplied.** Like Mendix 9, the MX10 runtime doesn't auto-apply model defaults when the deployment config omits them; `start.sh` reads them from `metadata.json` and supplies them (override with `MICROFLOW_CONSTANTS`). +* **`HttpHeaders`** logs a harmless `Unknown configuration setting` — leave `MXRUNTIME_HttpHeaders` empty. + +## How it differs from the cloud buildpack + +The `cf-mendix-buildpack` image bakes the model (a new ~785 MB image, orphaned, per reload). This crate bind-mounts it: `docker compose restart`, zero dangling images, one image per Mendix version. (Full table in the [Mendix 7 guide](running-mendix-7-in-docker.md#how-it-differs-from-the-cloud-buildpack).) + +## Troubleshooting + +* **Never reaches HTTP 200 on first boot** — it's probably still doing DDL on a large model under emulation. Watch the logs for `Executing N database synchronization command(s)` and raise `SMOKE_TIMEOUT`. +* **`Could not find value for constant …`** — a no-default constant wasn't supplied; the crate auto-supplies model defaults, so check any `MICROFLOW_CONSTANTS` override is complete. +* **Refuses to start citing project security** — set `DEVELOPMENT_MODE=true` for local runs. + +## Provenance & licence + +The crate scaffolding is **Apache-2.0**. The Mendix runtime is `curl`ed from the official CDN at build time and is **never committed** — it remains Mendix's IP under [Mendix's terms of use](https://www.mendix.com/terms-of-use/). + +--- + +*Part of [mendix-runtime-crates](https://github.com/ontologylabs/mendix-runtime-crates) — the runtime layer of the **mxto** Mendix toolchain. The same pattern works for Mendix 7, 8, 9, and 11 — see the [README](../README.md).* diff --git a/docs/running-mendix-11-in-docker.md b/docs/running-mendix-11-in-docker.md new file mode 100644 index 0000000..ca0f0c1 --- /dev/null +++ b/docs/running-mendix-11-in-docker.md @@ -0,0 +1,69 @@ +# Running Mendix 11 in Docker + +**Mendix 11** is the latest major release. New apps start here, and teams evaluating Mendix want a fast, repeatable way to run an 11.x app in a container — for CI, demos, or local development — without baking the model into a throwaway image. The **`mendix-11` runtime crate** does exactly that: bind-mount your MDA, get a working runtime, reload in seconds. + +> **TL;DR** +> ```bash +> cd crates/mendix-11 +> docker build --platform linux/amd64 --build-arg MENDIX_VERSION=11.6.4 \ +> -t ontologylabs/mendix-runtime:11 . +> unzip your-mx11-app.mda -d ./tests/mda +> docker compose -f tests/docker-compose.smoke.yml up # → http://localhost:8080 +> ``` + +## What you get + +* **Java 21 + the Mendix 11.x runtime**, pulled from `cdn.mendix.com` at build time (never committed). Base image `eclipse-temurin:21-jre-jammy`. +* **Your model bind-mounted**, not baked — `docker compose restart` to reload, zero dangling images. +* PostgreSQL-backed, driven through the **m2ee admin protocol**. +* Verified: this crate boots both **Claudius** (a certification reference app) and **ExpenseWorks** (an independent fresh 11.6.4 app) to a healthy **HTTP 200** in ~15–25 s — the same image, different ProjectIDs, confirming it's genuinely "any v11 app". + +## Build & run + +```bash +cd crates/mendix-11 +docker build --platform linux/amd64 --build-arg MENDIX_VERSION=11.6.4 \ + -t ontologylabs/mendix-runtime:11.6.4 -t ontologylabs/mendix-runtime:11 . +``` + +```yaml +# docker-compose.yml +services: + postgres: + image: postgres:14-alpine + environment: { POSTGRES_USER: mendix, POSTGRES_PASSWORD: mendix, POSTGRES_DB: mendix } + mendix: + image: ontologylabs/mendix-runtime:11.6.4 + depends_on: [postgres] + environment: + ADMIN_PASSWORD: "ChangeMe2026!" + DATABASE_ENDPOINT: "postgres://mendix:mendix@postgres:5432/mendix" + DEVELOPMENT_MODE: "true" + ports: ["8080:8080", "8090:8090"] + volumes: ["./app:/opt/mendix/app", "mendix-data:/opt/mendix/data"] +volumes: { mendix-data: {} } +``` + +## Mendix-11-specific notes + +* **Strict startup by default.** Mendix 11 refuses to load a production/acceptance MDA unless project security is `CheckEverything` *and* a strong admin password is set. For local runs, `DEVELOPMENT_MODE=true` (forces `DTAPMode=D`) relaxes that — and `ADMIN_PASSWORD` must be a real password (weak values like `1` are rejected in `PasswordStrengthVerifier`). +* **Custom CSP / HTTP headers.** The default empty `MXRUNTIME_HttpHeaders=[]` is harmless. If you need to inject custom response headers (e.g. a CSP for browser automation), note that the exact v11 config-key wiring is still being finalised — for plain app runs you don't need it. +* **Constants are auto-supplied** from the model's `metadata.json` defaults (override with `MICROFLOW_CONSTANTS`). Mendix 11 is more tolerant of omitted constants than 9/10, but the crate supplies them for consistency across versions. +* **Forward-compatible:** additional 11.x patch releases bake into the same image as extra `/opt/mendix/runtimes//` subdirs; `start.sh` resolves the right one per the deployed model's `metadata.json`. + +## How it differs from the cloud buildpack + +The `cf-mendix-buildpack` image bakes the model (a new ~785 MB image, orphaned, per reload). This crate bind-mounts it: `docker compose restart`, zero dangling images, one image per Mendix version. (Full table in the [Mendix 7 guide](running-mendix-7-in-docker.md#how-it-differs-from-the-cloud-buildpack).) + +## Troubleshooting + +* **Refuses to start citing project security / password** — set `DEVELOPMENT_MODE=true` and a strong `ADMIN_PASSWORD`. +* **`runtimelauncher.jar not found` at build** — `MENDIX_VERSION` must match your model's `RuntimeVersion` in `metadata.json`. + +## Provenance & licence + +The crate scaffolding is **Apache-2.0**. The Mendix runtime is `curl`ed from the official CDN at build time and is **never committed** — it remains Mendix's IP under [Mendix's terms of use](https://www.mendix.com/terms-of-use/). + +--- + +*Part of [mendix-runtime-crates](https://github.com/ontologylabs/mendix-runtime-crates) — the runtime layer of the **mxto** Mendix toolchain. The same pattern works for Mendix 7, 8, 9, and 10 — see the [README](../README.md).* diff --git a/docs/running-mendix-9-in-docker.md b/docs/running-mendix-9-in-docker.md new file mode 100644 index 0000000..267e0a7 --- /dev/null +++ b/docs/running-mendix-9-in-docker.md @@ -0,0 +1,76 @@ +# Running Mendix 9 in Docker + +**Mendix 9** (the 9.x LTS line, e.g. **9.24**) is still one of the most widely deployed Mendix versions in production — and one of the most awkward to run locally without Studio Pro. The **`mendix-9` runtime crate** boots *any* Mendix 9.x application you bind-mount into it: no Studio Pro, no model baked into the image, no Mendix binaries in your repo. + +> **TL;DR** +> ```bash +> cd crates/mendix-9 +> docker build --platform linux/amd64 --build-arg MENDIX_VERSION=9.24.20.33307 \ +> -t ontologylabs/mendix-runtime:9 . +> unzip your-mx9-app.mda -d ./tests/mda +> docker compose -f tests/docker-compose.smoke.yml up # → http://localhost:8080 +> ``` + +## What you get + +* **Java 11 + the Mendix 9.24 runtime**, pulled from `cdn.mendix.com` at build time (never committed). +* **Your model bind-mounted**, not baked — `docker compose restart` to reload, zero dangling images. +* PostgreSQL-backed, driven through the **m2ee admin protocol** (the same mechanism Mendix Cloud uses). +* Verified: this crate boots the native-mobile app **FigWarehouse 9.24.20** to a healthy **HTTP 200**. + +## The one rule that bites everyone: use JDK 11, not 21 + +**Mendix 9.24 is incompatible with JDK 21.** The 9.x toolchain bundles Gradle 7.6.3, which throws `Unsupported class file major version 65` on Java 21. The crate's base image is therefore `eclipse-temurin:11-jre-jammy` — do **not** "upgrade" it to 17/21 for a Mendix 9 app. + +## Build & run + +```bash +cd crates/mendix-9 +docker build --platform linux/amd64 --build-arg MENDIX_VERSION=9.24.20.33307 \ + -t ontologylabs/mendix-runtime:9.24.20.33307 -t ontologylabs/mendix-runtime:9 . +``` + +```yaml +# docker-compose.yml +services: + postgres: + image: postgres:14-alpine + environment: { POSTGRES_USER: mendix, POSTGRES_PASSWORD: mendix, POSTGRES_DB: mendix } + mendix: + image: ontologylabs/mendix-runtime:9.24.20.33307 + depends_on: [postgres] + environment: + ADMIN_PASSWORD: "ChangeMe2026!" + DATABASE_ENDPOINT: "postgres://mendix:mendix@postgres:5432/mendix" + DEVELOPMENT_MODE: "true" + ports: ["8080:8080", "8090:8090"] + volumes: ["./app:/opt/mendix/app", "mendix-data:/opt/mendix/data"] +volumes: { mendix-data: {} } +``` + +`docker compose up`, then `curl -fsSI http://localhost:8080/`. + +## Mendix-9-specific gotchas + +* **Model-default constants must be supplied.** On Mendix 9 the runtime does **not** auto-apply a constant's model default when the deployment config omits it — startup then fails with `Could not find value for constant ''` during microflow-engine reload. The crate handles this automatically: `start.sh` reads the constants + defaults from your model's `metadata.json` and supplies them (FigWarehouse boots with 10 of them, including a nested-JSON value). Override any with `MICROFLOW_CONSTANTS={"Module.Constant":"value"}`. +* **`HttpHeaders`** logs a harmless `Unknown configuration setting` — leave `MXRUNTIME_HttpHeaders` empty. +* **Native mobile apps** run fine: the crate serves the runtime + the bundled web/native assets; you point your Make-It-Native build at the URL. +* The **m2ee boot path is identical** to Mendix 7/8/10/11, so the same `start.sh` drives it. + +## How it differs from the cloud buildpack + +The `cf-mendix-buildpack` image **bakes the model** — every reload spawns a new ~785 MB image and orphans the last one. This crate bind-mounts the model: reload is `docker compose restart`, disk cost per reload is **0**, and **one image** serves every app at that Mendix version. (Full comparison in the [Mendix 7 guide](running-mendix-7-in-docker.md#how-it-differs-from-the-cloud-buildpack).) + +## Troubleshooting + +* **`Unsupported class file major version 65`** — you're on JDK 21; Mendix 9 needs JDK 11 (the crate's base image is correct out of the box). +* **`Could not find value for constant …`** — a no-default constant wasn't supplied; the crate auto-supplies model defaults, so check any `MICROFLOW_CONSTANTS` override is complete. +* **`runtimelauncher.jar not found` at build** — `MENDIX_VERSION` must match your model's `RuntimeVersion` in `metadata.json`. + +## Provenance & licence + +The crate scaffolding is **Apache-2.0**. The Mendix runtime is `curl`ed from the official CDN at build time and is **never committed** — it remains Mendix's IP under [Mendix's terms of use](https://www.mendix.com/terms-of-use/). + +--- + +*Part of [mendix-runtime-crates](https://github.com/ontologylabs/mendix-runtime-crates) — the runtime layer of the **mxto** Mendix toolchain. The same pattern works for Mendix 7, 8, 10, and 11 — see the [README](../README.md).*