Skip to main content

Managing Simulators

Learn how to clone simulators, manage configurations, and work with the Plato Hub ecosystem.

Cloning Simulators

Using the CLI

The easiest way to clone a simulator is through the Plato Hub CLI:
uv run plato hub clone {sim-name}
Example:
uv run plato hub clone espocrm
cd espocrm
This command:
  1. Clones the simulator repository from Plato Hub
  2. Sets up .plato-hub.json configuration
  3. Configures git remotes for the simulator

Browsing Available Simulators

Launch the interactive CLI to browse simulators:
uv run plato hub
Select “Launch Environment”, then choose “From Existing Simulator” to see the simulator browser: Simulator Browser Features:
  • Filter - Search for simulators by name
  • Arrow keys - Navigate the list
  • Enter - Select a simulator to view artifacts
After selecting a simulator, you can:
  • View all available snapshots (artifacts)
  • See version history and creation dates
  • Launch a VM from any snapshot
Artifact Selector

Simulator Structure

A typical Plato simulator has this structure:
simulator-name/
├── plato-config.yml          # Main configuration file
├── base/                     # Base dataset directory
│   ├── docker-compose.yml    # Docker services definition
│   └── flows.yaml            # Action flows (optional)
├── .plato-hub.json           # Hub metadata (auto-generated)
└── README.md                 # Simulator documentation

Key Files

plato-config.yml

Required - Defines VM resources, services, datasets, and database listeners

docker-compose.yml

Required - Defines your application services (web, database, workers, etc.)

flows.yaml

Optional - Defines automated action flows for the simulator

.plato-hub.json

Auto-generated - Links local directory to Hub repository

Configuration File

The plato-config.yml file is the heart of your simulator configuration.

Complete Example

plato-config.yml
service: espocrm  # Service name for this simulator

datasets:
  base: &base  # YAML anchor for reusing configuration
    compute: &base_compute
      cpus: 1                    # Number of vCPUs (1-8)
      memory: 3072               # RAM in MB (512-16384)
      disk: 10240                # Disk 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
      name: EspoCRM
      description: EspoCRM Customer Relationship Management
      source_code_url: https://github.com/espocrm/espocrm
      start_url: https://sims.plato.so  # Public URL for simulator
      license: GPL-3.0
      variables:                  # Login credentials
        - name: username
          value: admin
        - name: password
          value: password
      flows_path: base/flows.yaml

    services: &base_services
      main_app:                   # Service identifier
        type: docker-compose
        file: base/docker-compose.yml
        healthy_wait_timeout: 600
        required_healthy_containers:
          - espocrm               # Container names from compose file
          - db

    listeners: &base_listeners
      db:                         # Listener identifier
        type: db
        db_type: postgresql
        db_host: 127.0.0.1
        db_port: 5432
        db_user: espocrm
        db_password: espocrm
        db_database: espocrm
        volumes:
          - /home/plato/db_signals:/tmp/postgres-signals

Configuration Sections

Service

service: myapp  # Service name used for snapshots and deployment
The service name identifies your simulator across Plato Hub.

Compute Resources

compute:
  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               # Application port
  plato_messaging_port: 7000 # Port for Plato worker (keep unless conflicting with an app port)

Metadata

metadata:
  name: My Simulator           # Display name
  description: Description     # Brief description
  source_code_url: https://... # Repository URL
  start_url: https://sims.plato.so  # Access URL
  license: MIT                 # License type
  variables:                   # Login credentials
    - name: username
      value: admin
    - name: password
      value: pass123
  flows_path: base/flows.yaml  # Path to flows file

Services

services:
  main_app:                      # Service identifier
    type: docker-compose
    file: base/docker-compose.yml
    healthy_wait_timeout: 600    # Seconds to wait for health
    required_healthy_containers: # Containers that must be healthy
      - web
      - db
      - worker

Listeners

listeners:
  db:                           # Listener identifier
    type: db                    # Listener type
    db_type: postgresql         # Database type
    db_host: 127.0.0.1          # Database host
    db_port: 5432               # Database port
    db_user: appuser            # Database user
    db_password: password       # Database password
    db_database: appdb          # Database name
    volumes:                    # Volume mounts
      - /home/plato/db_signals:/tmp/postgres-signals

Multiple Datasets

Define multiple datasets for different environments:
service: myapp

datasets:
  base: &base
    compute: &base_compute
      cpus: 1
      memory: 2048
    metadata: &base_metadata
      name: MyApp Base
      start_url: https://sims.plato.so
      variables:
        - name: username
          value: user
        - name: password
          value: pass
    # ... other config

  test:
    <<: *base                # Inherit all from base
    compute:
      <<: *base_compute
      cpus: 2                # Override for test
      memory: 4096
    metadata:
      <<: *base_metadata
      name: MyApp Test
      variables:
        - name: username
          value: test_user
        - name: password
          value: test_pass

Working with Snapshots

Snapshots (also called artifacts) are saved VM states that can be reused.

Creating Snapshots

Create a snapshot through the Hub CLI after starting services and worker:
  1. Launch VM and start services
  2. Start Plato worker
  3. Test the simulator
  4. Select “Snapshot VM” from the actions menu
The snapshot captures:
  • Entire VM disk state
  • All running services
  • Database data
  • Application state

Using Snapshots

Launch a VM from an existing snapshot:
  1. Open Hub CLI: uv run plato hub
  2. Select “Launch Environment”
  3. Choose “From Existing Simulator”
  4. Browse simulators and select one
  5. Choose an artifact/snapshot
  6. VM launches with saved state
This allows you to:
  • Resume development from previous state
  • Deploy specific versions
  • Test different configurations
  • Share working environments

Git Integration

Plato Hub includes built-in git integration for simulator repositories.

Cloning with Credentials

The Hub CLI handles authentication automatically:
uv run plato hub clone simulator-name
No manual credential setup required!

Manual Cloning

If you need to clone manually, use the SDK to get credentials:
from plato.sandbox_sdk import PlatoSandboxClient
import os

client = PlatoSandboxClient(api_key=os.environ['PLATO_API_KEY'])
creds = client.get_gitea_credentials()

clone_url = f"https://{creds['username']}:{creds['password']}@hub.plato.so/{creds['org_name']}/simulator-name"
Then clone normally:
git clone {clone_url}

Repository Structure

Hub repositories follow standard git practices:
  • main branch - Production-ready code
  • Feature branches - Development work
  • Tags - Version releases

Best Practices

Configuration Management

Use YAML Anchors

Share configuration across datasets with & and * syntax

Environment Variables

Use ${VAR} syntax for sensitive data like passwords

Login Credentials

Always define username/password in variables section

Health Checks

Configure proper health checks in docker-compose.yml

Development Workflow

  1. Clone simulator from Hub
  2. Test locally with Hub CLI
  3. Make changes and commit to feature branch
  4. Create snapshot when working
  5. Share snapshot ID with team
  6. Merge to main when ready

Resource Allocation

Choose resources based on your simulator needs:
Simulator TypevCPUsMemory (MB)Disk (MB)
Simple web app11024-204810240
Database app1-22048-409620480
Complex system2-44096-819251200

Troubleshooting

  1. Check your API key in .env file
  2. Verify API key at plato.so/settings
  3. Ensure PLATO_BASE_URL=https://plato.so/api is set
  • File must be named exactly plato-config.yml
  • Check YAML syntax with a validator
  • Ensure proper indentation (spaces, not tabs)
  • Verify service field is at root level
  • Verify that the app_port in plato-config.yml matches the frontend app port from your docker-compose.yml
  • Ensure the app is running inside the VM
  • SSH into the VM and test with curl: curl localhost:<app_port>
  • Check Docker container logs: docker compose logs -f
  • Snapshots may take a few minutes to process
  • Refresh the artifact list
  • Check the snapshot completed successfully
  • Verify you’re looking at the correct simulator

Next Steps

Use the Hub CLI interactive browser to explore available simulators and their snapshots. It’s the easiest way to discover what’s available!