Installation
The FrontEnd Server runs as an ASP.NET Core 8 application, deployed as a Docker container built on top of a customer base image plus an overlay of customisation DLLs. A separate React shell container serves the SPA; both halves are wired together through the shell's runtime config which points at the BFF's HTTP root.
This document is the reference install guide for the FrontEnd Server. For an end-to-end "Hello World" walkthrough (database + auth server + Data API + FrontEnd Server + React shell), see Get Started with Mib v5.0 (Docker) or Get Started with Mib v5.0 (Podman).
For maintaining an existing IIS / .NET Framework install, see Legacy MVC — IIS Installation. New deployments must not start there.
Related docs.
System Overview — backend overlay system explains the 4-layer image stack (base image → NuGet deps → MibServer3 own DLLs → customer customisations) that backs every production deploy.
Local Development covers running the FrontEnd Server locally for component development.
What the FrontEnd Server is
A .NET 8 ASP.NET Core application that:
- Aggregates pages from the Data API and microservices (
Permission,EditHistory,Concurrency,FileManagement) and emits a single{schema, data}response per page render (GET /api/v2/display/<pageKey>/<id>). - Hosts every C# customisation as compiled DLLs overlaid into
/app/. See Backend overlay system. - Exposes the OAuth callback (
/oauth/callback) and writes the encrypted.AspNetCore.Cookiessession cookie used by the React shell. - Hosts the legacy MVC
/Display/<pageKey>route for backwards compatibility with server-rendered components — new deployments rarely touch this.
It does not serve the React shell. The shell is a separate Docker
container (built from MibFrontEnd/apps/cms) that serves static assets
via nginx and points at the FrontEnd Server's HTTP root.
Prerequisites
A working FrontEnd Server depends on several other services being reachable:
| Service | Why the FrontEnd Server needs it |
|---|---|
| Database (SQL Server / Azure SQL) | FrontEnd DB — page templates, menu, user preferences. Tables prefixed MIB3UX_*, PAGE_*, MENU_*. |
| MibAuthorizationServer | OAuth issuer. Validates session cookies and refreshes tokens. |
| MibServerApi (Data API) | Source of mediatype metadata + item data. |
| Permission Microservice | Per-user/group permission lookup. Required at startup; the FrontEnd Server's readiness probe fails until the first permission-metadata fetch succeeds. |
| EditHistory Microservice (optional) | Required only if UseEditHistoryMicroService=true. Provides the audit panel data. |
| Concurrency Microservice (optional) | Required only if UserConcurrencyServiceUrl is set. Drives the "who else is editing this" UI. |
| FileManagement Microservice (optional) | Required for TSV export and any media-file integration. |
| React shell container | Serves the SPA the operators use. Without it, the FrontEnd Server still works as an API, but no UI is reachable. |
For a graphical view of how these fit together, see System Overview — what the CMS actually is.
Deployment models
Two supported deployment models. The first is the modern path; the second exists for legacy customers still running on Windows IIS.
1. Docker (modern)
The FrontEnd Server ships as an OCI image built on the
mcr.microsoft.com/dotnet/aspnet:8.0 base. Customers typically take
that image, layer their customisation DLLs on top, and publish the
result as a "customer base image":
# Customer base image — built once per release
FROM <agile-registry>/mib/frontend:<version>
COPY my-customisation/bin/Release/net8.0/*.dll /app/
COPY my-customisation/config/ /app/config/
Engineering deploys then add a thin overlay on top of the customer base image with only the DLLs that changed since the last release. See Backend overlay system for the full layering model.
Minimal docker-compose.yml
version: '3.8'
services:
mib-frontend:
image: <agile-registry>/mib/frontend:<version>
restart: unless-stopped
ports:
- "8080:8080"
environment:
# Where the FrontEnd Server itself lives (used for OAuth callbacks etc.)
MIBCMSFRONTENDSERVERBASECONFIG_DEFAULT_ROOTURL: "https://cms.example.com/"
MIBCMSFRONTENDSERVERBASECONFIG_DEFAULT_FRONTENDAPPPATH: "/app"
# OAuth client (matches the API_CLIENTS row in MibAuthorization)
MIBAUTHORIZATIONCLIENTCONFIG_DEFAULT_SERVERURL: "https://auth.example.com/"
MIBAUTHORIZATIONCLIENTCONFIG_DEFAULT_CLIENTID: "mibFrontEndClient"
MIBAUTHORIZATIONCLIENTCONFIG_DEFAULT_CLIENTSECRET: "${MIB_FRONTEND_CLIENT_SECRET}"
# Data API
MIBAPICLIENTCONFIG_DEFAULT_URL: "https://api.example.com/"
# Permission Microservice (required)
MIBPERMISSIONMICROSERVICECLIENTCONFIG_DEFAULT_SERVERURL: "http://permission-ms"
# Optional microservices
MIBCMSFRONTENDSERVERBASECONFIG_DEFAULT_USEEDITHISTORYMICROSERVICE: "true"
MIBEDITHISTORYMICROSERVICECLIENTCONFIG_DEFAULT_APIURL: "http://edithistory-ms"
MIBCMSFRONTENDSERVERBASECONFIG_DEFAULT_USERCONCURRENCYSERVICEURL: "http://concurrency-ms"
MIBFILEMANAGEMENTMICROSERVICECLIENTCONFIG_DEFAULT_URLMICROSERVICE: "http://filemanagement-ms"
# FrontEnd DB
# NOTE: `sql2005` is the framework's identifier for the SQL Server
# driver family — it's the correct, modern value for any SQL Server
# version (2008, 2012, 2016, 2019, 2022, Azure SQL). The label is
# historical; don't change it based on your actual server version.
MIBDATABASECONFIG_DEFAULT_TYPE: "sql2005"
MIBDATABASECONFIG_DEFAULT_SERVER: "db.example.com"
MIBDATABASECONFIG_DEFAULT_DATABASE: "mibfrontend"
MIBDATABASECONFIG_DEFAULT_USERNAME: "mibfrontend_user"
MIBDATABASECONFIG_DEFAULT_PASSWORD: "${DB_PASSWORD}"
# Cache (Couchbase / Memcached / app-memory)
MIBCACHECONFIG_DEFAULT_APP: "true"
mib-shell:
image: ghcr.io/agilecontent/mib-frontend:<version>
restart: unless-stopped
ports:
- "4000:4000"
environment:
# The shell's runtime config: where the BFF lives, what federated remotes to load
VITE_API_URL: "https://cms.example.com/"
VITE_CUSTOM_COMPONENTS_URL: "https://customer-remote.example.com/assets/remoteEntry.js"
VITE_CUSTOM_COMPONENTS_2_URL: ""
VITE_CUSTOM_COMPONENTS_3_URL: ""
The React shell at mib-shell is mandatory for an end-user-facing
deployment. It can be hosted on the same domain as the BFF behind a
reverse proxy (recommended — avoids CORS) or on a separate domain
(requires CORS configuration; see
CorsOrigins below).
Database migrations
Same as the legacy install — see Database migrations
below. The same mibmigrator CLI runs against the same migration
assemblies; only the place where you run it differs (typically a
one-off Kubernetes Job or a CI step rather than a Windows CLI).
2. IIS on Windows (legacy)
Older customers still run the FrontEnd Server inside IIS on Windows
Server. The deploy uses the same DLLs, the same mibconfig files, and
the same OAuth client setup — only the host changes.
See Legacy IIS installation at the bottom of this page.
Database migrations
The FrontEnd DB is bootstrapped with mibmigrator. See
Framework — MibMigrator tool for
the CLI details.
Two migration assemblies, run in order against the FrontEnd DB section:
mibmigrator \
-assembly=MediaiBox.Core.Database.Migrations.dll \
-configPath=./config -section=front
mibmigrator \
-assembly=MediaiBox.Cms.FrontEnd.Database.Migrations.dll \
-configPath=./config -section=front
In containerised deploys the migrations typically run as a one-off init container or a CI step before the FrontEnd Server pod starts.
OAuth client registration
Each FrontEnd Server instance is an OAuth client of the
MibAuthorization Server. Register it by inserting a row into
API_CLIENTS in the Auth DB:
INSERT INTO API_CLIENTS
(NAME, OWNER, ACTIVE, ALLOWS_REFRESH_TOKEN, ALLOWED_ORIGINS,
OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_CLIENT_TYPE,
REDIRECT_URI, CONFIGURABLE_PERMISSIONS_URL)
VALUES
('My CMS', 1, 1, 1, 1,
'mibFrontEndClient', 'mY53Cr37aCc3s5K3y', 1,
'https://cms.example.com/oauth/callback',
'https://cms.example.com/configurablepermissions');
Key columns:
OAUTH_CLIENT_TYPE = 1— Authorization Code grant (the only grant supported by the FrontEnd Server).REDIRECT_URI— must exactly match the FrontEnd Server's/oauth/callbackURL.CONFIGURABLE_PERMISSIONS_URL— the FrontEnd Server's/configurablepermissionsendpoint. Used by the Authorization Server admin UI to know what permissions this client exposes for configuration. See Permissions Controller.
For details on OAuth client registration, see Authorization Server Configuration.
Configuration
The FrontEnd Server uses the MIB framework's MibConfig system. Every
config can be supplied as an XML .mibconfig file in /app/config/ or
as an environment variable matching the pattern
MIB<CONFIGNAME>_<SECTION>_<KEY>. In container deployments env vars
are the norm.
A full reference is in the per-config docs under CMS · MibConfig. Here's the minimal set for a working FrontEnd Server:
| Config | Purpose | Reference |
|---|---|---|
MibCmsFrontEndServerBaseConfig |
Self-URL, default language, feature toggles | MibCmsFrontEndServerBaseConfig |
MibAuthorizationClientConfig |
OAuth client identity + Auth Server URL | MibAuthorizationServerConfig |
MibApiClientConfig |
Data API base URL | — |
MibPermissionMicroServiceClientConfig |
Permission MS URL | Microservices — Permissions |
MibDatabaseConfig |
FrontEnd DB connection | MibDatabaseConfig |
MibCacheConfig |
Cache backend (in-memory / Memcached / Couchbase) | MibCache (framework) |
MibObjectCacheConfig |
Per-table TTLs | — |
MibTranslationConfig |
Dictionaries for {DICT:Section/Key} |
Localization |
MibLogConfig |
Log targets (file / DB / EventViewer / stdout) | MibLog (framework) |
Optional configs:
| Config | When needed |
|---|---|
MibEditHistoryMicroServiceClientConfig |
When UseEditHistoryMicroService=true |
MibFileManagementMicroServiceClientConfig |
When using TSV exports or file uploads |
Env-var shape
MibConfig flattens the XML structure into env vars by uppercasing
the path and joining with _:
<MibAuthorizationClientConfig>
<default>
<serverUrl>https://auth.example.com</serverUrl>
</default>
</MibAuthorizationClientConfig>
becomes
MIBAUTHORIZATIONCLIENTCONFIG_DEFAULT_SERVERURL=https://auth.example.com
Notable MibCmsFrontEndServerBaseConfig keys (React-era)
<MibCmsFrontEndServerBaseConfig>
<default>
<!-- Self-URL — must match what's registered as the OAuth REDIRECT_URI prefix -->
<rootUrl>https://cms.example.com/</rootUrl>
<!-- Path under which the React shell is served (typically /app via reverse proxy) -->
<frontEndAppPath>/app</frontEndAppPath>
<!-- Default language picked when the user has no preference -->
<defaultLanguage>en-us</defaultLanguage>
<!-- Pre-React rendering switch — leave false unless explicitly needed for legacy MVC -->
<renderOnlyMibComponents>false</renderOnlyMibComponents>
<!-- Concurrency MS pairing -->
<userConcurrencyServiceUrl>http://concurrency-ms</userConcurrencyServiceUrl>
<userConcurrencyPollingTime>00:00:10</userConcurrencyPollingTime>
<!-- Audit trail integration -->
<useEditHistoryMicroService>true</useEditHistoryMicroService>
<!-- CORS — only if the React shell is served from a different origin -->
<corsOrigins>https://shell.example.com</corsOrigins>
<corsMethods>GET,POST,PUT,DELETE,PATCH,OPTIONS</corsMethods>
<corsHeaders>Content-Type,Authorization,If-None-Match,If-Match</corsHeaders>
<!-- TSV downloads via FileManagement (MIB 6.0+) -->
<useFileManagementServiceForTsvDownload>true</useFileManagementServiceForTsvDownload>
</default>
</MibCmsFrontEndServerBaseConfig>
The full reference is at MibCmsFrontEndServerBaseConfig.
CorsOrigins
Only relevant when the React shell is served from a different origin
than the FrontEnd Server. If both run under one reverse proxy (e.g.
https://cms.example.com/app/ for the shell and
https://cms.example.com/api/v2/... for the BFF), CORS is not in play
— omit corsOrigins / corsMethods / corsHeaders.
When configured, you must also enable
CorsAllowCredentials so the browser sends the
.AspNetCore.Cookies cookie cross-origin.
Pairing with the React shell
The React shell needs three pieces of runtime config:
VITE_API_URL— the FrontEnd Server's root (e.g.https://cms.example.com/). The shell hits<root>/api/v2/...for page renders and<root>/oauth/...for the login redirect.VITE_CUSTOM_COMPONENTS_URL(and_2,_3) — federated remote URLs. See System Overview — federated remotes.- A working CORS or same-origin setup. Same-origin (one reverse proxy) is strongly preferred — avoids CORS, lets the cookie ride along by default, simplifies SameSite policy.
The shell does not need to know about the Data API, microservices, or any other backend service. Everything goes through the FrontEnd Server.
Verifying the install
A healthy FrontEnd Server pod should:
- Pass its readiness probe at
/healthcheck(200 OK). - Serve the OAuth callback at
/oauth/callback. - Serve
/configurablepermissions(200 OK, returnsGenericPermissionJSON; supports ETag / 304). - Return a non-empty
/api/v2/display/<startPage>/0once you log in through the React shell. - Emit a
[RenderV2-Stats]log line per page render — see System Overview — observability.
If /healthcheck is failing, the most common causes are:
- Permission MS unreachable. Startup blocks on the first
permission-metadata fetch by default. See the
MetadataInitialFetchTimeoutSecondssetting in Microservices — Permissions. - Database unreachable. Check
MIBDATABASECONFIG_*and the FrontEnd DB connection. - Auth Server unreachable. Check
MIBAUTHORIZATIONCLIENTCONFIG_DEFAULT_SERVERURL. - Missing customisation DLL. Pod crashes early with a
FileNotFoundExceptionon aMediaiBox.*.dllor<Customer>.Mib3.*.dll. See Backend overlay system — version pinning.
See also
- Overview — the one-page mental model
- System Overview — full mental model of how the FrontEnd Server fits with the rest of the CMS
- Backend overlay system — the 4-layer DLL stack behind every deploy
- Get Started with Mib v5.0 (Docker) — end-to-end tutorial
- Get Started with Mib v5.0 (Podman)
- Local Development — running the FrontEnd Server locally for component dev
- Authorization Server Configuration — OAuth grants and client registration
- Permissions Microservice — required dependency
- MibCmsFrontEndServerBaseConfig — full config reference
- Legacy MVC — IIS Installation — the deprecated install path for customers still on IIS / .NET Framework