Skip to content

marimohubSelf-hostable marimo notebooks

A provider-agnostic platform to store, manage, and run marimo notebooks. No database β€” bring your own storage, compute, and identity.

Configure your deployment ​

Pick your storage, compute, and auth backends to generate ready-to-paste config (.env, Helm, or Docker Compose) and the equivalent library wiring code β€” live, no install required.

Any S3-compatible store: CoreWeave CAIOS, AWS S3, MinIO, Tigris, Ceph, or Cloudflare R2 via its S3 endpoint. Point `*_S3_ENDPOINT` at the provider.

Modal sandboxes.

App-native OpenID Connect (the production backend).

No managed AI. The marimo assistant still works if a user supplies their own key in marimo settings.

Options

Which sandbox working-dir files survive a session (source | workspace). `source` persists only the source files (notebook.py + pyproject.toml); `workspace` also captures runtime files (e.g. generated data) into the notebook workspace on teardown and restores them on the next session.

Container image with marimo + uv + python, or a comma-separated list of such images: the first is the default and the rest are selectable per notebook as base images. Required by the `modal` backend; recommended for `coreweave`.

# --- Storage ---
MARIMOHUB_STORAGE_BACKEND=s3
MARIMOHUB_STORAGE_S3_BUCKET=orgname-marimohub
MARIMOHUB_STORAGE_S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
MARIMOHUB_STORAGE_S3_REGION=us-east-1
MARIMOHUB_STORAGE_S3_ACCESS_KEY_ID=  # secret
MARIMOHUB_STORAGE_S3_SECRET_ACCESS_KEY=  # secret
MARIMOHUB_STORAGE_S3_FORCE_PATH_STYLE=true

# --- Compute ---
MARIMOHUB_COMPUTE_BACKEND=modal
MARIMOHUB_COMPUTE_IMAGE=ghcr.io/orgname/marimo-sandbox:latest
MARIMOHUB_COMPUTE_IDLE_TIMEOUT=20m
MARIMOHUB_COMPUTE_SANDBOX_HOSTNAME=hub.example.com
MARIMOHUB_COMPUTE_WORKDIR=/workspace
MARIMOHUB_COMPUTE_ASSET_URL=https://cdn.jsdelivr.net/npm/@marimo-team/frontend@{version}/dist
MARIMOHUB_COMPUTE_MODAL_TOKEN_ID=  # required, secret
MARIMOHUB_COMPUTE_MODAL_TOKEN_SECRET=  # required, secret
MARIMOHUB_COMPUTE_MODAL_APP_NAME=marimohub

# --- Auth ---
MARIMOHUB_AUTH_BACKEND=oidc
MARIMOHUB_AUTH_OIDC_ISSUER=https://accounts.example.com
MARIMOHUB_AUTH_OIDC_CLIENT_ID=  # required
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=  # required, secret
MARIMOHUB_AUTH_OIDC_REDIRECT_URI=https://hub.example.com/api/auth/callback
MARIMOHUB_AUTH_OIDC_AUDIENCE=
MARIMOHUB_AUTH_SESSION_SECRET=  # required, secret
MARIMOHUB_AUTH_ALLOWED_EMAIL_DOMAINS=example.com,example.org

# --- Managed AI ---
MARIMOHUB_AI_BACKEND=none

# --- Options ---
MARIMOHUB_PERSIST_WORKSPACE=source

Setup

How to provision and connect each backend you picked above.

StorageS3 / S3-compatible Full docs β†’

Works with any S3-compatible store (AWS S3, MinIO, Tigris, Ceph, CoreWeave CAIOS, or Cloudflare R2 via its S3 endpoint).

  1. Create a bucket for marimohub.
  2. Get credentials with read/write on that bucket (an access key + secret), or rely on the instance/SDK default credential chain on AWS.
  3. Set the env:
MARIMOHUB_STORAGE_BACKEND=s3
MARIMOHUB_STORAGE_S3_BUCKET=orgname-marimohub
MARIMOHUB_STORAGE_S3_ENDPOINT=https://s3.us-east-1.amazonaws.com  # omit for AWS
MARIMOHUB_STORAGE_S3_REGION=us-east-1
MARIMOHUB_STORAGE_S3_ACCESS_KEY_ID=…       # secret β€” or use the SDK default chain
MARIMOHUB_STORAGE_S3_SECRET_ACCESS_KEY=…   # secret

Your store must support conditional writes

marimohub uses S3 If-Match to update notebooks safely and refuses to start on a store that doesn't honor it. AWS S3, R2, Tigris, CoreWeave CAIOS, and recent MinIO all qualify; very old MinIO/Ceph builds may not.

MinIO / Ceph need path-style addressing

Set MARIMOHUB_STORAGE_S3_FORCE_PATH_STYLE=true for MinIO and Ceph, or requests to the bucket will fail to resolve.

CoreWeave CAIOS

CAIOS (CoreWeave AI Object Storage) is CoreWeave's S3-compatible store and the storage half of the CKS deployment. Use the s3 backend and point the endpoint at CAIOS:

MARIMOHUB_STORAGE_BACKEND=s3
MARIMOHUB_STORAGE_S3_BUCKET=orgname-marimohub
MARIMOHUB_STORAGE_S3_ENDPOINT=https://cwobject.com
MARIMOHUB_STORAGE_S3_ACCESS_KEY_ID=…         # CAIOS access key (secret)
MARIMOHUB_STORAGE_S3_SECRET_ACCESS_KEY=…     # CAIOS secret key (secret)
ComputeModal Full docs β†’
  1. Create a Modal account.
  2. In the dashboard, open Settings β†’ API Tokens and create a token (you get a token id and secret).
  3. Build/publish a sandbox image (marimo + uv + python).
  4. Set the env:
MARIMOHUB_COMPUTE_BACKEND=modal
MARIMOHUB_COMPUTE_MODAL_TOKEN_ID=…              # secret
MARIMOHUB_COMPUTE_MODAL_TOKEN_SECRET=…          # secret
MARIMOHUB_COMPUTE_IMAGE=ghcr.io/orgname/marimo-sandbox:latest
MARIMOHUB_COMPUTE_IDLE_TIMEOUT=20m              # auto-stop idle kernels to control spend

No infrastructure to run

Modal is fully serverless β€” nothing to provision or scale, and you pay only for running kernels. The easiest path if you don't already run a cluster.

Cold starts & shared workspaces

A freshly-started kernel can take a few seconds to boot; a warm sandbox image (Sandbox image) helps. If multiple apps share one Modal workspace, set MARIMOHUB_COMPUTE_MODAL_APP_NAME so marimohub only reaps its own sandboxes.

AuthOIDC Full docs β†’

App-native OpenID Connect β€” the production backend. marimohub discovers the provider's endpoints automatically from the issuer's /.well-known/openid-configuration, so you only supply an issuer, client credentials, and a redirect URI.

MARIMOHUB_AUTH_BACKEND=oidc
MARIMOHUB_AUTH_OIDC_ISSUER=https://accounts.example.com
MARIMOHUB_AUTH_OIDC_CLIENT_ID=…
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=…
MARIMOHUB_AUTH_OIDC_REDIRECT_URI=https://hub.example.com/api/auth/callback
MARIMOHUB_AUTH_SESSION_SECRET=…            # signs the session cookie (HS256, β‰₯32 bytes)
MARIMOHUB_AUTH_ALLOWED_EMAIL_DOMAINS=example.com  # REQUIRED allowlist (verified email); `*` allows all
# MARIMOHUB_AUTH_OIDC_AUDIENCE=…           # optional: expected ID-token audience (the client id is enforced anyway)

The redirect URI is always https://<your-host>/api/auth/callback. Register it with your provider exactly as you set it here, or login fails with a redirect_uri_mismatch error. ALLOWED_EMAIL_DOMAINS is required β€” marimohub fails closed rather than admitting every account the IdP authenticates; list your domains or set * to allow all.

Generate a session secret with openssl rand -base64 32.

Google

  1. In the Google Cloud Console, open APIs & Services β†’ Credentials.
  2. Create Credentials β†’ OAuth client ID, application type Web application.
  3. Under Authorized redirect URIs, add https://hub.example.com/api/auth/callback (and http://localhost:3000/api/auth/callback for local testing).
  4. Copy the Client ID and Client secret.
MARIMOHUB_AUTH_OIDC_ISSUER=https://accounts.google.com
MARIMOHUB_AUTH_OIDC_CLIENT_ID=…apps.googleusercontent.com
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=…
MARIMOHUB_AUTH_ALLOWED_EMAIL_DOMAINS=example.com   # a single domain is also sent to Google as the `hd` hint

See Google's OpenID Connect docs.

Microsoft Entra ID

  1. In the Entra admin center (or Azure Portal), go to App registrations β†’ New registration.
  2. Set a Web redirect URI of https://hub.example.com/api/auth/callback.
  3. From Overview, copy the Application (client) ID and Directory (tenant) ID; under Certificates & secrets, create a client secret.
# tenant-scoped issuer (use `organizations` or `common` for multi-tenant)
MARIMOHUB_AUTH_OIDC_ISSUER=https://login.microsoftonline.com/<tenant-id>/v2.0
MARIMOHUB_AUTH_OIDC_CLIENT_ID=<application-client-id>
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=…

See Microsoft's OIDC docs.

Okta

  1. In the Okta Admin Console, open Applications β†’ Create App Integration.
  2. Choose OIDC - OpenID Connect and Web Application.
  3. Add https://hub.example.com/api/auth/callback as a Sign-in redirect URI.
  4. Copy the Client ID and Client secret from the app's General tab.
MARIMOHUB_AUTH_OIDC_ISSUER=https://<your-org>.okta.com
MARIMOHUB_AUTH_OIDC_CLIENT_ID=…
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=…

If you use an Okta authorization server, the issuer is https://<your-org>.okta.com/oauth2/<server-id>. See Okta's OIDC docs.

Auth0

  1. In the Auth0 Dashboard, open Applications β†’ Create Application and pick Regular Web Application.
  2. Under Settings β†’ Allowed Callback URLs, add https://hub.example.com/api/auth/callback.
  3. Copy the Domain, Client ID, and Client Secret from Settings.
# note the trailing slash on the issuer
MARIMOHUB_AUTH_OIDC_ISSUER=https://<tenant>.auth0.com/
MARIMOHUB_AUTH_OIDC_CLIENT_ID=…
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=…

See Auth0's OIDC docs.

Managed AIOff Full docs β†’

Managed AI is off β€” the default:

MARIMOHUB_AI_BACKEND=none

The marimo AI assistant still works if a user supplies their own API key in marimo's settings. Turn on managed AI to provide a key for everyone.

Provider-agnostic. Deploy anywhere.