Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 30 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Contributing

Thanks for helping improve Mendix Runtime Crates!

## The one hard rule: no Mendix binaries

This repository ships **recipes only** — `Dockerfile`, `start.sh`, YAML, docs. It
must **never** contain a Mendix binary (`*.tar.gz`, `*.mda`, `*.mpr`, `*.jar`,
`*.war`, …). The Mendix runtime is pulled from `cdn.mendix.com` at build time, on
the build machine — never committed.

A CI guard (`guard.sh`, run by `.github/workflows/no-mendix-binaries.yml`) fails
any change that adds a forbidden file pattern or any file over 256 KB. `main` is
protected: this check must pass before a PR can merge. Run it locally first:

```sh
./guard.sh
```

## Adding a new Mendix version

See **[Contributing a new version](README.md#contributing-a-new-version)**. In
short: copy the closest crate, set the `FROM` JDK base for that major (MX7/8 → 8,
MX9 → 11, MX10/11 → 21), set `ARG MENDIX_VERSION`, build, smoke-test against a real
app, and record the result in `versions.yaml` + `provenance.yaml`.

## Pull requests

Keep changes focused — one version or one doc per PR where practical. Be kind in
reviews and issues.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ build time — these recipes publish no registry image, so name it whatever suit
your pipeline. See each crate's `README.md` for the full env-var contract,
bind-mount layout, and a `docker compose` smoke example.

## Guides

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.

## How distribution works (and the Mendix IP line)

These recipes are distributed **recipe-only**:
Expand Down
104 changes: 104 additions & 0 deletions docs/running-mendix-7-in-docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Running Mendix 7 in Docker

**Mendix 7.23** shipped in 2017 and runs on **Java 8**. It is long out of mainstream support, but plenty of organisations still maintain production Mendix 7 apps — and getting one to *run locally* for testing, debugging, CI, or a migration spike is painful: the official tooling assumes Studio Pro on Windows, the cloud buildpack bakes your model into a throwaway image, and the modern Mendix Docker guidance simply doesn't cover a runtime this old.

The **`mendix-7` runtime crate** solves this. It is a model-agnostic, version-pinned Docker image that boots *any* Mendix 7.x application you bind-mount into it — no Studio Pro, no model baked into the image, no Mendix binaries committed to source control.

> **TL;DR**
> ```bash
> cd crates/mendix-7
> docker build --platform linux/amd64 --build-arg MENDIX_VERSION=7.23.8.58888 \
> -t ontologylabs/mendix-runtime:7 .
> unzip your-mx7-app.mda -d ./tests/mda
> docker compose -f tests/docker-compose.smoke.yml up # → http://localhost:8080
> ```

## What you get

* **Java 8 + the Mendix 7.23 runtime**, pulled from `cdn.mendix.com` at build time (never committed).
* **Your model bind-mounted**, not baked — `docker compose restart` to reload, with zero dangling images.
* A **PostgreSQL-backed** runtime driven entirely through the **m2ee admin protocol** — the same protocol Mendix Cloud and `m2ee-tools` use against production Mendix 7 servers.
* Verified: this crate boots **MoneyWorksPortal 7.23.8** to a healthy **HTTP 200**.

## Prerequisites

* Docker (Docker Desktop on macOS/Windows, or any engine on Linux).
* An **unzipped MDA** of your Mendix 7 app — a directory containing `model/metadata.json`. (An `.mda` is just a zip; `unzip your.mda -d ./app/`.)
* That's it. No Studio Pro, no Windows, no Mendix account.

## Step 1 — build the runtime image

```bash
cd crates/mendix-7
docker build \
--platform linux/amd64 \
--build-arg MENDIX_VERSION=7.23.8.58888 \
-t ontologylabs/mendix-runtime:7.23.8.58888 \
-t ontologylabs/mendix-runtime:7 \
.
```

The Dockerfile `curl`s `https://cdn.mendix.com/runtime/mendix-7.23.8.58888.tar.gz` (~341 MB) and asserts the expected `runtimelauncher.jar` is present — so a CDN or layout change fails the build loudly rather than at runtime. The image is **reusable across every Mendix 7.23 app**; build it once.

> **Apple Silicon / arm64:** the image is `linux/amd64` and runs under emulation. The pure-Java runtime works fine; expect a slower first boot (JVM container-start alone can take ~60 s under emulation).

## Step 2 — run it against your app

```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:7.23.8.58888
depends_on: [postgres]
environment:
ADMIN_PASSWORD: "ChangeMe2026!" # the runtime rejects weak passwords
DATABASE_ENDPOINT: "postgres://mendix:mendix@postgres:5432/mendix"
DEVELOPMENT_MODE: "true"
ports: ["8080:8080", "8090:8090"]
volumes:
- ./app:/opt/mendix/app # your unzipped MDA
- mendix-data:/opt/mendix/data
volumes: { mendix-data: {} }
```

```bash
docker compose up
curl -fsSI http://localhost:8080/ # 200 OK once the runtime is up
```

On first boot the crate creates the schema (DDL sync) and starts the runtime; subsequent boots are fast. Port `8080` is the app; `8090` is the m2ee admin protocol.

## Mendix-7-specific gotchas (the things that actually trip people up)

* **Java 8, not 11/21.** Mendix 7.x targets Java 8 — the crate's base image is `eclipse-temurin:8-jre-jammy`. Newer JDKs are not a drop-in for the MX7 runtime/toolchain.
* **Model-default constants must be supplied.** The Mendix runtime does **not** auto-apply a constant's *model default* when the deployment config omits it — that's normally the buildpack's job. Omit them and startup fails with `Could not find value for constant '<Module.Const>'` during microflow-engine reload. The crate handles this automatically: `start.sh` reads the constants and their defaults from your model's `metadata.json` and supplies them. Override any value with the `MICROFLOW_CONSTANTS` env var (`{"Module.Constant":"value"}`).
* **`HttpHeaders` is not a recognised config key on MX7.** The runtime logs `Unknown configuration setting 'HttpHeaders'` and ignores it — harmless; leave `MXRUNTIME_HttpHeaders` empty.
* **Weak admin passwords are rejected.** `ADMIN_PASSWORD=1` throws inside `PasswordStrengthVerifier`. Use a real password.
* **The boot path is stable.** Mendix 7.23's `runtimelauncher.jar` + m2ee admin protocol are the *same* mechanism as Mendix 8/9/10/11 — so the identical `start.sh` drives every major. (We assert the launcher's presence at build time.)

## How it differs from the cloud buildpack

| | `cf-mendix-buildpack` image | `mendix-7` crate |
|---|---|---|
| Application model | **baked into the image** | **bind-mounted** |
| Reload | `docker build --no-cache` (~minutes) | `docker compose restart` (~seconds) |
| Disk per reload | ~785 MB dangling | 0 |
| Image per app/commit | many | one per Mendix version |
| Mendix binary in your repo | n/a | **never** (pulled from CDN at build) |

## Troubleshooting

* **`Could not find value for constant …`** — a no-default constant wasn't supplied. The crate auto-supplies model defaults; if you overrode `MICROFLOW_CONSTANTS`, make sure your JSON includes every required constant.
* **Hangs on first boot under emulation** — large apps doing DDL on amd64 emulation are slow; give it time (the bundled smoke test's poll timeout is configurable via `SMOKE_TIMEOUT`).
* **`runtimelauncher.jar not found` at build** — the CDN tarball layout changed or the version string is wrong; check `MENDIX_VERSION` matches your model's `RuntimeVersion` in `metadata.json`.

## Provenance & licence

The crate scaffolding (Dockerfile, `start.sh`, docs) is **Apache-2.0**. The Mendix runtime it downloads is Mendix's IP and is **never committed here** — it is `curl`ed from the official CDN at build time on your machine, and remains subject to [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. Maintaining a Mendix 8, 9, or 10 app? The same pattern works for every version — see the [README](../README.md).*
Loading