Fork this, deploy it, get your own interactive marimo notebook running in the cloud on Aiven Runtimes. No database, no extra services required, and every visitor gets their own private, editable copy of the notebook.
The Dockerfile doesn't run a marimo server. Instead it exports
notebook.py to a self-contained WASM build (marimo export html-wasm --mode edit) at image-build time, and serves the resulting static
files. Each visitor's browser then runs its own Pyodide
(Python-in-WebAssembly) instance locally, meaning:
- No shared server-side kernel, so visitors can't see or overwrite each other's edits everyone gets an independent copy of the notebook.
- No arbitrary code ever runs on the container itself, since all execution happens client-side in the visitor's own browser sandbox. There's no token/password to manage as a result.
- The container serves tens of MB of Pyodide/WASM assets on first load which can be a little slow (nginx gzips these in flight but it's still a real download).
- Pyodide supports most but not all PyPI packages (see the Pyodide package list),
- Nothing a visitor edits is persisted anywhere so closing the tab
loses their changes -- see
examples/shared-server/for the opposite trade-off, where edits are real and shared, at the cost of isolation.
notebook.py— a placeholder marimo notebook. Replace it with your own.temperature_converter.py— a second, unrelated notebook, here to demo Multiple notebooks below rather than to be useful on its own. Delete it if you only want the one notebook.export_notebooks.py— finds every notebook in this directory and exports each to WASM at build time; see below.Dockerfile— runsexport_notebooks.pyat build time, then a second stage serves the static output with nginx.nginx.conf— gzip and long-lived caching for the content-hashed asset files, so the (large) first load is smaller and repeat visits are near-instant.requirements.txt— justmarimo(only needed to run the export).
That's the whole template. examples/ has more involved variants (see
below).
Starting a marimo notebook from scratch: edit notebook.py directly,
or run marimo edit notebook.py locally to build it interactively.
Bringing an existing Jupyter/IPython notebook: marimo can convert a
.ipynb file straight to marimo's format:
pip install marimo
marimo convert your_notebook.ipynb -o notebook.pyMarimo's execution model is reactive (cells rerun automatically based on
what they depend on), which differs from Jupyter's run-cells-in-any-order
model — the conversion handles the mechanical part, but notebooks that
mutate the same variable across multiple cells may need small tweaks
afterward. marimo edit notebook.py locally is the fastest way to check.
temperature_converter.py is here to demonstrate this: drop another
.py notebook into this directory and it's picked up automatically —
export_notebooks.py finds every file that defines marimo.App(...),
no Dockerfile edit needed.
marimo doesn't have a built-in way to navigate between separate WASM
exports — each one is a fully self-contained Pyodide bundle with no
shared runtime or file browser (that's a server-only feature of
marimo edit). So: with exactly one notebook, this deploys exactly as
before, straight at /. With more than one, each gets its own
subdirectory (e.g. /second-notebook/) and the site root becomes a
plain, static links page — the same pattern marimo's own multi-notebook
deployment guide recommends, not a custom router.
If a notebook you drop in imports a local module of its own, marimo
bundles it into a wheel and references it with a relative URL resolved
in the browser rather than at build time — nested a directory deep,
that resolution has been observed to land one level too high (a real
issue hit while building an earlier version of this template, no
longer part of it). nginx.conf's /public/ location and
export_notebooks.py's wheel-copying-to-root step both guard against
that if it comes up for you.
As a normal server-backed notebook, for fast iteration while you build:
pip install -r requirements.txt
marimo edit notebook.pyTo preview exactly what visitors will get (the WASM build):
marimo export html-wasm notebook.py -o /tmp/site --mode edit
python -m http.server 8080 --directory /tmp/site
# open http://localhost:8080With more than one notebook in the directory, run export_notebooks.py
instead — it reproduces exactly what the Dockerfile does, including the
links page:
pip install marimo
python export_notebooks.py /tmp/site
python -m http.server 8080 --directory /tmp/siteAiven Runtimes (Aiven Applications) builds and runs this Dockerfile
straight from your fork:
- Push your fork to GitHub (public, or connect the account under Aiven Console → your project → Integrations → GitHub if private).
- Create the application service — plan
free-10-256is enough for a single notebook — pointing at your repo/branch, port8080.
No environment variables, database, or other service integration needed for this template.
examples/shared-server/— the opposite trade-off from this root template: a realmarimo editserver instead of a WASM export, so saving is native (Ctrl+Swrites straight tonotebook.py) and changes are genuinely shared between everyone connected, at the cost of per-visitor isolation and a sandbox -- anyone with the password can run arbitrary code in that container. See its README before deploying it anywhere real.