This guide explains the complete architecture and configuration of the advanced MDriven Docker Compose setup. Unlike a manual build process, this configuration leverages official pre-built MDriven images from Docker Hub, bundled together with a MySQL database, an Nginx reverse proxy, and a built-in web-based Code Server (SCM) for managing your files.
Start by installing Docker Desktop. Docker Desktop provides the environment and tools required for managing and running containers on your local machine.
1. Folder Structure
To ensure all the bindings in the compose file work correctly, your project root must contain the following file and folder structure. These files handle credentials, initialization scripts, and application overrides.
\---Apps (Project Root)
| compose.yaml - [The main orchestration file]
\---databases
\---mysql
| mysql.env - [Environment variables/passwords for MySQL]
\---init - [Folder for .sql schema initialization scripts]
\---settings
| nginx-proxy.conf - [Nginx routing configuration]
\---mdriven-server
| CommandLineOverride.xml - [Server startup overrides]
| DatabaseVistaDB.vdb6 - [Admin database for the Server]
| PwdReset.txt - [Optional: Create to reset User 'a' password]
\---mdriven-turnkey
| CommandLineOverride.xml - [Turnkey startup overrides]
| HardServerUrl.xml - [Specifies the Turnkey URL]
| MDrivenServerOverride.xml - [Settings for Turnkey to connect to Server]
| TurnkeySettingsOverride.xml - [Additional Turnkey overrides]
\---vscode - [Optional: Stricter permissions/settings for SCM]
Important Configuration Files Explained
To understand exactly what settings and variables go into these XML files, please refer to their dedicated documentation pages:
- CommandLineOverride.xml: Used by both the MDriven Server and Turnkey to inject startup arguments (for example, defining a subdirectory path like pathtoapp=/__MDrivenServer, specifying host name and port).
- HardServerUrl.xml: Specifies the exact URL (and port) that will be used to access the Turnkey application externally.
- MDrivenServerOverride.xml: Configures how the Turnkey application connects to the MDriven Server. It holds the internal routing URL (e.g., http://server-core:5010) and the credentials for User 'a'.
- TurnkeySettingsOverride.xml: Used for overriding Turnkey behaviour and enabling or disabling Turnkey Features.
2. Understanding the Services
The compose file orchestrates five distinct services working together seamlessly:
mysql: Runs MySQL 8.0. It maps a local./mysql-datafolder for data persistence and uses aninitfolder to run initialization scripts. It includes a strict health check to ensure the database is fully responsive before dependent services start.server-core: The core MDriven Server running theubuntu-amd64image. It mounts your configurations and the VistaDB admin file directly into the container. It runs as a limited user (PUID=1000) for security and relies on the MySQL service being healthy before starting.turnkey-core: The MDriven Turnkey application. It mounts its specific XML overrides and connects to the MDriven Server. Like the server, it runs with limited privileges and includes a robust health check.scm(Code Server): A very powerful addition. This runs a web-based version of Visual Studio Code (lscr.io/linuxserver/code-server). By mapping theMDSDataandMDTDatavolumes into its workspace, it allows developers to edit server and turnkey files, as well as easily view application logs directly from their browser on port8080!nginx: An Alpine-based Nginx proxy. It acts as the gatekeeper, relying on a customnginx-proxy.conffile to route traffic efficiently. It exposes ports5011,5012, and8080.
3. The Complete Docker Compose File
Here is the complete compose.yaml configuration. Place this in the root of your project directory.
name: MDriven
services:
mysql: # MDriven Server Connection String --- Server=mysql;port=3306;Database=mdriven_db;Uid=mdriven;Pwd=123456;
image: mysql:8.0
restart: on-failure:5
env_file:
- ${PROJECT_ROOT:-.}/databases/mysql/mysql.env
volumes:
- ./mysql-data:/var/lib/mysql
- ${PROJECT_ROOT:-.}/databases/mysql/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u root -p $MYSQL_ROOT_PASSWORD || exit 1"]
interval: 10s
timeout: 20s
retries: 5
start_period: 30s
server-core:
platform: linux/amd64
image: mdriven/mdriven-server:ubuntu-amd64
volumes:
- type: volume
source: MDSData
target: /app
## Uncomment to reset User 'a' password
# - type: bind
# source: ${PROJECT_ROOT:-.}/settings/mdriven-server/PwdReset.txt
# target: /pwdreset/PwdReset.txt
- type: bind
source: ${PROJECT_ROOT:-.}/settings/mdriven-server/CommandLineOverride.xml
target: /app/App_Data/CommandLineOverride.xml
- type: bind
source: ${PROJECT_ROOT:-.}/settings/mdriven-server/DatabaseVistaDB.vdb6
target: /app/App_Data/DatabaseVistaDB.vdb6
depends_on:
mysql:
condition: service_healthy
restart: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5011/"]
interval: 10s
timeout: 10s
retries: 5
start_period: 30s
environment:
- PUID=1000
- PGID=1000
# - UPDATE_APP=true # set true for latest version or yyyymmdd for specific version
restart: on-failure:5
entrypoint: ["/bin/sh","/usr/local/bin/entrypoint.sh"]
command: ["dotnet", "AppCompleteGenericCore.dll"]
turnkey-core:
platform: linux/amd64
image: mdriven/mdriven-turnkey:ubuntu-amd64
volumes:
- type: volume
source: MDTData
target: /app
- type: bind
source: ${PROJECT_ROOT:-.}/settings/mdriven-turnkey/CommandLineOverride.xml
target: /app/App_Data/CommandLineOverride.xml
- type: bind
source: ${PROJECT_ROOT:-.}/settings/mdriven-turnkey/HardServerUrl.xml
target: /app/App_Data/HardServerUrl.xml
- type: bind
source: ${PROJECT_ROOT:-.}/settings/mdriven-turnkey/MDrivenServerOverride.xml
target: /app/App_Data/MDrivenServerOverride.xml
- type: bind
source: ${PROJECT_ROOT:-.}/settings/mdriven-turnkey/TurnkeySettingsOverride.xml
target: /app/App_Data/TurnkeySettingsOverride.xml
depends_on:
server-core:
condition: service_healthy
restart: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5012/"]
interval: 10s
timeout: 10s
retries: 5
start_period: 30s
environment:
- PUID=1000
- PGID=1000
# - UPDATE_APP=true # set true for latest version or yyyymmdd for specific version
restart: on-failure:5
entrypoint: ["/bin/sh","/usr/local/bin/entrypoint.sh"]
command: ["dotnet", "StreaminAppCoreWebApp.dll"]
scm:
image: lscr.io/linuxserver/code-server:4.109.2-ls317
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- PASSWORD=123456
- DEFAULT_WORKSPACE=/config/workspace
- PWA_APPNAME=mdriven-server
- PORT=8080
volumes:
- type: volume
source: MDSData
target: /config/workspace/MDrivenServer
read_only: false
- type: volume
source: MDTData
target: /config/workspace/MDrivenTurnkey
read_only: false
## Uncomment for stricter file manager and terminal permissions
# - type: bind
# source: ${PROJECT_ROOT:-.}/settings/vscode/.config
# target: /config/.config
# read_only: true
# - type: bind
# source: ${PROJECT_ROOT:-.}/settings/vscode/data/User/settings.json
# target: /config/data/User/settings.json
# read_only: true
# - type: bind
# source: ${PROJECT_ROOT:-.}/settings/vscode/extensions/extensions.json
# target: /config/extensions/extensions.json
# read_only: true
nginx:
image: nginx:alpine
volumes:
- type: bind
source: ${PROJECT_ROOT:-.}/settings/nginx-proxy.conf
target: /etc/nginx/conf.d/default.conf
depends_on:
scm:
condition: service_started
turnkey-core:
condition: service_healthy
restart: true
ports:
- 5011:5011
- 5012:5012
- 8080:8080
volumes:
MDSData:
MDTData:4. Key Advanced Features
Dependency Chains & Health Checks
The depends_on clauses in this file use condition: service_healthy. This is a crucial safety measure. It ensures that Turnkey won't even attempt to boot until the MDriven Server responds successfully to a curl request, and the Server won't boot until MySQL successfully executes a ping command.
Dynamic Paths
The file heavily utilizes the ${PROJECT_ROOT:-.} variable. This ensures that the mounts will correctly map to the current directory (.)
Configuration Settings
You can easily customize your production setupâsuch as updating the app versions, lowering container permissions, or resetting the administrator passwordâby adjusting environment variables and bindings within your compose.yaml file.
Please refer to the Docker Compose Configuration Settings section on the Docker Overview Page for detailed instructions on using UPDATE_APP, PUID/PGID, and the PwdReset.txt file.
5. How To Run The Setup
Once your file structure is correctly populated, simply open your terminal, navigate to your /Apps folder, and run:
docker compose up -dBecause of the robust dependency chaining, you can expect the containers to start in strict order: MySQL -> Server -> Turnkey/SCM -> Nginx.
- To manage files and view app logs: Navigate to
http://localhost:8080(password:123456) to access the web-based VS Code environment, where you can browse application files and review live logs in the integrated terminal/workspace.
6. Behind the Scenes: The Dockerfiles
For users looking to deeply customize their containers, here is a look at the actual source Dockerfiles used to generate the official MDriven images referenced in the compose.yaml above.
MDriven Server Dockerfile
This file uses an Ubuntu Noble base image and fetches the latest version of the Server Core dynamically via the MDriven Release API.
# syntax=docker/dockerfile:1
FROM [mcr.microsoft.com/dotnet/sdk:8.0-noble-amd64](https://mcr.microsoft.com/dotnet/sdk:8.0-noble-amd64)
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
curl \
unzip \
jq \
&& rm -rf /var/lib/apt/lists/* WORKDIR /app
RUN mkdir -p /app_temp
RUN API_ENDPOINT="[https://mdriven.net/Rest/ProductRelease/Get?vProduct=ServerCore&platform=linux](https://mdriven.net/Rest/ProductRelease/Get?vProduct=ServerCore&platform=linux)" \
&& DOWNLOAD_URL=$(curl -sL "$API_ENDPOINT" | jq -r '.Releases[0]') \
&& curl -L -o release.zip "$DOWNLOAD_URL" \
&& unzip release.zip -d /app_temp \
&& rm release.zip
RUN dotnet nuget add source /mnt/c/capableobjectswush/Xternal/VistaDB --name XternatVistaDB
COPY ./entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.shMDriven Turnkey Dockerfile
This file is similar but importantly includes locale generation which is required for correct Turnkey date and language formatting.
# syntax=docker/dockerfile:1
FROM [mcr.microsoft.com/dotnet/sdk:8.0-noble-amd64](https://mcr.microsoft.com/dotnet/sdk:8.0-noble-amd64)
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
curl \
unzip \
jq \
locales \
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \
&& dpkg-reconfigure --frontend=noninteractive locales \
&& rm -rf /var/lib/apt/lists/* ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
WORKDIR /app
RUN mkdir -p /app_temp
RUN API_ENDPOINT="[https://mdriven.net/Rest/ProductRelease/Get?vProduct=TurnkeyCore&platform=linux](https://mdriven.net/Rest/ProductRelease/Get?vProduct=TurnkeyCore&platform=linux)" \
&& DOWNLOAD_URL=$(curl -sL "$API_ENDPOINT" | jq -r '.Releases[0]') \
&& curl -L -o release.zip "$DOWNLOAD_URL" \
&& unzip release.zip -d /app_temp \
&& rm release.zip
COPY ./entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
Theentrypoint.sh vs Standard Entry Points
You might notice that the standard entry points for MDriven applications are:
- Server:
dotnet AppCompleteGenericCore.dll - Turnkey:
dotnet StreaminAppCoreWebApp.dll
However, the official MDriven setups utilize a custom script (COPY ./entrypoint.sh /usr/local/bin/) before launching those .dll files.
This entrypoint.sh file adds essential advanced features, including:
- Password Resets: The ability to dynamically reset User 'a's password via the mounted
PwdReset.txtfile. - Version Control: Mechanisms for upgrading or downgrading MDriven Turnkey and Server using the
UPDATE_APPenvironment variable. - Security: Lowering application privileges using
PUIDandPGIDto prevent the apps from running asroot.
Recommendation: If you want these robust features, we highly recommend utilizing the standard Docker Compose setups provided by MDriven rather than writing custom .dll entry points from scratch!
