# What Is the OpenMAIC Render-Service Container and How Does It Work?

> Discover the OpenMAIC render-service container, a micro-service converting Hyperframes projects to MP4 videos with Chromium and FFmpeg. Learn its essential role.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: how-to-guide
- Published: 2026-09-01

---

**The `render-service` container is an isolated micro-service that converts browser-generated Hyperframes projects into downloadable MP4 videos using Chromium and FFmpeg.**

The **render-service container** in OpenMAIC offloads CPU-intensive video rendering from the main Next.js application to keep the core platform lightweight. When users click "Export Video" in the browser, this dedicated Docker worker processes the conversion, while remaining entirely optional—if disabled, the system seamlessly falls back to ZIP downloads for local CLI rendering.

## Architecture and Core Purpose

The primary role of the render-service is to act as a **dedicated video-rendering worker** that isolates heavyweight native dependencies from the web application. As defined in [`docker-compose.yml`](https://github.com/THU-MAIC/OpenMAIC/blob/main/docker-compose.yml), the container bundles **Chromium** (to load and play the Hyperframes bundle) and **FFmpeg** (to encode the raw frames into H.264 video).

This isolation is architectural. Chromium and FFmpeg introduce significant binary size, memory footprint, and security surface area. By confining these to a separate service, the main OpenMAIC app avoids bloat while the render-service runs in an isolated network with restricted egress policies.

### Security and Network Isolation

The container launches with the `NET_ADMIN` Linux capability to enforce strict egress lockdown, preventing the Chromium instance from initiating unauthorized outbound connections during rendering. This security model is implemented in [`render-service/docker-entrypoint.sh`](https://github.com/THU-MAIC/OpenMAIC/blob/main/render-service/docker-entrypoint.sh) and documented in [`render-service/README.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/render-service/README.md).

## How the Render-Service Fits into the Export Workflow

The video export process follows a three-stage pipeline bridging browser-side generation with containerized encoding.

### Step 1: Browser Bundle Generation

When a user selects **"Export Video"**, the OpenMAIC front-end first constructs a self-contained Hyperframes bundle entirely within the browser. This JSON payload encapsulates all project assets, animation keyframes, and timing metadata required for deterministic frame-by-frame rendering.

### Step 2: Service Communication via RENDER_SERVICE_URL

The main application communicates with the render-service through the **`RENDER_SERVICE_URL`** environment variable, which defaults to `http://render-service:9000` as configured in [`docker-compose.yml`](https://github.com/THU-MAIC/OpenMAIC/blob/main/docker-compose.yml). The helper function `resolveRenderServiceUrl()` in [`lib/server/render-service.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/server/render-service.ts) centralizes this resolution:

```typescript
import { resolveRenderServiceUrl } from '@/lib/server/render-service';

// Build URL to the render‑service endpoint
const url = `${resolveRenderServiceUrl()}/render/submit`;

// `hyperframeBundle` is the JSON produced by the browser
await fetch(url, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ bundle: hyperframeBundle })
});

```

### Step 3: Video Encoding Pipeline

Upon receiving the bundle at `/render/submit`, the container loads the project into headless Chromium to capture sequential frames, then pipes the raw video stream through FFmpeg for MP4 encoding. The final video is returned to the main application or uploaded to cloud storage, depending on the deployment topology described in `packages/docs/content/docs/deployment.mdx`.

## Configuration and Runtime Options

The behavior of the render-service is tunable through environment variables documented in [`render-service/README.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/render-service/README.md) and `packages/docs/content/docs/configuration.mdx`:

- **`RENDER_SERVICE_URL`**: The internal endpoint used by the Next.js app to reach the service (default: `http://render-service:9000`)
- **`RENDER_MAX_CONCURRENCY`**: Limits parallel rendering jobs to prevent resource exhaustion
- **Timeout variables**: Configure maximum waiting periods for Chromium startup and frame capture completion

## Fallback Behavior When the Service Is Unavailable

Because the render-service is optional, OpenMAIC implements graceful degradation. If `RENDER_SERVICE_URL` is undefined or the container is unreachable, the application falls back to offering a ZIP download of the Hyperframes project:

```typescript
if (!process.env.RENDER_SERVICE_URL) {
  // Offer a ZIP download instead of MP4 rendering
  const zipUrl = await generateProjectZip(bundle);
  window.location.href = zipUrl;
}

```

Users can then render the video locally using the OpenMAIC CLI, maintaining full functionality even in lightweight or air-gapped deployments.

## Testing and CLI Usage

Developers can interact with the container directly through its CLI interface, as demonstrated in the continuous integration suite. The file [`tests/workflows/ci-video-export-contract.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/workflows/ci-video-export-contract.test.ts) exercises the rendering pipeline using the following pattern:

```bash

# Inside the repo root

npx render-service submit path/to/hyperframe-bundle.json

```

This command submits a bundle directly to the service, bypassing the Next.js API layer, which is useful for debugging rendering issues or batch-processing videos via CI/CD pipelines.

## Summary

- The **render-service container** is an isolated micro-service in OpenMAIC that converts Hyperframes bundles to MP4 videos using Chromium and FFmpeg.
- It communicates with the main app via the **`RENDER_SERVICE_URL`** environment variable, defaulting to `http://render-service:9000` as configured in [`docker-compose.yml`](https://github.com/THU-MAIC/OpenMAIC/blob/main/docker-compose.yml).
- The service is **optional**; when disabled, OpenMAIC falls back to ZIP downloads for local CLI rendering.
- Security hardening includes the **`NET_ADMIN`** capability and network isolation defined in [`render-service/docker-entrypoint.sh`](https://github.com/THU-MAIC/OpenMAIC/blob/main/render-service/docker-entrypoint.sh).
- Configuration options like **`RENDER_MAX_CONCURRENCY`** control resource utilization and queue management.

## Frequently Asked Questions

### What happens if the render-service container is not running?

If the container is unavailable or `RENDER_SERVICE_URL` is not set, OpenMAIC automatically falls back to generating a ZIP download of the Hyperframes project. Users can then render the video locally using the OpenMAIC CLI tools without requiring the containerized service.

### Why is the render-service separated from the main Next.js application?

The service isolates **Chromium** and **FFmpeg**, which are heavyweight native dependencies with large binary footprints and complex security requirements. Running them in a separate container keeps the core web application lightweight and reduces the attack surface for browser-based exploits.

### How does OpenMAIC securely handle user content in the render-service?

The container launches with the `NET_ADMIN` Linux capability to enforce egress lockdown, preventing the Chromium instance from accessing external networks during rendering. This security model is implemented in [`render-service/docker-entrypoint.sh`](https://github.com/THU-MAIC/OpenMAIC/blob/main/render-service/docker-entrypoint.sh) and described in the service's README.

### Can I use the render-service CLI independently of the web interface?

Yes. The container exposes a CLI interface accessible via `npx render-service submit`, as tested in [`tests/workflows/ci-video-export-contract.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/workflows/ci-video-export-contract.test.ts). This allows direct submission of Hyperframes bundles for headless video generation without using the browser-based export button.