Skip to main content

Quickstart Guide

Get up and running with Plato Hub in minutes. Create and deploy your first simulator with just a few commands.

Installation

First, install the Plato SDK for your platform:
uv init

# macOS Silicon (M1/M2/M3)
uv add plato-sdk==1.0.95.dev20251027235103

# macOS Intel
uv add plato-sdk==1.0.95.dev20251027235111

# Linux AMD64
uv add plato-sdk==1.0.95.dev20251027235232

Your First Simulator

1

Clone a Simulator

Clone an existing simulator:
uv run plato hub clone custom-sim
cd custom-sim
This downloads the simulator code and sets up your local development.You can explore available hub commands:
uv run plato hub
2

Check Configuration

Look at the simulator configuration in plato-config.yml:
plato-config.yml
service: baserow  # Service name for this simulator

datasets:
  base: &base  # Define 'base' dataset with anchor for reuse
    compute: &base_compute  # VM resource allocation
      cpus: 1                    # Number of vCPUs (1-8)
      memory: 3072               # RAM in MB (512-16384)
      disk: 10240                # Disk space in MB (1024-102400)
      app_port: 80               # Port your application listens on
      plato_messaging_port: 7000 # Port for Plato worker (keep unless conflicting with an app port)

    metadata: &base_metadata  # Simulator metadata
      name: BaseRow           # Display name
      description: BaseRow    # Brief description
      source_code_url: unknown # Link to source repository
      start_url: https://sims.plato.so  # URL to access the app
      license: GPL-3.0        # Software license
      variables:              # Login credentials for the simulator
        - name: username
          value: admin
        - name: password
          value: admin123
      flows_path: base/flows.yaml  # Path to flow definitions

    services: &base_services  # Service configuration
      main_app:               # Service name (can be any identifier)
        type: docker-compose  # Service type (docker-compose only)
        file: base/docker-compose.yml  # Path to compose file
        healthy_wait_timeout: 600      # Seconds to wait for health
        required_healthy_containers:   # Containers that must be healthy
          - backend            # Container name from docker-compose

    listeners: &base_listeners  # Database mutation listeners
      db:                    # Listener name (can be any identifier)
        type: db             # Listener type (db, file, etc.)
        db_type: postgresql  # Database type (postgresql, mysql, sqlite)
        db_host: 127.0.0.1   # Database host
        db_port: 5432        # Database port
        db_user: baserow     # Database username
        db_password: baserow # Database password
        db_database: baserow # Database name
        volumes:             # Volume mounts for signal files
          - /home/plato/db_signals:/tmp/postgres-signals
          # Format: <vm_path>:<container_path>
          # Multiple volumes can be specified
This configuration defines your VM resources, services, and how your simulator runs.
3

Start Development

You can now use the Python SDK to create sandboxes and test your simulator programmatically.See the example start script below for how to create and manage sandboxes with the SDK.

Project Structure

Your simulator project structure:
custom-sim/
├── plato-config.yml          # Required: VM and service configuration
├── base/
│   ├── docker-compose.yml    # Main application services
│   └── flows.yaml            # Flow definitions
└── .plato-hub.json          # Hub configuration (auto-generated)

Environment Setup

Before running the start script, create a .env file with your credentials:
.env
PLATO_API_KEY=your-api-key-here
PLATO_BASE_URL=https://plato.so/api
Get your API key from plato.so/settings.

Example Start Script

Here’s how to programmatically create and manage sandboxes using the Python SDK:
import os
from plato.sandbox_sdk import PlatoSandboxClient
from plato.models.sandbox import CreateSnapshotRequest, PlatoConfig
import yaml

# Initialize client with your API key
client = PlatoSandboxClient(api_key=os.environ['PLATO_API_KEY'])

# Load configuration
dataset = 'base'
sim_name = 'your-sim-name'  # ask rob/pranav for sim name

with open(f"{sim_name}/plato-config.yml", "r") as f:
    cfg = PlatoConfig.model_validate(yaml.safe_load(f))

# Create sandbox and wait for it to be ready
sandbox = client.create_sandbox(config=cfg.datasets[dataset], wait=True, timeout=900)

# Set up SSH access
ssh_response = client.setup_ssh(sandbox, cfg.datasets[dataset], dataset=dataset)

# Get Gitea credentials for cloning
creds = client.get_gitea_credentials()
clone_url = f"https://{creds['username']}:{creds['password']}@hub.plato.so/{creds['org_name']}/{sim_name}"

# SSH into the VM: ssh -F /Users/pranavputta/.plato/ssh_45.conf sandbox-45
# Clone repository onto VM: git clone {clone_url}

# Start the service (wait for containers to be healthy)
start_service = client.start_service(
    public_id=sandbox.public_id,
    dataset=dataset,
    dataset_config=cfg.datasets[dataset]
)
# Wait for service to start...

# Start the Plato worker (for mutation tracking)
start_worker = client.start_worker(
    public_id=sandbox.public_id,
    dataset=dataset,
    dataset_config=cfg.datasets[dataset]
)
# Wait for worker to be healthy...

# Once services are running and tested, create a snapshot
response = client.create_snapshot(
    public_id=sandbox.public_id,
    request=CreateSnapshotRequest(service=sim_name, dataset=dataset)
)

Configuration Reference

Key Sections

compute

Defines VM resources (CPUs, memory, disk, ports)

metadata

Simulator information (name, description, license, etc.)

services

Docker Compose service definitions and health checks

listeners

Database monitoring configuration for tracking mutations

Volume Mounting

Volumes allow you to share data between the VM and containers. Common use cases:
listeners:
  db:
    # ... other db config
    volumes:
      # Share database signal files
      - /home/plato/db_signals:/tmp/postgres-signals

      # Mount config files
      - /home/plato/config:/app/config:ro  # :ro for read-only

      # Share data directories
      - /home/plato/data:/var/lib/data
Format: <vm_path>:<container_path>[:mode]
  • vm_path: Path on the VM filesystem
  • container_path: Path inside the container
  • mode (optional): ro for read-only, rw for read-write (default)

Dataset Configuration

Each dataset can have its own configuration. Use YAML anchors (& and *) to share configuration across datasets:
datasets:
  base: &base
    compute: &base_compute
      cpus: 1
      memory: 3072
      disk: 10240
      # ... more config

  test:
    <<: *base  # Inherits all from base
    compute:
      <<: *base_compute
      memory: 4096  # Override specific values
    metadata:
      name: BaseRow Test  # Override test dataset name

  production:
    <<: *base
    compute:
      <<: *base_compute
      cpus: 2          # More CPU for production
      memory: 8192     # More memory for production

Next Steps