Skip to content

Cookbook Deploy Fine Grained

Andrew MacGaffey edited this page Aug 16, 2026 · 7 revisions

Deployment Cookbook: Fine-Grained

The same capabilities as Static MDS, with each service running separately instead of consolidated together. Every service - session, pub/sub, SQL, orchestration, the gateway, admin, and each projector - runs on its own, so you can place it, size it, and make it redundant on its own terms.

Audience: Architect, Operator. Choose this when you want isolation between services, or want to make individual services redundant.

This is the Scalable, fine-grained, multi-homed topology in Architecture: Advanced run at fixed capacity - read that for the full picture; install here first and learn the details later.


The same images, three ways to run them

Every method below runs the identical images (ghcr.io/metafluent/mf-*) with the identical deployment-config/ - only the way you launch them differs:

Method You launch it with Ideal for
Conventional the host ./run launcher the standard install - this is the primary path
Docker docker compose up a demo or lab on a single machine
Kubernetes standard Deployment / Service manifests a cluster-managed fixed install

The consolidated mf-core-srvcs of the Static MDS deployment simply becomes its four constituent services here. The projector images are unchanged.


Images you need

Image Role Release
mf-api-gateway REST entry point for the cluster deploy-mf-api-gateway
mf-admin ResourceStore (config), network registry, central log deploy-mf-admin
mf-session Authenticates clients and issues session identity deploy-mf-session
mf-pubsub Serves publish/subscribe (topic) subscriptions deploy-mf-pubsub
mf-sql Serves SQL (relational) queries deploy-mf-sql
mf-orchestration Places and coordinates the projector tier deploy-mf-orchestration
mf-projector-mds MDS projector (ETA + MAMA adapters); run one or more deploy-mf-projector-mds

See the Image Catalog for what each image contains. To try the platform without a live feed, add a simulator - see Use a simulator below.


Conventional Fine-Grained

The primary path: extracted images, run natively. Full mechanics are in Deployment: Without Docker.

  1. From each release above, download the installation-package zip and unpack it.
  2. Edit each deployment-config/ for your environment (see Configuration: Basics). The packages ship working defaults; you change only what your environment needs.
  3. Set JAVA_HOME and start each with ./run.

Each service looks for the gateway at mf-api-gateway:9090 by default. Point it at your gateway host whatever way suits your environment: set METAFLUENT_API_GATEWAY_HOST (and METAFLUENT_API_GATEWAY_PORT) in the launch environment, set the same values in deployment-config/, or map the name in your own name resolution. The launcher prints the value in effect at startup.

Point the projector at its ETA server. The ETA/MDS projector reads its feed from an ETA server given by manager.etaServerHost (port etaServerPort, default 14002). It defaults to localhost, so if the feed runs on the same host as the projector there is nothing to set. For a feed on another host, set METAFLUENT_ETA_SERVER_HOST (or the property in deployment-config/) to its address.

Isolation and redundancy, service by service

Because each service runs on its own, you can:

  • Place it where it belongs - put a service on its own host or network, so different services can sit on different role networks (control, private, client).
  • Make it redundant on its own - run two of any service that carries client state (session, pub/sub, SQL, orchestration) as an active/standby pair; one serves, the other stays hot and takes over in seconds. The mechanism is Architecture: Advanced.
  • Add projector capacity and resilience - want more throughput, or a feed that keeps flowing if one projector restarts? Run another mf-projector-mds. Projectors can each carry a different set of feeds (METAFLUENT_ETA_FEED_INCLUSIONS / METAFLUENT_ETA_FEED_EXCLUSIONS), exactly as in Static MDS.

Docker Fine-Grained

Docker Compose brings every service up on a single machine, ideal for a demo or a lab. For production, use the conventional or Kubernetes install.

Save this as docker-compose.yml and run METAFLUENT_HOST_UID=$(id -u) docker compose up -d:

services:

  mf-api-gateway:
    image: ghcr.io/metafluent/mf-api-gateway-cfg-stable:milestone
    container_name: mf-api-gateway
    network_mode: host
    environment: { METAFLUENT_HOST_UID: "${METAFLUENT_HOST_UID}" }
    volumes: [ "./logs:/app/logs", "./data:/app/data" ]

  mf-admin:
    image: ghcr.io/metafluent/mf-admin-cfg-stable:milestone
    container_name: mf-admin
    network_mode: host
    environment: { METAFLUENT_HOST_UID: "${METAFLUENT_HOST_UID}" }
    volumes: [ "./logs:/app/logs", "./data:/app/data" ]

  mf-session:
    image: ghcr.io/metafluent/mf-session-cfg-stable:milestone
    container_name: mf-session
    network_mode: host
    environment: { METAFLUENT_HOST_UID: "${METAFLUENT_HOST_UID}" }
    volumes: [ "./logs:/app/logs", "./data:/app/data" ]

  mf-pubsub:
    image: ghcr.io/metafluent/mf-pubsub-cfg-stable:milestone
    container_name: mf-pubsub
    network_mode: host
    environment: { METAFLUENT_HOST_UID: "${METAFLUENT_HOST_UID}" }
    volumes: [ "./logs:/app/logs", "./data:/app/data" ]

  mf-sql:
    image: ghcr.io/metafluent/mf-sql-cfg-stable:milestone
    container_name: mf-sql
    network_mode: host
    environment: { METAFLUENT_HOST_UID: "${METAFLUENT_HOST_UID}" }
    volumes: [ "./logs:/app/logs", "./data:/app/data" ]

  mf-orchestration:
    image: ghcr.io/metafluent/mf-orchestration-cfg-stable:milestone
    container_name: mf-orchestration
    network_mode: host
    environment: { METAFLUENT_HOST_UID: "${METAFLUENT_HOST_UID}" }
    volumes: [ "./logs:/app/logs", "./data:/app/data" ]

  mf-projector-mds:
    image: ghcr.io/metafluent/mf-projector-mds-cfg-stable:milestone
    container_name: mf-projector-mds
    network_mode: host
    environment: { METAFLUENT_HOST_UID: "${METAFLUENT_HOST_UID}" }
    volumes: [ "./logs:/app/logs", "./data:/app/data" ]

METAFLUENT_HOST_UID gives the in-container user your host UID, so the bind-mounted ./logs and ./data stay writable. Run more projectors, partitioned by feed, the same way as in Static MDS.


Kubernetes Fine-Grained

An example. It runs the same images and deployment-config/ as the other two methods: one Deployment per service, and a Service for each name other services address.

# Each service: a Deployment plus a Service on the name others address it by.
# Shown for the gateway; session, pubsub, sql, orchestration, and admin follow
# the identical pattern with their own image and port.
apiVersion: apps/v1
kind: Deployment
metadata: { name: mf-api-gateway }
spec:
  replicas: 1
  selector: { matchLabels: { app: mf-api-gateway } }
  template:
    metadata: { labels: { app: mf-api-gateway } }
    spec:
      containers:
        - name: mf-api-gateway
          image: ghcr.io/metafluent/mf-api-gateway-cfg-stable:milestone
---
apiVersion: v1
kind: Service
metadata: { name: mf-api-gateway }
spec:
  selector: { app: mf-api-gateway }
  ports: [ { port: 9090, targetPort: 9090 } ]
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: mf-session }
spec:
  replicas: 1
  selector: { matchLabels: { app: mf-session } }
  template:
    metadata: { labels: { app: mf-session } }
    spec:
      containers:
        - name: mf-session
          image: ghcr.io/metafluent/mf-session-cfg-stable:milestone
---
apiVersion: v1
kind: Service
metadata: { name: mf-session }
spec:
  selector: { app: mf-session }
  ports: [ { port: 8900, targetPort: 8900 } ]
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: mf-projector-mds }
spec:
  replicas: 1
  selector: { matchLabels: { app: mf-projector-mds } }
  template:
    metadata: { labels: { app: mf-projector-mds } }
    spec:
      containers:
        - name: mf-projector-mds
          image: ghcr.io/metafluent/mf-projector-mds-cfg-stable:milestone

To make a service redundant, raise its replicas (or add a second Deployment); the active/standby election picks which instance serves. To add projector capacity or a feed partition, add another projector Deployment.


Use a simulator

To evaluate the platform without a live feed, add the mf-eta-simulator image - a synthetic ETA source that replays recorded content, so your projectors have something to serve.

Image Role Release
mf-eta-simulator Synthetic ETA data source deploy-mf-eta-simulator

Run it the same way as everything else: as another ./run package, another Compose service, or another Deployment. The Compose stanza is the same as in Static MDS - and the projector already finds it at the localhost default, nothing to set.


Going further

  • Static MDS - the consolidated starting point this page decomposes.
  • Static MDS with Compute - add a compute tier that derives computed content.
  • Scalable MDS - let the projector tier grow and shrink with load automatically.
  • Serving real, entitled Refinitiv data? See Configure DACS to turn on authentication and entitlement checks.

Where to go next

Clone this wiki locally