From 8d723292915870e946e89f299a9f2bd5bf9ba633 Mon Sep 17 00:00:00 2001 From: katarzyna_koltun Date: Sun, 10 May 2026 14:19:37 +0200 Subject: [PATCH 01/14] updates --- .../docker-deploy/docker-monitoring.md | 74 ++++++++ .../deployment/docker-deploy/docker-pad.md | 6 +- .../private-cloud-deploy/kubernetes-pad.md | 179 ++++++++++++++++++ 3 files changed, 256 insertions(+), 3 deletions(-) create mode 100644 content/en/docs/deployment/docker-deploy/docker-monitoring.md create mode 100644 content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md diff --git a/content/en/docs/deployment/docker-deploy/docker-monitoring.md b/content/en/docs/deployment/docker-deploy/docker-monitoring.md new file mode 100644 index 00000000000..0ce488e3800 --- /dev/null +++ b/content/en/docs/deployment/docker-deploy/docker-monitoring.md @@ -0,0 +1,74 @@ +--- +title: "Monitoring Tools in Docker" +url: /developerportal/deploy/docker-monitoring/ +weight: 30 +description: "Describes the available monitoring tools for Docker deployments of Mendix." +--- + +## Introduction + +Effective container monitoring is essential for maintaining application performance, detecting issues early, and ensuring overall system health. This guide introduces several widely adopted monitoring tools and explains how to integrate them with your Docker environment. + +Each tool offers distinct capabilities tailored to different use cases. For detailed installation and configuration instructions, refer to the official documentation provided for each tool. + +## Grafana + +Grafana is an open-source platform for monitoring and observability. It allows you to query, visualize, alert on, and understand your metrics no matter where they are stored. When combined with tools like Prometheus or Alloy, Grafana can provide powerful insights into your Docker infrastructure. + +### Key Features + +Grafana offers the following features: + +* Create interactive dashboards. +* Connects to a variety of data sources. +* Set up alerts based on your metrics. + +### Installing and Monitoring Docker Containers with Grafana + +For information on how to set up Grafana and monitor your Docker containers, see [Monitor Docker containers with Grafana Alloy](https://grafana.com/docs/alloy/latest/monitor/monitor-docker-containers/) in Grafana documentation. + +## Datadog + +Datadog is a monitoring and security platform for cloud applications. It provides end-to-end visibility across your entire stack, including Docker containers, by collecting metrics, traces, and logs. + +### Key Features + +Datadog offers the following features: + +* Consolidates metrics, traces, and logs. +* Provides real-time insights into your infrastructure. +* Offers intelligent AI-powered alerting capabilities. + +### Installing and Monitoring Docker Containers with Datadog + +To get started with Datadog for Docker container monitoring, see [Docker Agent for Docker, containerd, and Podman](https://docs.datadoghq.com/containers/docker/?tab=linux) in Datadog documentation. + +## AppDynamics and Splunk + +While AppDynamics and Splunk are distinct products, they both offer robust solutions for application performance monitoring (APM) and operational intelligence. Splunk can ingest data from various sources, including AppDynamics, to provide a comprehensive view of your environment. + +### Key Features + +AppDynamics focuses on deep application performance monitoring. + +Splunk specializes in collecting, indexing, and analyzing machine-generated data. + +### Integrating AppDynamics and Splunk + +For information on how to leverage AppDynamics data within Splunk, or to understand how these powerful tools can work together, see [AppDynamics SaaS](https://help.splunk.com/en/appdynamics-saas) in Splunk documentation. + +## Dynatrace + +Dynatrace provides an all-in-one intelligence platform for enterprise cloud. It offers automatic, intelligent observability across your entire stack, including Docker containers, by continuously discovering, mapping, and monitoring everything. + +### Key Features + +Dynatrace offers the following features: + +* Automatically discovers and maps your environment. +* Pinpoints the root cause of issues quickly. +* Monitors applications, infrastructure, and user experience. + +### Installing and Monitoring Docker Containers with Dynatrace + +To integrate Dynatrace with your Docker environment for comprehensive monitoring, see [Set up Dynatrace on Docker](https://docs.dynatrace.com/docs/ingest-from/setup-on-container-platforms/docker) in Dynatrace documentation. \ No newline at end of file diff --git a/content/en/docs/deployment/docker-deploy/docker-pad.md b/content/en/docs/deployment/docker-deploy/docker-pad.md index 96c03654d54..21fe3119e79 100644 --- a/content/en/docs/deployment/docker-deploy/docker-pad.md +++ b/content/en/docs/deployment/docker-deploy/docker-pad.md @@ -44,7 +44,7 @@ Before you begin, ensure you have the following: The Portable App Distribution feature in Mendix Studio Pro provides you with the necessary application files to build a Docker image. It packages your Mendix application as a self-contained distribution, ready for integration into your Docker environment. -To deploy your app to Docker, you must create a Portable App Distribution Package, build a Docker image, and then deploy the Docker image (including optionally pushing it to a container registry. For more information, refer to the sections below. +To deploy your app to Docker, you must create a Portable App Distribution Package, build a Docker image, and then deploy the Docker image (including optionally pushing it to a container registry). For more information, refer to the sections below. ### Creating a Portable App Distribution Package @@ -98,7 +98,7 @@ To build a Docker image from the Portable Package, perform the following steps: 3. Build the Docker image by using the following command: `docker build -t : -f build/docker/Dockerfile`, where: - * `` and `` - Indicate your required image name and version tag (for example, my-mendix-app:1.0.0). + * `` and `` - Indicate your required image name and version tag (for example, `my-mendix-app:1.0.0`). * `-f build/docker/Dockerfile` - Specifies the path to your Dockerfile. ### Optional: Pushing the Docker Image @@ -109,7 +109,7 @@ To push the Docker image to a container registry, perform the following steps: 2. Tag the Docker image with the registry URL by running the following command: `docker tag : /:`. 3. Push the Docker image to the registry by running the following command: `docker push /:`. -### Deploying the Docker Image +### Deploying the Docker Image {#deploy} Once the Docker image is available in your container registry, you can deploy it to your target environment by performing the following steps: diff --git a/content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md b/content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md new file mode 100644 index 00000000000..0db8533f948 --- /dev/null +++ b/content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md @@ -0,0 +1,179 @@ +--- +title: "Portable App Distribution for Kubernetes" +url: /developerportal/deploy/docker-deploy-k8s/ +weight: 20 +description: "Describes how to use Portable App Distribution to deploy on Kubernetes without installing the Mendix Operator." +--- + +## Introduction + +This guide provides a walkthrough for deploying your Mendix application using [Portable App Distribution](/developerportal/deploy/portable-app-distribution-deploy/) with Kubernetes, but without relying on the Mendix Operator. This is particularly useful for air-gapped environments, private cloud deployments, or scenarios where you need full control over the deployment process. + +{{% alert color="info" %}} +This document is not an official Mendix implementation, or a substitute for recommended production deployment strategies. For more features, such as app management or governance, we suggest using [Mendix on Kubernetes](/developerportal/deploy/private-cloud/) or [Mendix on Azure](/developerportal/deploy/mendix-on-azure/), which offer a structured, tested experience with cloud infrastructure. + +For information about the scope of support, see [Support for Different Deployment Strategies](/support/deployment-strategy-support/). +{{% /alert %}} + +## Benefits of Portable App Distribution + +Portable App Distribution revolutionizes the way in which Mendix applications are packaged and delivered. This innovative approach bundles your application code with all its necessary dependencies into a single, self-contained, and runnable artifact. This greatly simplifies the deployment of Mendix applications, whether you are targeting on-premise infrastructure or modern containerized environments like Docker, making the entire process more efficient and seamless. + +The ability to generate a Portable App Distribution with a single build command means that creating a Docker-ready artifact becomes a streamlined process, making the overall integration into existing Docker-based CI/CD pipelines more efficient and less prone to errors. + +The Portable App Distribution feature allows you to package and deploy Mendix apps without relying on the Mendix Cloud or a Mendix Operator. This is particularly useful for the following use cases: + +* Air-gapped environments where internet access is restricted or unavailable +* Private cloud deployments where you manage your own infrastructure +* Full control scenarios where you need complete ownership of the deployment pipeline + +Docker provides a consistent and reproducible environment for running Mendix apps, making it ideal for cloud-native and containerized deployments. + +Portable App Distribution offers a more agile, user-centric, and efficient deployment ecosystem, empowering customers with greater control over their Docker deployments and simplifying the internal deployment processes. + +## Prerequisites + +Before you begin, ensure you have the following: + +* Mendix Studio Pro version 11.19, 11.6.5, or above +* A Mendix app that you want to deploy +* Docker installed on your system (for building and running Docker images) +* Access to a container registry (for pushing and pulling Docker images) + +## Deploying an App with Portable App Distribution + +The Portable App Distribution feature in Mendix Studio Pro provides you with the necessary application files to build a Docker image. It packages your Mendix application as a self-contained distribution, ready for integration into your Docker environment. + +To deploy your app to Docker, you must create a Portable App Distribution Package, build a Docker image, and then deploy the Docker image (including pushing it to a container registry). For more information, refer to the sections below. + +### Creating a Portable App Distribution Package + +To create a Portable Package from your Mendix app, perform the following steps: + +1. Open your app in Studio Pro. +2. Go to **App** > **Create Deployment Package**. +3. In the **Create Deployment Package** dialog, select **Portable package**. +4. Select the target runtime platform (**linux-x64** or **linux-arm64**). +5. Click **Create Package**. + +The Portable Package is saved to the **releases** folder of your app. + +For more information about Portable Packages, see [Portable App Distribution](/developerportal/deploy/portable-app-distribution-deploy/). Files included in the Portable Package are the core of your Mendix application and are ready to be included in a Docker image. + +### Building a Docker Image + +To build a Docker image from the Portable Package, perform the following steps: + +1. Extract the Portable Package to a directory of your choice. +2. Create a Dockerfile in the extracted directory with contents like the following. + + ```text + # This file provides an example on how to start the runtime in Docker. + # It is based on the configuration named Default. + + FROM eclipse-temurin:21-jdk + + # Set working directory + WORKDIR /mendix + + # Copy Mendix app files into the image + COPY ./app ./app + COPY ./bin ./bin + COPY ./etc ./etc + COPY ./lib ./lib + + # Environment variables (optional) + ENV MX_LOG_LEVEL=info + ENV M2EE_ADMIN_PASS=${M2EE_ADMIN_PASS} + + # Expose ports + EXPOSE 8090 + EXPOSE 8080 + + # Start command + CMD ["./bin/start", "etc/Default"] + ``` + + You must create this Dockerfile yourself and place it alongside the application files generated by the Portable App Distribution. The `COPY` commands in the example above assume that the `app`, `bin`, `etc`, and `lib` directories are in the same location as your Dockerfile. + +3. Build the Docker image by using the following command: `docker build -t : .`, where `` and `` indicate your required image name and version tag (for example, `my-mendix-app:1.0.0`). + +### Pushing the Docker Image + +To push the Docker image to a container registry, perform the following steps: + +1. Log in to your container registry by running the following command: `docker login `. +2. Tag the Docker image with the registry URL by running the following command: `docker tag : /:`. +3. Push the Docker image to the registry by running the following command: `docker push /:`. + +### Deploying the Docker Image + +Once the Docker image is available in your container registry, you can deploy it to your target environment. For more information, see [Portable App Distribution for Docker: Deploying the Docker Image](/developerportal/deploy/docker-deploy-pad/#deploy). + +## Environment Variables {#env-variables} + +You can configure the Mendix Runtime by using environment variables. The following environment variables are supported: + +| Environment Variable | Description | +| --- | --- | +| `MENDIX_DATABASE_URL` | The URL of the database| +| `MENDIX_DATABASE_TYPE` | The type of the database (for example, PostgreSQL, MySQL)| +| `MENDIX_DATABASE_HOST` | The host name of the database server | +| `MENDIX_DATABASE_PORT` | The port of the database server | +| `MENDIX_DATABASE_NAME` |The name of the database | + +For more information, see [Runtime Customization](/refguide/custom-settings/#introduction). + +## Configuration File {#config-file} + +Alternatively, you can configure the Mendix Runtime by using a configuration file. The configuration file is a JSON file that contains the same settings as the environment variables. + +### Example Configuration File + +```json +{ + "DatabaseType": "PostgreSQL", + "DatabaseHost": "localhost:5432", + "DatabaseName": "mendix", + "DatabaseUserName": "mendix", + "DatabasePassword": "mendix", + "AdminPassword": "Admin1234!", + "RuntimePort": 8080, + "RuntimeAdminPort": 8090 +} +``` + +### Using the Configuration File + +To use the configuration file, you can upload the configuration file to the configuration path: + +`docker run --rm -it -p 8080:8080 -e M2EE_ADMIN_PASS= /: \ -v host_path/config.conf:container_path/config.conf` + +You must also mount the volume so that Docker can find it. + +## Logging + +The Mendix Runtime logs to a standard output by default. You can configure the log level using the `MX_LOG_LEVEL` environment variable. + +The following log levels are supported (in order of verbosity): + +| Log Level | Description | +| --------- | ----------- | +| `TRACE` | Most verbose — logs all internal operations | +| `DEBUG` | Detailed diagnostic information | +| `INFO` | General operational messages (default) | +| `WARNING` | Potentially harmful situations | +| `ERROR` | Error events that may still allow the app to continue | +| `CRITICAL` | Severe errors that may cause the app to stop | + +## Health Checks + +The Mendix Runtime exposes health check endpoints that can be used to monitor the status of your app: + +| EndPoint | Description | +| -------- | ----------- | +| `/health` | Returns the overall health status of the app | +| `/health/live` | Returns the liveness status — indicates if the app is running | +| `/health/ready` | Returns the readiness status — indicates if the app is ready to serve traffic | + +These endpoints are especially useful when integrating with orchestration platforms such as Kubernetes, which rely on liveness and readiness probes to manage container lifecycle. From 099f233d12c4ad28856a61b6232bf9ac678fe82c Mon Sep 17 00:00:00 2001 From: katarzyna_koltun Date: Sun, 10 May 2026 14:23:53 +0200 Subject: [PATCH 02/14] updates --- content/en/docs/deployment/docker-deploy/docker-pad.md | 2 +- .../private-cloud/private-cloud-deploy/kubernetes-pad.md | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/content/en/docs/deployment/docker-deploy/docker-pad.md b/content/en/docs/deployment/docker-deploy/docker-pad.md index 21fe3119e79..7bac5f6a5c0 100644 --- a/content/en/docs/deployment/docker-deploy/docker-pad.md +++ b/content/en/docs/deployment/docker-deploy/docker-pad.md @@ -199,7 +199,7 @@ Alternatively, you can configure the Mendix Runtime by using a configuration fil "RuntimePort": 8080, "RuntimeAdminPort": 8090 } -```` +``` ### Using the Configuration File diff --git a/content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md b/content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md index 0db8533f948..9ee3b665241 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md @@ -145,12 +145,10 @@ Alternatively, you can configure the Mendix Runtime by using a configuration fil ### Using the Configuration File -To use the configuration file, you can upload the configuration file to the configuration path: +To use the configuration file, set the `MENDIX_CONFIG_FILE` environment variable to the path of the configuration file: -`docker run --rm -it -p 8080:8080 -e M2EE_ADMIN_PASS= /: \ -v host_path/config.conf:container_path/config.conf` +`export MENDIX_CONFIG_FILE=/path/to/config.json` -You must also mount the volume so that Docker can find it. - ## Logging The Mendix Runtime logs to a standard output by default. You can configure the log level using the `MX_LOG_LEVEL` environment variable. From fd0343265cee6c37e83485c6d528dc31604abde3 Mon Sep 17 00:00:00 2001 From: katarzyna_koltun Date: Mon, 11 May 2026 14:03:04 +0200 Subject: [PATCH 03/14] moved file --- .../private-cloud-deploy => docker-deploy}/kubernetes-pad.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename content/en/docs/deployment/{private-cloud/private-cloud-deploy => docker-deploy}/kubernetes-pad.md (100%) diff --git a/content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md similarity index 100% rename from content/en/docs/deployment/private-cloud/private-cloud-deploy/kubernetes-pad.md rename to content/en/docs/deployment/docker-deploy/kubernetes-pad.md From 48bdd62a579fe53cfe05b16c7b4767693699e0bb Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Wed, 3 Jun 2026 17:39:02 +0200 Subject: [PATCH 04/14] Update kubernetes-pad.md --- .../deployment/docker-deploy/kubernetes-pad.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index 9ee3b665241..9777faad136 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -35,10 +35,12 @@ Portable App Distribution offers a more agile, user-centric, and efficient deplo Before you begin, ensure you have the following: -* Mendix Studio Pro version 11.19, 11.6.5, or above +* Mendix Studio Pro version 10.24.19, 11.6.5, 11.19, or above * A Mendix app that you want to deploy * Docker installed on your system (for building and running Docker images) * Access to a container registry (for pushing and pulling Docker images) +* Any Kubernetes cluster (for example, AKS, EKS, GKE, or on-premises) +* `Kubectl` configured and connected to your cluster ## Deploying an App with Portable App Distribution @@ -53,8 +55,7 @@ To create a Portable Package from your Mendix app, perform the following steps: 1. Open your app in Studio Pro. 2. Go to **App** > **Create Deployment Package**. 3. In the **Create Deployment Package** dialog, select **Portable package**. -4. Select the target runtime platform (**linux-x64** or **linux-arm64**). -5. Click **Create Package**. +4. Click **OK**. The Portable Package is saved to the **releases** folder of your app. @@ -64,7 +65,16 @@ For more information about Portable Packages, see [Portable App Distribution](/d To build a Docker image from the Portable Package, perform the following steps: -1. Extract the Portable Package to a directory of your choice. +1. Extract the Portable Package to a directory of your choice + +```text +# Create a working directory +mkdir mendix-docker && cd mendix-docker + +# Extract the portable package (it's a zip file) +unzip /path/to/releases/YourApp.zip -d . +``` + 2. Create a Dockerfile in the extracted directory with contents like the following. ```text From 55180cb288fc820a08124555c0196ee2f7086566 Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:07:00 +0200 Subject: [PATCH 05/14] Update kubernetes-pad.md --- .../docker-deploy/kubernetes-pad.md | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index 9777faad136..e690c061815 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -118,7 +118,26 @@ To push the Docker image to a container registry, perform the following steps: ### Deploying the Docker Image -Once the Docker image is available in your container registry, you can deploy it to your target environment. For more information, see [Portable App Distribution for Docker: Deploying the Docker Image](/developerportal/deploy/docker-deploy-pad/#deploy). +Once the Docker image is available in your container registry, you can deploy it to Kubernetes by applying the following .yaml files. The .yaml files must be organized in a folder, for example, *k8s/*. You must apply them in the same order as below. + +#### Creating a Namespace + +Create a namespace by performing the following steps: + +1. Create a file named, for example, *k8s/namespace.yaml*, with the following contents: + + ```yaml + apiVersion: v1 + kind: Namespace + metadata: + name: mendix-app + ``` + +2. Apply the file by running the following command: `kubectl apply -f k8s/namespace.yaml`. + + Replace the name and path of the file as required. + + ## Environment Variables {#env-variables} From 205f70c778b314bb0335fc5059e4b49fc3b9ab3e Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 11:44:11 +0200 Subject: [PATCH 06/14] Update kubernetes-pad.md --- .../docker-deploy/kubernetes-pad.md | 213 ++++++++++++++---- 1 file changed, 164 insertions(+), 49 deletions(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index e690c061815..6125248ad76 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -124,7 +124,7 @@ Once the Docker image is available in your container registry, you can deploy it Create a namespace by performing the following steps: -1. Create a file named, for example, *k8s/namespace.yaml*, with the following contents: +1. Create a file named, for example, *k8s/namespace.yaml*, with the contents like the following: ```yaml apiVersion: v1 @@ -137,70 +137,185 @@ Create a namespace by performing the following steps: Replace the name and path of the file as required. +#### Creating a Kubernetes Secret +Store all sensitive values in a Kubernetes Secret by performing the following steps: -## Environment Variables {#env-variables} +1. Create a file named, for example, *k8s/secret.yaml*, with the contents like the following: -You can configure the Mendix Runtime by using environment variables. The following environment variables are supported: + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: mendix-secret + namespace: mendix-app + type: Opaque + stringData: + RUNTIME_PARAMS_DATABASEJDBCURL: "postgresql://mendix:mendix@postgres:5432/mendix" # Defines the JDBC URL to use for the database connection (which overrides the other database connection settings). + RUNTIME_PARAMS_DATABASE_TYPE: "PostgreSQL" + RUNTIME_PARAMS_DATABASE_HOST: "postgresEndpointURL" #This will be overridden if you supply DatabaseJdbcUrl. + RUNTIME_PARAMS_DATABASE_PORT: "5432" + RUNTIME_PARAMS_DATABASE_NAME: "" + RUNTIME_PARAMS_DATABASE_USERNAME: "" + RUNTIME_PARAMS_DATABASE_PASSWORD: "" + RUNTIME_PARAMS_ADMIN_PASSWORD: "" + RUNTIME_PARAMS_LICENSE_LICENSE_ID: "" + RUNTIME_PARAMS_LICENSE_LICENSE_KEY: "" + ``` -| Environment Variable | Description | -| --- | --- | -| `MENDIX_DATABASE_URL` | The URL of the database| -| `MENDIX_DATABASE_TYPE` | The type of the database (for example, PostgreSQL, MySQL)| -| `MENDIX_DATABASE_HOST` | The host name of the database server | -| `MENDIX_DATABASE_PORT` | The port of the database server | -| `MENDIX_DATABASE_NAME` |The name of the database | +2. Apply the file by running the following command: `kubectl apply -f k8s/secret.yaml`. -For more information, see [Runtime Customization](/refguide/custom-settings/#introduction). + Replace the name and path of the file as required. -## Configuration File {#config-file} + {{% alert color="info" %}} + For production environments, consider using a secrets manager like Azure Key Vault, AWS Secrets Manager, or HashiCorp Vault with a CSI driver instead of plain Kubernetes Secrets. + {{% /alert %}} -Alternatively, you can configure the Mendix Runtime by using a configuration file. The configuration file is a JSON file that contains the same settings as the environment variables. +#### Creating a Persistent Volume Claim for Storage -### Example Configuration File +Mendix requires persistent storage for uploaded files. Create a Persistent Volume Claim (PVC) by performing the following steps: -```json -{ - "DatabaseType": "PostgreSQL", - "DatabaseHost": "localhost:5432", - "DatabaseName": "mendix", - "DatabaseUserName": "mendix", - "DatabasePassword": "mendix", - "AdminPassword": "Admin1234!", - "RuntimePort": 8080, - "RuntimeAdminPort": 8090 -} -``` +1. Create a file named, for example, *k8s/pvc.yaml*, with the contents like the following: + + ```yaml + apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: mendix-storage + namespace: mendix-app + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + ``` -### Using the Configuration File +2. Apply the file by running the following command: `kubectl apply -f k8s/pvc.yaml`. -To use the configuration file, set the `MENDIX_CONFIG_FILE` environment variable to the path of the configuration file: + Replace the name and path of the file as required. + + {{% alert color="info" %}} + For multi-replica deployments or cloud-native setups, use S3-compatible storage instead. For more information, see [Configuring Deployment: S3 Storage](#s3-storage). + {{% /alert %}} -`export MENDIX_CONFIG_FILE=/path/to/config.json` - -## Logging +#### Configuring Deployment -The Mendix Runtime logs to a standard output by default. You can configure the log level using the `MX_LOG_LEVEL` environment variable. +Configure deployment settings by performing the following steps: -The following log levels are supported (in order of verbosity): +1. Create a file named, for example, *k8s/deployment.yaml*, with the contents like the following: -| Log Level | Description | -| --------- | ----------- | -| `TRACE` | Most verbose — logs all internal operations | -| `DEBUG` | Detailed diagnostic information | -| `INFO` | General operational messages (default) | -| `WARNING` | Potentially harmful situations | -| `ERROR` | Error events that may still allow the app to continue | -| `CRITICAL` | Severe errors that may cause the app to stop | + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: mendix-app + namespace: mendix-app + labels: + app: mendix-app + spec: + replicas: 1 + selector: + matchLabels: + app: mendix-app + template: + metadata: + labels: + app: mendix-app + spec: + containers: + - name: mendix-app + image: /mendix-app:1.0.0 + ports: + - name: http + containerPort: 8080 + - name: admin + containerPort: 8090 + + # Load sensitive config from Secret + envFrom: + - secretRef: + name: mendix-secret + + # Non-sensitive environment variables + env: + - name: RUNTIME_PARAMS_MENDIX_CORE_STORAGESERVICE + value: "localfilesystem" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_PATH + value: "/data" + - name: RUNTIME_PARAMS_MENDIX_LOG_LEVEL + value: "INFO" + + # Mount persistent storage + volumeMounts: + - name: mendix-storage + mountPath: /data + + # Resource limits + resources: + requests: + memory: "512Mi" + cpu: "250m" + limits: + memory: "1Gi" + cpu: "500m" + + # Health checks + livenessProbe: + httpGet: + path: /health/live + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 10 + failureThreshold: 3 + + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 3 + + volumes: + - name: mendix-storage + persistentVolumeClaim: + claimName: mendix-storage + ``` -## Health Checks +2. Apply the file by running the following command: `kubectl apply -f k8s/deployment.yaml`. -The Mendix Runtime exposes health check endpoints that can be used to monitor the status of your app: + Replace the name and path of the file as required. -| EndPoint | Description | -| -------- | ----------- | -| `/health` | Returns the overall health status of the app | -| `/health/live` | Returns the liveness status — indicates if the app is running | -| `/health/ready` | Returns the readiness status — indicates if the app is ready to serve traffic | +##### S3 Storage {#s3-storage} + +If you are using S3 instead of local storage, make the following changes to the above example file: + +* Remove the `volumeMounts` and `volumes` sections. +* Replace the `env` section with the following: + + ```yaml + env: + env: + - name: RUNTIME_PARAMS_MENDIX_CORE_STORAGESERVICE + value: "com.mendix.storage.s3" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ENDPOINT + value: "" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_BUCKETNAME + value: "" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_REGION + value: "" + ... + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ACCESS_KEYID + valueFrom: + secretKeyRef: + name: mendix-secret + key: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ACCESS_KEYID + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_SECRETACCESSKEY + valueFrom: + secretKeyRef: + name: mendix-secret + key: RUNTIME_PARAMS_MENDIX_STORAGE_S3_SECRETACCESSKEY + ``` -These endpoints are especially useful when integrating with orchestration platforms such as Kubernetes, which rely on liveness and readiness probes to manage container lifecycle. + From 88a24c80592de02e741a50faa36a8c8646731103 Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 12:17:41 +0200 Subject: [PATCH 07/14] Update kubernetes-pad.md --- .../docker-deploy/kubernetes-pad.md | 98 ++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index 6125248ad76..f0da0232743 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -318,4 +318,100 @@ If you are using S3 instead of local storage, make the following changes to the key: RUNTIME_PARAMS_MENDIX_STORAGE_S3_SECRETACCESSKEY ``` - +#### Configuring the Service + +Configure the Service settings by performing the following steps: + +1. Create a file named, for example, *k8s/service.yaml*, with the contents like the following: + + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: mendix-app-service + namespace: mendix-app + spec: + selector: + app: mendix-app + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 8080 + - name: admin + protocol: TCP + port: 8090 + targetPort: 8090 + type: ClusterIP + ``` + +2. Apply the file by running the following command: `kubectl apply -f k8s/service.yaml`. + + Replace the name and path of the file as required. + +#### Configuring the Ingress + +Configure the Ingress settings by performing the following steps: + +1. Create a file named, for example, *k8s/ingress.yaml*, with the contents like the following: + + ```yaml + apiVersion: networking.k8s.io/v1 + kind: Ingress + metadata: + name: mendix-app-ingress + namespace: mendix-app + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + spec: + rules: + - host: your-app.your-domain.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: mendix-app-service + port: + number: 80 + ``` + +2. Optional: To use HTTPS, add a `tls` section to the `spec` of the above example, and reference a TLS secret (for example, from **cert-manager**): + + ```yaml + spec: + tls: + - hosts: + - your-app.your-domain.com + secretName: mendix-tls-secret + ``` + +3. Apply the file by running the following command: `kubectl apply -f k8s/ingress.yaml`. + + Replace the name and path of the file as required. + +### Verifying the Deployment + +Verify the deployment by running the following commands: + +```text +# Check all resources in the namespace +kubectl get all -n mendix-app + +# Watch pod startup +kubectl get pods -n mendix-app -w + +# View app logs +kubectl logs -f deployment/mendix-app -n mendix-app + +# Check ingress +kubectl get ingress -n mendix-app +``` + +## Reference + +### Environment Variables + +The following is a list of available environment variables that you can use. + From 47b5cf710b13d08fdfeec449b91b220549bc9900 Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:23:21 +0200 Subject: [PATCH 08/14] Update kubernetes-pad.md --- .../docker-deploy/kubernetes-pad.md | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index f0da0232743..ed3f0cfb1b6 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -413,5 +413,58 @@ kubectl get ingress -n mendix-app ### Environment Variables -The following is a list of available environment variables that you can use. +The following is a list of available required and optional environment variables. +#### Required + +You must configure the following required variables: + +* `RUNTIME_PARAMS_DATABASEJDBCURL` - The URL of the database +* `RUNTIME_PARAMS_MENDIX_DATABASE_TYPE` - The type of the database (PostgreSQL, MySQL, and so on) +* `RUNTIME_PARAMS_MENDIX_DATABASE_HE` - The hostname of the database server +* `RUNTIME_PARAMS_MENDIX_DATABASE_PORT` - The port of the database server +* `RUNTIME_PARAMS_MENDIX_DATABASE_NAME` - The name of the database +* `RUNTIME_PARAMS_MENDIX_DATABASE_PASSWORD` - Database password +* `RUNTIME_PARAMS_ADMIN_PASSWORD` - The password of the Mendix admin user +* `RUNTIME_PARAMS_MENDIX_CORE_STORAGESERVICE` - Storage type: + + * `localfilesystem` + * `com.mendix.storage.s3` + * `com.mendix.storage.azure` + +#### Optional + +The following variables are optional: + +* `RUNTIME_PARAMS_LICENSE_LICENSE_ID` - License ID +* `RUNTIME_PARAMS_LICENSE_LICENSE_KEY` - License key +* `MENDIX_LOG_LEVEL` - Log level, for example, `INFO`, `DEBUG`, `ERROR`, and so on + +### Health Check Endpoints + +The following endpoints are available to perform health checks on your app: + +* `/health` - General health status +* `/health/live` - Liveness probe to check if the app is running +* `/health/ready` - Readiness probe to check if the app is ready to serve traffic + +## Troubleshooting + +The following commands can help you troubleshoot your app: + +```text +# Pod not starting? +kubectl describe pod -n mendix-app + +# View logs +kubectl logs -n mendix-app + +# Check secrets are correct +kubectl get secret mendix-secret -n mendix-app -o yaml + +# Check service endpoints +kubectl get endpoints -n mendix-app + +# Check ingress +kubectl describe ingress mendix-app-ingress -n mendix-app +``` From 0eae27494328e1d5e7c80478be955fdddc63a032 Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:35:41 +0200 Subject: [PATCH 09/14] Update kubernetes-pad.md --- .../docker-deploy/kubernetes-pad.md | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index ed3f0cfb1b6..49b5dceec27 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -261,26 +261,26 @@ Configure deployment settings by performing the following steps: cpu: "500m" # Health checks - livenessProbe: - httpGet: - path: /health/live - port: 8080 - initialDelaySeconds: 60 - periodSeconds: 10 - failureThreshold: 3 - - readinessProbe: - httpGet: - path: /health/ready - port: 8080 - initialDelaySeconds: 30 - periodSeconds: 10 - failureThreshold: 3 - - volumes: - - name: mendix-storage - persistentVolumeClaim: - claimName: mendix-storage + # livenessProbe: + # httpGet: + # path: /health/live + # port: 8080 + # initialDelaySeconds: 60 + # periodSeconds: 10 + # failureThreshold: 3 + + # readinessProbe: + # httpGet: + # path: /health/ready + # port: 8080 + # initialDelaySeconds: 30 + # periodSeconds: 10 + # failureThreshold: 3 + + # volumes: + # - name: mendix-storage + # persistentVolumeClaim: + # claimName: mendix-storage ``` 2. Apply the file by running the following command: `kubectl apply -f k8s/deployment.yaml`. @@ -442,12 +442,14 @@ The following variables are optional: ### Health Check Endpoints -The following endpoints are available to perform health checks on your app: +The Mendix Runtime exposes health check endpoints that can be used to monitor the status of your app: * `/health` - General health status * `/health/live` - Liveness probe to check if the app is running * `/health/ready` - Readiness probe to check if the app is ready to serve traffic +These endpoints are especially useful when integrating with orchestration platforms such as Kubernetes, which rely on liveness and readiness probes to manage container lifecycle. + ## Troubleshooting The following commands can help you troubleshoot your app: From 62e6cd93bdb63165a4fc200c1c337af20496079b Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:37:51 +0200 Subject: [PATCH 10/14] Update kubernetes-pad.md --- content/en/docs/deployment/docker-deploy/kubernetes-pad.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index 49b5dceec27..e33fd2d8c67 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -420,7 +420,7 @@ The following is a list of available required and optional environment variables You must configure the following required variables: * `RUNTIME_PARAMS_DATABASEJDBCURL` - The URL of the database -* `RUNTIME_PARAMS_MENDIX_DATABASE_TYPE` - The type of the database (PostgreSQL, MySQL, and so on) +* `RUNTIME_PARAMS_MENDIX_DATABASE_TYPE` - The type of the database (for example, PostgreSQL or MySQL) * `RUNTIME_PARAMS_MENDIX_DATABASE_HE` - The hostname of the database server * `RUNTIME_PARAMS_MENDIX_DATABASE_PORT` - The port of the database server * `RUNTIME_PARAMS_MENDIX_DATABASE_NAME` - The name of the database @@ -438,7 +438,7 @@ The following variables are optional: * `RUNTIME_PARAMS_LICENSE_LICENSE_ID` - License ID * `RUNTIME_PARAMS_LICENSE_LICENSE_KEY` - License key -* `MENDIX_LOG_LEVEL` - Log level, for example, `INFO`, `DEBUG`, `ERROR`, and so on +* `MENDIX_LOG_LEVEL` - Log level, for example, `INFO`, `DEBUG`, or `ERROR` ### Health Check Endpoints From 6fbc143ad1bc12f15e76cd592460c6081d2517cd Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:39:38 +0200 Subject: [PATCH 11/14] Update kubernetes-pad.md From 4382e595faa4f9a8bb651fdffc3eafc4ba4f28c0 Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:48:18 +0200 Subject: [PATCH 12/14] Update kubernetes-pad.md --- .../docker-deploy/kubernetes-pad.md | 395 +++--------------- 1 file changed, 51 insertions(+), 344 deletions(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index e33fd2d8c67..0db8533f948 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -35,12 +35,10 @@ Portable App Distribution offers a more agile, user-centric, and efficient deplo Before you begin, ensure you have the following: -* Mendix Studio Pro version 10.24.19, 11.6.5, 11.19, or above +* Mendix Studio Pro version 11.19, 11.6.5, or above * A Mendix app that you want to deploy * Docker installed on your system (for building and running Docker images) * Access to a container registry (for pushing and pulling Docker images) -* Any Kubernetes cluster (for example, AKS, EKS, GKE, or on-premises) -* `Kubectl` configured and connected to your cluster ## Deploying an App with Portable App Distribution @@ -55,7 +53,8 @@ To create a Portable Package from your Mendix app, perform the following steps: 1. Open your app in Studio Pro. 2. Go to **App** > **Create Deployment Package**. 3. In the **Create Deployment Package** dialog, select **Portable package**. -4. Click **OK**. +4. Select the target runtime platform (**linux-x64** or **linux-arm64**). +5. Click **Create Package**. The Portable Package is saved to the **releases** folder of your app. @@ -65,16 +64,7 @@ For more information about Portable Packages, see [Portable App Distribution](/d To build a Docker image from the Portable Package, perform the following steps: -1. Extract the Portable Package to a directory of your choice - -```text -# Create a working directory -mkdir mendix-docker && cd mendix-docker - -# Extract the portable package (it's a zip file) -unzip /path/to/releases/YourApp.zip -d . -``` - +1. Extract the Portable Package to a directory of your choice. 2. Create a Dockerfile in the extracted directory with contents like the following. ```text @@ -118,355 +108,72 @@ To push the Docker image to a container registry, perform the following steps: ### Deploying the Docker Image -Once the Docker image is available in your container registry, you can deploy it to Kubernetes by applying the following .yaml files. The .yaml files must be organized in a folder, for example, *k8s/*. You must apply them in the same order as below. - -#### Creating a Namespace - -Create a namespace by performing the following steps: - -1. Create a file named, for example, *k8s/namespace.yaml*, with the contents like the following: - - ```yaml - apiVersion: v1 - kind: Namespace - metadata: - name: mendix-app - ``` - -2. Apply the file by running the following command: `kubectl apply -f k8s/namespace.yaml`. - - Replace the name and path of the file as required. - -#### Creating a Kubernetes Secret - -Store all sensitive values in a Kubernetes Secret by performing the following steps: - -1. Create a file named, for example, *k8s/secret.yaml*, with the contents like the following: - - ```yaml - apiVersion: v1 - kind: Secret - metadata: - name: mendix-secret - namespace: mendix-app - type: Opaque - stringData: - RUNTIME_PARAMS_DATABASEJDBCURL: "postgresql://mendix:mendix@postgres:5432/mendix" # Defines the JDBC URL to use for the database connection (which overrides the other database connection settings). - RUNTIME_PARAMS_DATABASE_TYPE: "PostgreSQL" - RUNTIME_PARAMS_DATABASE_HOST: "postgresEndpointURL" #This will be overridden if you supply DatabaseJdbcUrl. - RUNTIME_PARAMS_DATABASE_PORT: "5432" - RUNTIME_PARAMS_DATABASE_NAME: "" - RUNTIME_PARAMS_DATABASE_USERNAME: "" - RUNTIME_PARAMS_DATABASE_PASSWORD: "" - RUNTIME_PARAMS_ADMIN_PASSWORD: "" - RUNTIME_PARAMS_LICENSE_LICENSE_ID: "" - RUNTIME_PARAMS_LICENSE_LICENSE_KEY: "" - ``` - -2. Apply the file by running the following command: `kubectl apply -f k8s/secret.yaml`. - - Replace the name and path of the file as required. - - {{% alert color="info" %}} - For production environments, consider using a secrets manager like Azure Key Vault, AWS Secrets Manager, or HashiCorp Vault with a CSI driver instead of plain Kubernetes Secrets. - {{% /alert %}} - -#### Creating a Persistent Volume Claim for Storage - -Mendix requires persistent storage for uploaded files. Create a Persistent Volume Claim (PVC) by performing the following steps: - -1. Create a file named, for example, *k8s/pvc.yaml*, with the contents like the following: - - ```yaml - apiVersion: v1 - kind: PersistentVolumeClaim - metadata: - name: mendix-storage - namespace: mendix-app - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 10Gi - ``` - -2. Apply the file by running the following command: `kubectl apply -f k8s/pvc.yaml`. - - Replace the name and path of the file as required. - - {{% alert color="info" %}} - For multi-replica deployments or cloud-native setups, use S3-compatible storage instead. For more information, see [Configuring Deployment: S3 Storage](#s3-storage). - {{% /alert %}} - -#### Configuring Deployment - -Configure deployment settings by performing the following steps: - -1. Create a file named, for example, *k8s/deployment.yaml*, with the contents like the following: - - ```yaml - apiVersion: apps/v1 - kind: Deployment - metadata: - name: mendix-app - namespace: mendix-app - labels: - app: mendix-app - spec: - replicas: 1 - selector: - matchLabels: - app: mendix-app - template: - metadata: - labels: - app: mendix-app - spec: - containers: - - name: mendix-app - image: /mendix-app:1.0.0 - ports: - - name: http - containerPort: 8080 - - name: admin - containerPort: 8090 - - # Load sensitive config from Secret - envFrom: - - secretRef: - name: mendix-secret - - # Non-sensitive environment variables - env: - - name: RUNTIME_PARAMS_MENDIX_CORE_STORAGESERVICE - value: "localfilesystem" - - name: RUNTIME_PARAMS_MENDIX_STORAGE_PATH - value: "/data" - - name: RUNTIME_PARAMS_MENDIX_LOG_LEVEL - value: "INFO" - - # Mount persistent storage - volumeMounts: - - name: mendix-storage - mountPath: /data - - # Resource limits - resources: - requests: - memory: "512Mi" - cpu: "250m" - limits: - memory: "1Gi" - cpu: "500m" - - # Health checks - # livenessProbe: - # httpGet: - # path: /health/live - # port: 8080 - # initialDelaySeconds: 60 - # periodSeconds: 10 - # failureThreshold: 3 - - # readinessProbe: - # httpGet: - # path: /health/ready - # port: 8080 - # initialDelaySeconds: 30 - # periodSeconds: 10 - # failureThreshold: 3 - - # volumes: - # - name: mendix-storage - # persistentVolumeClaim: - # claimName: mendix-storage - ``` - -2. Apply the file by running the following command: `kubectl apply -f k8s/deployment.yaml`. - - Replace the name and path of the file as required. - -##### S3 Storage {#s3-storage} - -If you are using S3 instead of local storage, make the following changes to the above example file: - -* Remove the `volumeMounts` and `volumes` sections. -* Replace the `env` section with the following: - - ```yaml - env: - env: - - name: RUNTIME_PARAMS_MENDIX_CORE_STORAGESERVICE - value: "com.mendix.storage.s3" - - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ENDPOINT - value: "" - - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_BUCKETNAME - value: "" - - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_REGION - value: "" - ... - - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ACCESS_KEYID - valueFrom: - secretKeyRef: - name: mendix-secret - key: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ACCESS_KEYID - - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_SECRETACCESSKEY - valueFrom: - secretKeyRef: - name: mendix-secret - key: RUNTIME_PARAMS_MENDIX_STORAGE_S3_SECRETACCESSKEY - ``` - -#### Configuring the Service - -Configure the Service settings by performing the following steps: - -1. Create a file named, for example, *k8s/service.yaml*, with the contents like the following: - - ```yaml - apiVersion: v1 - kind: Service - metadata: - name: mendix-app-service - namespace: mendix-app - spec: - selector: - app: mendix-app - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 8080 - - name: admin - protocol: TCP - port: 8090 - targetPort: 8090 - type: ClusterIP - ``` +Once the Docker image is available in your container registry, you can deploy it to your target environment. For more information, see [Portable App Distribution for Docker: Deploying the Docker Image](/developerportal/deploy/docker-deploy-pad/#deploy). -2. Apply the file by running the following command: `kubectl apply -f k8s/service.yaml`. - - Replace the name and path of the file as required. - -#### Configuring the Ingress - -Configure the Ingress settings by performing the following steps: - -1. Create a file named, for example, *k8s/ingress.yaml*, with the contents like the following: - - ```yaml - apiVersion: networking.k8s.io/v1 - kind: Ingress - metadata: - name: mendix-app-ingress - namespace: mendix-app - annotations: - nginx.ingress.kubernetes.io/rewrite-target: / - spec: - rules: - - host: your-app.your-domain.com - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: mendix-app-service - port: - number: 80 - ``` +## Environment Variables {#env-variables} -2. Optional: To use HTTPS, add a `tls` section to the `spec` of the above example, and reference a TLS secret (for example, from **cert-manager**): +You can configure the Mendix Runtime by using environment variables. The following environment variables are supported: - ```yaml - spec: - tls: - - hosts: - - your-app.your-domain.com - secretName: mendix-tls-secret - ``` +| Environment Variable | Description | +| --- | --- | +| `MENDIX_DATABASE_URL` | The URL of the database| +| `MENDIX_DATABASE_TYPE` | The type of the database (for example, PostgreSQL, MySQL)| +| `MENDIX_DATABASE_HOST` | The host name of the database server | +| `MENDIX_DATABASE_PORT` | The port of the database server | +| `MENDIX_DATABASE_NAME` |The name of the database | -3. Apply the file by running the following command: `kubectl apply -f k8s/ingress.yaml`. +For more information, see [Runtime Customization](/refguide/custom-settings/#introduction). - Replace the name and path of the file as required. +## Configuration File {#config-file} -### Verifying the Deployment +Alternatively, you can configure the Mendix Runtime by using a configuration file. The configuration file is a JSON file that contains the same settings as the environment variables. -Verify the deployment by running the following commands: +### Example Configuration File -```text -# Check all resources in the namespace -kubectl get all -n mendix-app - -# Watch pod startup -kubectl get pods -n mendix-app -w - -# View app logs -kubectl logs -f deployment/mendix-app -n mendix-app - -# Check ingress -kubectl get ingress -n mendix-app +```json +{ + "DatabaseType": "PostgreSQL", + "DatabaseHost": "localhost:5432", + "DatabaseName": "mendix", + "DatabaseUserName": "mendix", + "DatabasePassword": "mendix", + "AdminPassword": "Admin1234!", + "RuntimePort": 8080, + "RuntimeAdminPort": 8090 +} ``` -## Reference - -### Environment Variables - -The following is a list of available required and optional environment variables. +### Using the Configuration File -#### Required +To use the configuration file, you can upload the configuration file to the configuration path: -You must configure the following required variables: +`docker run --rm -it -p 8080:8080 -e M2EE_ADMIN_PASS= /: \ -v host_path/config.conf:container_path/config.conf` + +You must also mount the volume so that Docker can find it. -* `RUNTIME_PARAMS_DATABASEJDBCURL` - The URL of the database -* `RUNTIME_PARAMS_MENDIX_DATABASE_TYPE` - The type of the database (for example, PostgreSQL or MySQL) -* `RUNTIME_PARAMS_MENDIX_DATABASE_HE` - The hostname of the database server -* `RUNTIME_PARAMS_MENDIX_DATABASE_PORT` - The port of the database server -* `RUNTIME_PARAMS_MENDIX_DATABASE_NAME` - The name of the database -* `RUNTIME_PARAMS_MENDIX_DATABASE_PASSWORD` - Database password -* `RUNTIME_PARAMS_ADMIN_PASSWORD` - The password of the Mendix admin user -* `RUNTIME_PARAMS_MENDIX_CORE_STORAGESERVICE` - Storage type: +## Logging - * `localfilesystem` - * `com.mendix.storage.s3` - * `com.mendix.storage.azure` - -#### Optional +The Mendix Runtime logs to a standard output by default. You can configure the log level using the `MX_LOG_LEVEL` environment variable. -The following variables are optional: +The following log levels are supported (in order of verbosity): -* `RUNTIME_PARAMS_LICENSE_LICENSE_ID` - License ID -* `RUNTIME_PARAMS_LICENSE_LICENSE_KEY` - License key -* `MENDIX_LOG_LEVEL` - Log level, for example, `INFO`, `DEBUG`, or `ERROR` +| Log Level | Description | +| --------- | ----------- | +| `TRACE` | Most verbose — logs all internal operations | +| `DEBUG` | Detailed diagnostic information | +| `INFO` | General operational messages (default) | +| `WARNING` | Potentially harmful situations | +| `ERROR` | Error events that may still allow the app to continue | +| `CRITICAL` | Severe errors that may cause the app to stop | -### Health Check Endpoints +## Health Checks The Mendix Runtime exposes health check endpoints that can be used to monitor the status of your app: -* `/health` - General health status -* `/health/live` - Liveness probe to check if the app is running -* `/health/ready` - Readiness probe to check if the app is ready to serve traffic +| EndPoint | Description | +| -------- | ----------- | +| `/health` | Returns the overall health status of the app | +| `/health/live` | Returns the liveness status — indicates if the app is running | +| `/health/ready` | Returns the readiness status — indicates if the app is ready to serve traffic | These endpoints are especially useful when integrating with orchestration platforms such as Kubernetes, which rely on liveness and readiness probes to manage container lifecycle. - -## Troubleshooting - -The following commands can help you troubleshoot your app: - -```text -# Pod not starting? -kubectl describe pod -n mendix-app - -# View logs -kubectl logs -n mendix-app - -# Check secrets are correct -kubectl get secret mendix-secret -n mendix-app -o yaml - -# Check service endpoints -kubectl get endpoints -n mendix-app - -# Check ingress -kubectl describe ingress mendix-app-ingress -n mendix-app -``` From 08ad3133c6947dba4b1a31e64f22fa49cd6929e4 Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:49:37 +0200 Subject: [PATCH 13/14] Update kubernetes-pad.md --- content/en/docs/deployment/docker-deploy/kubernetes-pad.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index 0db8533f948..14e1fbdbfad 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -145,11 +145,9 @@ Alternatively, you can configure the Mendix Runtime by using a configuration fil ### Using the Configuration File -To use the configuration file, you can upload the configuration file to the configuration path: +To use the configuration file, set the `MENDIX_CONFIG_FILE` environment variable to the path of the configuration file: -`docker run --rm -it -p 8080:8080 -e M2EE_ADMIN_PASS= /: \ -v host_path/config.conf:container_path/config.conf` - -You must also mount the volume so that Docker can find it. +`export MENDIX_CONFIG_FILE=/path/to/config.json` ## Logging From f58a8031a6220fb497fe9c9def042effec7d68fb Mon Sep 17 00:00:00 2001 From: katarzyna-koltun-mx <108737161+katarzyna-koltun-mx@users.noreply.github.com> Date: Thu, 4 Jun 2026 17:00:12 +0200 Subject: [PATCH 14/14] Update kubernetes-pad.md --- .../docker-deploy/kubernetes-pad.md | 442 ++++++++++++++---- 1 file changed, 345 insertions(+), 97 deletions(-) diff --git a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md index 14e1fbdbfad..d9167f4c4ab 100644 --- a/content/en/docs/deployment/docker-deploy/kubernetes-pad.md +++ b/content/en/docs/deployment/docker-deploy/kubernetes-pad.md @@ -35,67 +35,24 @@ Portable App Distribution offers a more agile, user-centric, and efficient deplo Before you begin, ensure you have the following: -* Mendix Studio Pro version 11.19, 11.6.5, or above -* A Mendix app that you want to deploy -* Docker installed on your system (for building and running Docker images) -* Access to a container registry (for pushing and pulling Docker images) +* A Portable Package [created from your Mendix app](/developerportal/deploy/portable-app-distribution-deploy/#creating-a-portable-app-distribution-file) +* Docker installed on your system +* Access to a container registry +* Kubernetes cluster (if deploying to Kubernetes) +* `kubectl` configured to connect to your Kubernetes cluster ## Deploying an App with Portable App Distribution The Portable App Distribution feature in Mendix Studio Pro provides you with the necessary application files to build a Docker image. It packages your Mendix application as a self-contained distribution, ready for integration into your Docker environment. -To deploy your app to Docker, you must create a Portable App Distribution Package, build a Docker image, and then deploy the Docker image (including pushing it to a container registry). For more information, refer to the sections below. +To deploy your app to Docker, you must [create a Portable App Distribution Package](/developerportal/deploy/portable-app-distribution-deploy/#creating-a-portable-app-distribution-file), build a Docker image, and then deploy the Docker image (including pushing it to a container registry). For more information, refer to the sections below. -### Creating a Portable App Distribution Package - -To create a Portable Package from your Mendix app, perform the following steps: - -1. Open your app in Studio Pro. -2. Go to **App** > **Create Deployment Package**. -3. In the **Create Deployment Package** dialog, select **Portable package**. -4. Select the target runtime platform (**linux-x64** or **linux-arm64**). -5. Click **Create Package**. - -The Portable Package is saved to the **releases** folder of your app. - -For more information about Portable Packages, see [Portable App Distribution](/developerportal/deploy/portable-app-distribution-deploy/). Files included in the Portable Package are the core of your Mendix application and are ready to be included in a Docker image. - ### Building a Docker Image To build a Docker image from the Portable Package, perform the following steps: 1. Extract the Portable Package to a directory of your choice. -2. Create a Dockerfile in the extracted directory with contents like the following. - - ```text - # This file provides an example on how to start the runtime in Docker. - # It is based on the configuration named Default. - - FROM eclipse-temurin:21-jdk - - # Set working directory - WORKDIR /mendix - - # Copy Mendix app files into the image - COPY ./app ./app - COPY ./bin ./bin - COPY ./etc ./etc - COPY ./lib ./lib - - # Environment variables (optional) - ENV MX_LOG_LEVEL=info - ENV M2EE_ADMIN_PASS=${M2EE_ADMIN_PASS} - - # Expose ports - EXPOSE 8090 - EXPOSE 8080 - - # Start command - CMD ["./bin/start", "etc/Default"] - ``` - - You must create this Dockerfile yourself and place it alongside the application files generated by the Portable App Distribution. The `COPY` commands in the example above assume that the `app`, `bin`, `etc`, and `lib` directories are in the same location as your Dockerfile. - +2. Create a Dockerfile in the extracted directory. For more information, see [Building a Docker Image](/developerportal/deploy/docker-deploy-pad/#building-a-docker-image). 3. Build the Docker image by using the following command: `docker build -t : .`, where `` and `` indicate your required image name and version tag (for example, `my-mendix-app:1.0.0`). ### Pushing the Docker Image @@ -108,70 +65,361 @@ To push the Docker image to a container registry, perform the following steps: ### Deploying the Docker Image -Once the Docker image is available in your container registry, you can deploy it to your target environment. For more information, see [Portable App Distribution for Docker: Deploying the Docker Image](/developerportal/deploy/docker-deploy-pad/#deploy). +Once the Docker image is available in your container registry, you can deploy it to Kubernetes by applying the following .yaml files. The .yaml files must be organized in a folder, for example, *k8s/*. You must apply them in the same order as below. -## Environment Variables {#env-variables} +#### Creating a Namespace -You can configure the Mendix Runtime by using environment variables. The following environment variables are supported: +Create a namespace by performing the following steps: -| Environment Variable | Description | -| --- | --- | -| `MENDIX_DATABASE_URL` | The URL of the database| -| `MENDIX_DATABASE_TYPE` | The type of the database (for example, PostgreSQL, MySQL)| -| `MENDIX_DATABASE_HOST` | The host name of the database server | -| `MENDIX_DATABASE_PORT` | The port of the database server | -| `MENDIX_DATABASE_NAME` |The name of the database | +1. Create a file named, for example, *namespace.yaml*, with contents like the following: -For more information, see [Runtime Customization](/refguide/custom-settings/#introduction). + ```yaml + apiVersion: v1 + kind: Namespace + metadata: + name: mendix-app + ``` -## Configuration File {#config-file} +2. Apply the file by running the following command: `kubectl apply -f namespace.yaml`. + + Replace the name and path of the file as required. + +#### Creating a Kubernetes Secret + +Store all sensitive values in a Kubernetes Secret by performing the following steps: + +1. Create a file named, for example, *secret.yaml*, with the contents like the following: + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: mendix-secret + namespace: mendix-app + type: Opaque + stringData: + RUNTIME_PARAMS_DATABASEJDBCURL: "postgresql://mendix:mendix@postgres:5432/mendix" # Defines the JDBC URL to use for the database connection (which overrides the other database connection settings). + RUNTIME_PARAMS_DATABASE_TYPE: "PostgreSQL" + RUNTIME_PARAMS_DATABASE_HOST: "postgresEndpointURL" #This will be overridden if you supply DatabaseJdbcUrl. + RUNTIME_PARAMS_DATABASE_PORT: "5432" + RUNTIME_PARAMS_DATABASE_NAME: "" + RUNTIME_PARAMS_DATABASE_USERNAME: "" + RUNTIME_PARAMS_DATABASE_PASSWORD: "" + RUNTIME_PARAMS_ADMIN_PASSWORD: "" + RUNTIME_PARAMS_LICENSE_LICENSE_ID: "" + RUNTIME_PARAMS_LICENSE_LICENSE_KEY: "" + ``` + +2. Apply the file by running the following command: `kubectl apply -f secret.yaml`. + + Replace the name and path of the file as required. + +#### Using a ConfigMap + +The previous section showed how to load secrets as environment variables. For other properties that need to be changed and are not defined in a secret, you can pass constants and variables using a ConfigMap by mounting them as files (similar to mounting files in Docker) and by passing them directly as environment variables. + +The following is a sample command to create a ConfigMap: `kubectl create configmap my-config --from-file=default.conf --from-file=custom.conf --from-file=variables.conf -n mendix-app`. + +Configuration values such as the admin user password, license key, and custom runtime settings are provided in the *custom.conf* and *variables.conf* files. These files must be included in the [Configuration File](/developerportal/deploy/portable-app-distribution-deploy/best-practices/). + +#### Configuring Deployment + +Create a Kubernetes Deployment for your Mendix app by performing the following steps: + +1. Create a file named, for example, *deployment.yaml*, with the contents like the following: + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: mendix-app + namespace: mendix-app + spec: + replicas: 1 + selector: + matchLabels: + app: mendix-app + template: + metadata: + labels: + app: mendix-app + spec: + containers: + - name: mendix-app + image: /: + ports: + - containerPort: 8080 + - containerPort: 8090 + envFrom: + - secretRef: + name: mendix-secret + resources: + requests: + memory: "512Mi" + cpu: "250m" + limits: + memory: "1Gi" + cpu: "500m" + # Use this if you have health checks enabled. + # livenessProbe: + # httpGet: + # path: /health/live + # port: 8080 + # initialDelaySeconds: 60 + # periodSeconds: 10 + #readinessProbe: + # httpGet: + # path: /health/ready + # port: 8080 + # initialDelaySeconds: 30 + # periodSeconds: 10 + + # If passing a ConfigMap + # volumeMounts: + # - name: config-volume + # mountPath: /opt/app/etc/ + # readOnly: true + # volumes: + # - name: config-volume + # configMap: + # name: my-config + ``` + +2. Apply the file by running the following command: `kubectl apply -f deployment.yaml`. + + Replace the name and path of the file as required. + +#### Configuring the Service + +Create a Kubernetes Service to expose your Mendix app by performing the following steps: + +1. Create a file named, for example, *service.yaml*, with the contents like the following: + + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: mendix-app-service + namespace: mendix-app + spec: + selector: + app: mendix-app + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 8080 + - name: admin + protocol: TCP + port: 8090 + targetPort: 8090 + type: ClusterIP + ``` + +2. Apply the file by running the following command: `kubectl apply -f service.yaml`. + + Replace the name and path of the file as required. + +#### Configuring the Ingress + +Create a Kubernetes Ingress to expose your Mendix app to the outside world by performing the following steps: + +1. Create a file named, for example, *ingress.yaml*, with the contents like the following: + + ```yaml + apiVersion: networking.k8s.io/v1 + kind: Ingress + metadata: + name: mendix-app-ingress + namespace: mendix-app + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + spec: + rules: + - host: + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: mendix-app-service + port: + number: 80 + ``` -Alternatively, you can configure the Mendix Runtime by using a configuration file. The configuration file is a JSON file that contains the same settings as the environment variables. +2. Apply the file by running the following command: `kubectl apply -f ingress.yaml`. -### Example Configuration File + Replace the name and path of the file as required. -```json -{ - "DatabaseType": "PostgreSQL", - "DatabaseHost": "localhost:5432", - "DatabaseName": "mendix", - "DatabaseUserName": "mendix", - "DatabasePassword": "mendix", - "AdminPassword": "Admin1234!", - "RuntimePort": 8080, - "RuntimeAdminPort": 8090 -} +### Configuring Storage + +The following sections explain how to configure storage for your Mendix app on Kubernetes. + +#### Local Storage + +By default, the Mendix Runtime uses local storage. However, in a Kubernetes environment, local storage is not persistent. To use persistent storage, you can use a Persistent Volume Claim (PVC). + +1. Create a file named, for example, *k8s/pvc.yaml*, with the contents like the following: + + ```yaml + apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: mendix-storage + namespace: mendix-app + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + ``` + +2. Apply the file by running the following command: `kubectl apply -f k8s/pvc.yaml`. + + Replace the name and path of the file as required. + +3. Update the Deployment to mount the PVC: + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: mendix-app + namespace: mendix-app + spec: + replicas: 1 + selector: + matchLabels: + app: mendix-app + template: + metadata: + labels: + app: mendix-app + spec: + containers: + - name: mendix-app + image: /: + ports: + - containerPort: 8080 + - containerPort: 8090 + envFrom: + - secretRef: + name: mendix-secret + env: + - name: MENDIX_STORAGE_TYPE + value: "local" + - name: MENDIX_STORAGE_PATH + value: "/data" + volumeMounts: + - name: mendix-storage + mountPath: /data + resources: + requests: + memory: "512Mi" + cpu: "250m" + limits: + memory: "1Gi" + cpu: "500m" + livenessProbe: + httpGet: + path: /health/live + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 10 + volumes: + - name: mendix-storage + persistentVolumeClaim: + claimName: mendix-storage + ``` + +#### S3 Storage + +To use S3-compatible storage, set the following environment variables: + +```text +env: + - name: RUNTIME_PARAMS_MENDIX_CORE_STORAGESERVICE + value: "com.mendix.storage.s3" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ENDPOINT + value: "" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_BUCKETNAME + value: "" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_REGION + value: "" + ... + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ACCESS_KEYID + valueFrom: + secretKeyRef: + name: mendix-secret + key: RUNTIME_PARAMS_MENDIX_STORAGE_S3_ACCESS_KEYID + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_SECRETACCESSKEY + valueFrom: + secretKeyRef: + name: mendix-secret + key: RUNTIME_PARAMS_MENDIX_STORAGE_S3_SECRETACCESSKEY ``` -### Using the Configuration File +#### Azure Blob Storage + +To use Azure BlobStorage, set the following environment variables: + +```text +env: + - name: RUNTIME_PARAMS_MENDIX_CORE_STORAGESERVICE + value: "com.mendix.storage.azure" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_AZURE_BLOBENDPOINT + value: "" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_AZURE_CONTAINER + value: "" + - name: RUNTIME_PARAMS_MENDIX_STORAGE_S3_REGION + value: "" + ... + - name: RUNTIME_PARAMS_MENDIX_STORAGE_AZURE_ACCOUNT + valueFrom: + secretKeyRef: + name: mendix-secret + key: RUNTIME_PARAMS_MENDIX_STORAGE_AZURE_ACCOUNT + - name: RUNTIME_PARAMS_MENDIX_STORAGE_AZURE_ACCOUNTKEY + valueFrom: + secretKeyRef: + name: mendix-secret + key: RUNTIME_PARAMS_MENDIX_STORAGE_AZURE_ACCOUNTKEY +``` -To use the configuration file, set the `MENDIX_CONFIG_FILE` environment variable to the path of the configuration file: +## Troubleshooting -`export MENDIX_CONFIG_FILE=/path/to/config.json` +If you encounter issues, use the following troubleshooting tips to help you solve them. -## Logging +### App Does Not Start -The Mendix Runtime logs to a standard output by default. You can configure the log level using the `MX_LOG_LEVEL` environment variable. +If the app does not start, check the logs of the pod: -The following log levels are supported (in order of verbosity): +```text +kubectl logs -n mendix-app +``` -| Log Level | Description | -| --------- | ----------- | -| `TRACE` | Most verbose — logs all internal operations | -| `DEBUG` | Detailed diagnostic information | -| `INFO` | General operational messages (default) | -| `WARNING` | Potentially harmful situations | -| `ERROR` | Error events that may still allow the app to continue | -| `CRITICAL` | Severe errors that may cause the app to stop | +### App Is Not Accessible -## Health Checks +If the app is not accessible, check the status of the pod, service, and ingress: -The Mendix Runtime exposes health check endpoints that can be used to monitor the status of your app: +```text +kubectl get pods -n mendix-app +kubectl get services -n mendix-app +kubectl get ingress -n mendix-app +``` + +### Database Connection Issues -| EndPoint | Description | -| -------- | ----------- | -| `/health` | Returns the overall health status of the app | -| `/health/live` | Returns the liveness status — indicates if the app is running | -| `/health/ready` | Returns the readiness status — indicates if the app is ready to serve traffic | +If the app cannot connect to the database, check the database credentials in the secret: -These endpoints are especially useful when integrating with orchestration platforms such as Kubernetes, which rely on liveness and readiness probes to manage container lifecycle. +```text +kubectl get secret mendix-secret -n mendix-app -o yaml +```