Deploy marimo notebooks to Kubernetes.
# With uv (recommended)
uv tool install kubectl-marimo
# With uvx (no install)
uvx kubectl-marimo edit notebook.py
# With pip
pip install kubectl-marimo# Edit a notebook interactively
kubectl marimo edit notebook.py
# Run as read-only app
kubectl marimo run notebook.py
# With cloud storage
kubectl marimo edit --source=cw://my-bucket/data notebook.py
# Sync changes back
kubectl marimo sync notebook.py
# Delete deployment
kubectl marimo delete notebook.py
# List active deployments
kubectl marimo statusCreate or edit notebooks in the cluster (interactive mode).
kubectl marimo edit [OPTIONS] [FILE]Options:
-n, --namespace- Kubernetes namespace (default: "default")--source- Data source URI (cw://, sshfs://, rsync://)--dry-run- Print YAML without applying-f, --force- Overwrite without prompting
Examples:
# Edit existing notebook
kubectl marimo edit notebook.py
# Edit with S3 data mounted
kubectl marimo edit --source=cw://bucket/data notebook.py
# Edit in staging namespace
kubectl marimo edit -n staging notebook.pyRun a notebook as a read-only application.
kubectl marimo run [OPTIONS] FILEOptions: Same as edit
Examples:
# Run notebook as app
kubectl marimo run dashboard.py
# Run with data source
kubectl marimo run --source=cw://bucket/reports dashboard.pyPull changes from pod back to local file.
kubectl marimo sync [OPTIONS] FILEOptions:
-n, --namespace- Kubernetes namespace-f, --force- Overwrite local file without prompting
Delete notebook deployment from cluster.
kubectl marimo delete [OPTIONS] FILEOptions:
-n, --namespace- Kubernetes namespace--delete-pvc- Also delete PersistentVolumeClaim (PVC is preserved by default)--no-sync- Delete without syncing changes back
List active notebook deployments.
kubectl marimo status [DIRECTORY]Configure deployments via frontmatter in your notebook.
---
title: my-analysis
image: ghcr.io/marimo-team/marimo:latest
storage: 5Gi
env:
DEBUG: "true"
API_KEY:
secret: my-secret
key: api-key
mounts:
- cw://my-bucket/data
---# /// script
# dependencies = ["marimo", "pandas"]
# ///
# [tool.marimo.k8s]
# image = "ghcr.io/marimo-team/marimo:latest"
# storage = "5Gi"
#
# [tool.marimo.k8s.env]
# DEBUG = "true"| Field | Description | Default |
|---|---|---|
| title | Resource name | filename |
| image | Container image | ghcr.io/marimo-team/marimo:latest |
| port | Server port | 2718 |
| storage | PVC size | none (ephemeral) |
| auth | Set to "none" to disable | token auth |
| env | Environment variables | none |
| mounts | Data source URIs | none |
Inline values:
env:
DEBUG: "true"
LOG_LEVEL: "info"From Kubernetes secrets:
env:
API_KEY:
secret: my-secret
key: api-key
DB_PASSWORD:
secret: db-credentials
key: password| Scheme | Description | Example |
|---|---|---|
| cw:// | CoreWeave Object Storage | cw://bucket/path |
| sshfs:// | SSH filesystem mount | sshfs://user@host:/path |
| rsync:// | Local directory sync | rsync://./data:/notebooks |
Local rsync:// URIs sync a directory to the pod via kubectl cp. Remote URIs (rsync://user@host:/path) create a sidecar for continuous sync.
- Kubernetes cluster with marimo-operator installed
- kubectl configured to access the cluster