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
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
| Service | Internal port | Exposed host port |
|---|
| FlyteConsole + FlyteAdmin (HTTP) | 8088 | 30080 |
| FlyteAdmin (gRPC) | 8089 | 30080 |
| Docker registry | 5000 | 30000 |
| PostgreSQL | 5432 | 30001 |
| MinIO API (S3-compatible) | 9000 | 30002 |
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.
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
Clone flytesnacks
git clone https://github.com/flyteorg/flytesnacks
cd flytesnacks/examples/basics
Run the hello world example
pyflyte run --remote basics/hello_world.py hello_world_wf
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.