Quick Start

Get Magic Runtime running and execute your first controller

5 minutes

0 Prerequisites

  • Docker Engine + Docker Compose plugin
  • curl (and optionally jq)
  • Ports 80 (UI) and 8000 (API) available

1 Download & Configure

Download the Production Stack and configure environment variables:

Terminal
# Download Production Stack
wget https://magic.threadsync.io/deploy/magic-runtime-2.0.0-production.tar.gz

# Verify via signed checksums (recommended)
wget https://magic.threadsync.io/deploy/SHA256SUMS
wget https://magic.threadsync.io/deploy/SHA256SUMS.sig
wget https://magic.threadsync.io/deploy/threadsync-releases.asc
gpg --import threadsync-releases.asc
gpg --verify SHA256SUMS.sig SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
# Expected SHA256 (Production Stack): b6e7400e0f81715072fb8480682efc5ab7cabaf4313da87210078fad5a4191a6

# Extract and enter directory
tar -xzf magic-runtime-2.0.0-production.tar.gz
cd magic-runtime

# Configure environment
cp .env.example .env

# Edit .env with your values:
# - DB_PASSWORD=your_strong_password
# - JWT_SECRET=your_jwt_secret
# - ADMIN_API_KEY=your_api_key
# - ALLOWED_ORIGINS=http://localhost

Production Mode

Keep CONTROLLER_EXECUTION_MODE=process and set an explicit CONTROLLER_ALLOWLIST for production deployments.

2 Build & Run

Terminal
# Start all services
docker compose up -d --build

# Initialize database (runs migrations)
./scripts/init_db.sh

Open http://localhost — the dashboard is served by Nginx; /api is proxied to the Magic runtime.

3 Verify Installation

Terminal
# Check health endpoint
curl http://localhost/api/health | jq

# Expected response:
# {
#   "status": "healthy",
#   "version": "2.0.0",
#   "runtime": "magic-controller-runtime"
# }

# List available controllers
curl http://localhost/api/controllers | jq

# Check readiness (includes DB + migrations)
curl http://localhost/api/readyz | jq

4 Execute Your First Controller

The runtime comes with a demo controller. Execute it:

Terminal
# Execute the demo controller
curl -X POST http://localhost/api/execute/DemoController \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $ADMIN_API_KEY" \
  -d '{"message": "Hello, Magic!"}' | jq

# Expected response:
# {
#   "result": "Processed: Hello, Magic!",
#   "request_id": "req_abc123",
#   "duration_ms": 12
# }

5 Create Your Own Controller

5a. Define the Contract

controllers/my_controller/contract.yaml
name: MyController
version: 1.0.0

input:
  type: object
  required: [name]
  properties:
    name:
      type: string
      maxLength: 100

output:
  type: object
  required: [greeting, request_id]
  properties:
    greeting:
      type: string
    request_id:
      type: string

capabilities: []  # No external access needed

resources:
  cpu: 0.25
  memory: 128Mi
  timeout: 5s

5b. Implement the Controller

controllers/my_controller/controller.py
from magic import Controller, contract

@contract("./contract.yaml")
class MyController(Controller):

    async def execute(self, input: dict) -> dict:
        name = input["name"]

        return {
            "greeting": f"Hello, {name}! Welcome to Magic.",
            "request_id": self.request_id
        }

5c. Deploy & Test

Using the Magic CLI

The magic CLI is bundled inside the runtime container. Run commands via:

docker compose exec runtime magic <command>

Or, if you're working inside the container: magic <command> directly.

v2.1 will add a host CLI via pipx install magic-runtime for local development. See Enterprise Standards → CLI Lanes.

Terminal
# Validate the contract
docker compose exec runtime magic validate ./controllers/my_controller/

# Deploy (hot-reload, no restart needed)
docker compose exec runtime magic deploy ./controllers/my_controller/

# Execute
curl -X POST http://localhost/api/execute/MyController \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $ADMIN_API_KEY" \
  -d '{"name": "Developer"}' | jq

You're Ready!

You've deployed your first contract-bound controller. Check the User Guide for advanced topics.

6 Next Steps