Skip to main content
The Flyte sandbox packages the entire Flyte stack — FlyteAdmin, FlytePropeller, DataCatalog, FlyteConsole, MinIO (S3-compatible object store), and PostgreSQL — into a single Docker container that runs a lightweight k3s Kubernetes cluster internally.
The sandbox is not suitable for production workloads. It uses in-container storage and has no HA, backups, or authentication by default. For a production deployment, see the AWS, GCP, or single binary guides.

Prerequisites

Install the following tools before starting:
# Install flytectl via curl (Linux / macOS)
curl -sL https://ctl.flyte.org/install | sudo bash -s -- -b /usr/local/bin

# Or via Homebrew on macOS
brew install flyteorg/homebrew-tap/flytectl
The flytectl demo command uses Docker APIs internally. The sandbox image can also be run directly with any OCI-compatible runtime by executing the container image without flytectl.

Start the sandbox

flytectl demo start
This command pulls the sandbox Docker image, starts the container, waits for k3s and all Flyte services to become healthy, and prints connection information:
👨‍💻 Flyte is ready! Flyte UI is available at http://localhost:30080/console 🚀 🚀 🎉
❇️ Run the following command to export sandbox environment variables for accessing flytectl
    export FLYTECTL_CONFIG=~/.flyte/config-sandbox.yaml
🐋 Flyte sandbox ships with a Docker registry. Tag and push custom workflow images to localhost:30000
📂 The Minio API is hosted on localhost:30002. Use http://localhost:30080/minio/login for Minio console

What gets deployed

ServiceInternal portExposed host port
FlyteConsole + FlyteAdmin (HTTP)808830080
FlyteAdmin (gRPC)808930080
Docker registry500030000
PostgreSQL543230001
MinIO API (S3-compatible)900030002
Within the sandbox container, k3s orchestrates all Flyte task pods. Task images are pulled from the in-container registry at localhost:30000.

Access FlyteConsole

Open http://localhost:30080/console in your browser. No authentication is required in sandbox mode.

Configure flytectl

Export the sandbox configuration file so flytectl and pyflyte connect to the local cluster:
export FLYTECTL_CONFIG=~/.flyte/config-sandbox.yaml
The generated config-sandbox.yaml contains:
admin:
  # For GRPC endpoints you might want to use dns:///flyte.myexample.com
  endpoint: localhost:30080
  authType: Pkce
  insecure: true
  console:
    endpoint: http://localhost:30080
logger:
  show-source: true
level: 0

Run your first workflow

1

Clone flytesnacks

git clone https://github.com/flyteorg/flytesnacks
cd flytesnacks/examples/basics
2

Run the hello world example

pyflyte run --remote basics/hello_world.py hello_world_wf
3

Open the console

Navigate to http://localhost:30080/console to watch the execution.

Push custom images

The sandbox includes a Docker registry on port 30000. Build and push your workflow image:
docker build -t localhost:30000/my-workflow:latest .
docker push localhost:30000/my-workflow:latest
Then reference the image in your @task decorator:
import flytekit

@flytekit.task(container_image="localhost:30000/my-workflow:latest")
def my_task() -> str:
    return "hello"

Inspect sandbox internals

# View all Flyte pods inside the sandbox
export KUBECONFIG=~/.flyte/sandbox/kubeconfig
kubectl get pods -n flyte

# Stream FlyteAdmin logs
kubectl logs -n flyte deployment/flyteadmin -f

# Connect to the in-sandbox PostgreSQL
psql -h localhost -p 30001 -U postgres -d flyte

Stop and tear down

# Stop the sandbox container (preserves data)
flytectl demo teardown

# Remove all sandbox data and volumes
flytectl demo teardown --volume
Run flytectl demo start --source . to mount your local project directory into the sandbox container, which makes iterating on local code faster without pushing images.

Build docs developers (and LLMs) love