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
- User creates webapp via marie-studio UI
- Frontend calls tRPC
webapp.createprocedure - Backend stores metadata in PostgreSQL and calls webapp-runner HTTP API
- Webapp-runner clones code, builds Docker image, starts container
- Traefik automatically routes
{slug}.apps.marie.localto the container - User accesses webapp via subdomain URL
Quick Start
Prerequisites
- Python 3.11+
- Docker with Docker Compose
- Access to Docker socket (for container management)
Development
From monorepo root
pnpm runner:install # Install Python dependencies in virtualenv
pnpm runner:dev # Run development server with hot reloadDocker Deployment
From monorepo root
pnpm runner:build # Build Docker image
pnpm runner:up # Start services (runner + Traefik)
pnpm runner:logs # View logs
pnpm runner:down # Stop servicesConfiguration
Environment variables (can be set in .env file):
| Variable | Default | Description |
|---|---|---|
HOST | 0.0.0.0 | Server bind address |
PORT | 8080 | Server port |
DEBUG | false | Enable debug mode and hot reload |
APPS_DIR | /data/apps | Directory for app data storage |
TEMPLATES_DIR | ./templates | Path to Dockerfile templates |
DOMAIN | apps.marie.local | Base domain for webapp subdomains |
DOCKER_NETWORK | marie-network | Docker network for containers |
TRAEFIK_ENTRYPOINT | web | Traefik entrypoint name |
RUNNER_API_KEY | “ | API key for authentication (empty = disabled) |
DEFAULT_MEMORY_LIMIT | 2g | Default container memory limit |
DEFAULT_CPU_LIMIT | 1.0 | Default container CPU limit (cores) |
API Reference
Create Webapp
POST /apps
Content-Type: multipart/form-dataForm Fields:
id(required): Unique identifier (UUID)name(required): Display nameapp_type:gradio|streamlit|fastapi|static|docker(default:gradio)git_url: Git repository URL (required if nocodefile)git_branch: Git branch (default:main)port: Container port (default:7860)env: JSON-encoded environment variables (default:{})code: Uploaded zip file (required if nogit_url)
Response:
{
"id": "abc123",
"name": "My Webapp",
"status": "running",
"url": "https://abc123.apps.marie.local"
}List Webapps
GET /appsGet 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}/redeployGet Logs
GET /apps/{app_id}/logs?tail=100Health Check
GET /healthApp Types
Gradio
Python apps using Gradio .
Expected structure:
my-gradio-app/
├── app.py # Must contain Gradio interface
└── requirements.txt # Optional dependenciesExample:
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
- Check logs:
pnpm runner:logsorGET /apps/{id}/logs - Verify Docker network exists:
docker network ls | grep marie-network - Check port conflicts:
docker psto see running containers
Build fails
- Ensure
requirements.txthas valid dependencies - Check for syntax errors in app code
- For custom Dockerfiles, ensure they’re valid
Cannot access webapp URL
- Verify Traefik is running:
docker ps | grep traefik - Check DNS/hosts file for
*.apps.marie.local - Verify container is running:
GET /apps/{id}
Last updated on