Deployment options
There are two ways to run marimohub. Both run the same server; they differ only in how you select and wire your backends.
1. Config-driven (the common case)
Set MARIMOHUB_* environment variables and let the server select and wire adapters for you. Pick a backend per port with the *_BACKEND selectors, then set that backend's options:
# --- Storage ---
MARIMOHUB_STORAGE_BACKEND=s3
MARIMOHUB_STORAGE_S3_BUCKET=my-bucket
# …
# --- Compute ---
MARIMOHUB_COMPUTE_BACKEND=kubernetes
MARIMOHUB_COMPUTE_KUBERNETES_NAMESPACE=marimohub
# …
# --- Auth ---
MARIMOHUB_AUTH_BACKEND=oidc
MARIMOHUB_AUTH_OIDC_ISSUER=https://issuer.example.com
# …
# --- Options ---
MARIMOHUB_PERSIST_WORKSPACE=source- Everything is documented in Configuration.
- Best for standard deployments (Docker, Podman, Kubernetes).
The container image is the primary distribution. Each GitHub release also attaches standalone server binaries for Linux hosts without Node: marimohub-linux-x64 and marimohub-linux-arm64, each with a .sha256 checksum file. They omit the catalog recovery command; run it from the container image. The binary reads the same MARIMOHUB_* variables. It listens on all network interfaces unless you set MARIMOHUB_BIND_HOST, for example to 127.0.0.1 behind a reverse proxy on the same host. On first start it unpacks its bundled files to $XDG_CACHE_HOME/marimohub-sea/<build-id> (default ~/.cache/marimohub-sea/<build-id>); set MARIMOHUB_SEA_CACHE_DIR to use a different directory. The unpacked files are executed, so the binary refuses a cache directory that is a symlink, not owned by the current user, or reachable through a directory another user can write to, including sticky directories such as /tmp.
Each release unpacks into its own <build-id> directory of roughly 75 MB, and earlier ones are left in place, because another instance may still be running from one. Delete the directories you no longer need after an upgrade.
The example below is a throwaway configuration that keeps all state in memory. For a real deployment use the durable variables from the .env above.
arch=$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/')
base=https://github.com/marimo-team/marimohub/releases/latest/download
curl -fsSLO "$base/marimohub-linux-$arch"
curl -fsSLO "$base/marimohub-linux-$arch.sha256"
sha256sum -c "marimohub-linux-$arch.sha256"
chmod +x "marimohub-linux-$arch"
"./marimohub-linux-$arch" --version
export MARIMOHUB_STORAGE_BACKEND=memory
export MARIMOHUB_ALLOW_EPHEMERAL_STORAGE=true
export MARIMOHUB_COMPUTE_BACKEND=none
export MARIMOHUB_AUTH_BACKEND=dev
"./marimohub-linux-$arch"2. SDK / library composition (the complex case)
Import the adapters you want and construct createApi(deps) by hand. Use this when you need a custom adapter, custom routes, or a non-standard runtime. See examples/library-composition.
import { createApi } from '@marimo-hub/api';
import { createServices } from '@marimo-hub/core';
import { S3Storage } from '@marimo-hub/storage-s3';
import { ModalCompute } from '@marimo-hub/compute-modal';
const bucket = new S3Storage({ bucket: 'my-bucket' /* … */ });
const app = createApi({
services: createServices(bucket),
bucket,
compute: new ModalCompute({
/* … */
}),
authenticator: new MyAuthenticator(),
sandboxBucket: {
name: 'my-bucket',
endpoint: 'https://…',
credentials: {
/* … */
},
},
sandboxHostname: 'hub.example.com',
});Generate this for your backends
The configurator on Getting started has a Library tab that emits this wiring for whatever storage / compute / auth you pick — copy it instead of writing it by hand.
- You own adapter selection and lifecycle.
- Required
ApiDeps:services,bucket,compute,authenticator,sandboxBucket,sandboxHostname. Commonly set:sandboxWorkdir,persistWorkspace,authRoutes,maxConcurrentSessionsPerUser,allowedOrigins,defaultRole. - The Cloudflare Workers entrypoint (
examples/cloudflare-worker) is a library composition because R2 and Containers are platform bindings, not env credentials.
Which one?
| Use config-driven if… | Use the SDK if… |
|---|---|
| Standard Docker/k8s deploy | You need a custom storage/compute/auth adapter |
| All adapters are built-in | You're on a runtime with platform bindings (CF) |
| You want the prebuilt image | You want to add routes or embed in another app |