Skip to Content
ServicesWebapp Runner

Webapp Runner Service

Container lifecycle management service for M3 Forge webapps.

Overview

Webapp Runner is a Python/FastAPI service that manages Docker containers for user-deployed webapps. It provides a “push code, it runs” experience similar to Hugging Face Spaces or Lightning AI.

Key Features

  • Multi-App Support: Gradio, Streamlit, FastAPI, static HTML, custom Docker
  • Git Integration: Clone and deploy directly from Git repositories
  • Zip Upload: Deploy from uploaded zip files
  • Dynamic Routing: Traefik integration for automatic subdomain routing
  • Container Lifecycle: Create, start, stop, redeploy, delete
  • Log Streaming: Access container logs via API
  • Health Checks: Monitor runner and Docker daemon health

Architecture

┌─────────────────┐ tRPC ┌─────────────────┐ HTTP ┌─────────────────┐ │ marie-studio │◄────────────►│ marie-studio │◄────────────►│ webapp-runner │ │ (Frontend) │ │ (Backend) │ │ (Python) │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ │ iframe + session token │ Prisma │ Docker SDK ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Webapp Plugin │ │ PostgreSQL │ │ Docker + Traefik│ │ (Gradio/etc) │ │ (webapp_*) │ │ (containers) │ └─────────────────┘ └─────────────────┘ └─────────────────┘

Communication Flow

  1. User creates webapp via marie-studio UI
  2. Frontend calls tRPC webapp.create procedure
  3. Backend stores metadata in PostgreSQL and calls webapp-runner HTTP API
  4. Webapp-runner clones code, builds Docker image, starts container
  5. Traefik automatically routes {slug}.apps.marie.local to the container
  6. User accesses webapp via subdomain URL

Quick Start

Prerequisites

  • Python 3.11+
  • Docker with Docker Compose
  • Access to Docker socket (for container management)

Development

pnpm runner:install # Install Python dependencies in virtualenv pnpm runner:dev # Run development server with hot reload

Docker Deployment

pnpm runner:build # Build Docker image pnpm runner:up # Start services (runner + Traefik) pnpm runner:logs # View logs pnpm runner:down # Stop services

Configuration

Environment variables (can be set in .env file):

VariableDefaultDescription
HOST0.0.0.0Server bind address
PORT8080Server port
DEBUGfalseEnable debug mode and hot reload
APPS_DIR/data/appsDirectory for app data storage
TEMPLATES_DIR./templatesPath to Dockerfile templates
DOMAINapps.marie.localBase domain for webapp subdomains
DOCKER_NETWORKmarie-networkDocker network for containers
TRAEFIK_ENTRYPOINTwebTraefik entrypoint name
RUNNER_API_KEYAPI key for authentication (empty = disabled)
DEFAULT_MEMORY_LIMIT2gDefault container memory limit
DEFAULT_CPU_LIMIT1.0Default container CPU limit (cores)

API Reference

Create Webapp

POST /apps Content-Type: multipart/form-data

Form Fields:

  • id (required): Unique identifier (UUID)
  • name (required): Display name
  • app_type: gradio | streamlit | fastapi | static | docker (default: gradio)
  • git_url: Git repository URL (required if no code file)
  • git_branch: Git branch (default: main)
  • port: Container port (default: 7860)
  • env: JSON-encoded environment variables (default: {})
  • code: Uploaded zip file (required if no git_url)

Response:

{ "id": "abc123", "name": "My Webapp", "status": "running", "url": "https://abc123.apps.marie.local" }

List Webapps

GET /apps

Get Webapp Status

GET /apps/{app_id}

Delete Webapp

DELETE /apps/{app_id}

Start / Stop / Redeploy

POST /apps/{app_id}/start POST /apps/{app_id}/stop POST /apps/{app_id}/redeploy

Get Logs

GET /apps/{app_id}/logs?tail=100

Health Check

GET /health

App Types

Python apps using Gradio .

Expected structure:

my-gradio-app/ ├── app.py # Must contain Gradio interface └── requirements.txt # Optional dependencies

Example:

import gradio as gr def greet(name): return f"Hello, {name}!" demo = gr.Interface(fn=greet, inputs="text", outputs="text") demo.launch()

Troubleshooting

If RUNNER_API_KEY is set, all requests need X-API-Key header. Set RUNNER_API_KEY= (empty) to disable auth for development.

Container fails to start

  1. Check logs: pnpm runner:logs or GET /apps/{id}/logs
  2. Verify Docker network exists: docker network ls | grep marie-network
  3. Check port conflicts: docker ps to see running containers

Build fails

  1. Ensure requirements.txt has valid dependencies
  2. Check for syntax errors in app code
  3. For custom Dockerfiles, ensure they’re valid

Cannot access webapp URL

  1. Verify Traefik is running: docker ps | grep traefik
  2. Check DNS/hosts file for *.apps.marie.local
  3. Verify container is running: GET /apps/{id}
Last updated on