Por qué un notebook reactivo en tu propio servidor
En Jupyter, el orden de ejecución depende de tus clics: una variable redefinida más abajo, una celda olvidada, y los resultados mostrados ya no corresponden al código. El archivo .ipynb, un JSON cargado de salidas, se revisa mal y genera conflictos en Git en cada ejecución.
marimo analiza las dependencias entre celdas. Cuando una celda cambia, se recalculan todas las que dependen de ella, y solo esas. El notebook es un archivo de Python normal: git diff lo lee y python notebook.py lo ejecuta.
Alojarlo en tu VPS significa mantener los datos en un servidor que controlas, dar a todo el equipo el mismo entorno desde el navegador y elegir la memoria y el procesador que necesitan tus cálculos.
Lo que aporta marimo
- Ejecución reactiva — una celda modificada recalcula las que dependen de ella, sin estado oculto.
- Archivos .py — notebooks legibles, versionables en Git y ejecutables como scripts.
- Elementos de interfaz — deslizadores, menús, tablas y gráficos ligados a variables de Python.
- Del notebook a la aplicación —
marimo runsirve un notebook en solo lectura, con el código oculto. - Migración desde Jupyter —
marimo converttransforma un archivo .ipynb. - Imagen oficial «data» — pandas, polars, numpy y altair preinstalados.
marimo, Jupyter y code-server
Desplace la tabla
| marimo | JupyterLab | code-server | |
|---|---|---|---|
| Formato del notebook | Archivo .py | Archivo .ipynb (JSON) | Archivos del proyecto |
| Orden de ejecución | Reactivo, por dependencias | Manual, con cada clic | Según el script que lances |
| Revisión en Git | Diff de Python legible | Diff de JSON con salidas | Diff del código |
| Publicar como aplicación | Sí, `marimo run` | Extensiones de terceros | No |
| Uso ideal | Análisis y herramientas internas en Python | Gran variedad de kernels | Desarrollo de software completo |
Requisitos previos
Un VPS Ubuntu 24.04 con 2 GB de RAM y 20 GB de disco (prevé más memoria si cargas conjuntos de datos grandes), Docker y el plugin Compose instalados, y acceso root por SSH. Un subdominio (por ejemplo notebooks.example.com) que apunte al VPS es útil para el acceso HTTPS, pero no imprescindible: un túnel SSH basta si trabajas solo.
Instalar marimo con Docker Compose
Preparar el directorio y la contraseña
Crea el directorio de la aplicación y un archivo
.envcon la contraseña del editor.mkdir -p /opt/marimo && cd /opt/marimo echo "ADMIN_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=')" > .env chmod 600 .envEscribir el archivo compose
Crea
compose.yaml. La imagen oficial «data» ya contiene las librerías de análisis. El puerto solo se publica en la interfaz de loopback y la contraseña se transmite mediante un archivo en lugar de la línea de comandos.services: marimo: image: ghcr.io/marimo-team/marimo:0.25.2-data restart: unless-stopped ports: - "127.0.0.1:2718:8080" environment: ADMIN_PASSWORD: ${ADMIN_PASSWORD:?ADMIN_PASSWORD requis} command: - sh - -c - umask 077 && printf %s "$$ADMIN_PASSWORD" > /tmp/marimo-password && exec marimo edit --headless --skip-update-check --host 0.0.0.0 -p 8080 --token-password-file /tmp/marimo-password /app volumes: - marimo-data:/app volumes: marimo-data: {}Arrancar y comprobar
Inicia la pila y consulta la sonda de salud: debe responder 200.
docker compose up -d docker compose ps curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:2718/healthPublicar el editor por HTTPS
marimo se comunica con el navegador por WebSocket: el vhost de nginx debe transmitir las cabeceras
UpgradeyConnection; si no, el editor se muestra pero las celdas nunca se ejecutan.server { server_name notebooks.example.com; location / { proxy_pass http://127.0.0.1:2718; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 3600s; } }certbot --nginx -d notebooks.example.com
¿Sin dominio? Usa un túnel SSH
El editor ejecuta código Python con los permisos del contenedor: nunca lo expongas sin contraseña. Si trabajas solo, no hace falta publicarlo — un túnel SSH abre el editor en http://localhost:2718 desde tu equipo.
ssh -L 2718:127.0.0.1:2718 root@<vps-ip>Proteger el editor
Un editor de marimo abierto permite a quien entre ejecutar Python en tu servidor: esa es su razón de ser, y por eso se imponen algunas reglas sencillas.
Una contraseña larga y única. La del archivo .env es aleatoria; no la sustituyas por una contraseña que uses en otro sitio, y cámbiala cuando un colaborador que la conoce deje el proyecto (edita .env y luego docker compose up -d).
Un puerto que se queda en local. El compose publica el puerto solo en 127.0.0.1: desde Internet, únicamente nginx por HTTPS llega a él. Nunca cambies esa dirección por 0.0.0.0.
Nada de secretos en claro en los notebooks. Un notebook es un archivo Python versionado: una clave de API escrita en una celda acaba en el historial de Git. Léela desde una variable de entorno añadida al compose, o desde un archivo fuera del repositorio.
Registros que vigilar. Al arrancar, marimo muestra su dirección de acceso en docker compose logs, contraseña incluida: el registro se queda en tu VPS, pero no lo pegues tal cual en un ticket o en un chat.
Tu primer notebook reactivo
Inicia sesión con la contraseña del archivo .env. El editor abre la carpeta /app, que ya contiene los tutoriales oficiales. Crea un notebook con dos celdas: la primera define un deslizador y la segunda filtra un archivo CSV con su valor. Mueve el deslizador: la segunda celda se recalcula sola.
import marimo as mo
import polars as pl
umbral = mo.ui.slider(0, 1000, value=100, label="Importe mínimo")
umbralventas = pl.read_csv("data/ventas.csv")
ventas.filter(pl.col("importe") >= umbral.value)Leer tus datos: CSV, Parquet y API
La imagen «data» cubre lo esencial de un análisis sin instalar nada. pandas lee archivos CSV, Excel y JSON; polars lee CSV y Parquet muy rápido y puede procesar archivos más grandes que la memoria en modo perezoso; altair dibuja gráficos interactivos que se muestran justo debajo de la celda.
Deja tus archivos en la carpeta /app/data del volumen, con scp hacia el VPS y luego docker compose cp, o súbelos desde el panel de archivos del editor. Para una API, la biblioteca estándar de Python basta para descargar un JSON, que pandas o polars convierten después en una tabla.
Cada resultado de celda es un objeto vivo: un DataFrame se muestra como una tabla ordenable y filtrable, y la selección hecha en una tabla o un gráfico puede alimentar la celda siguiente. Ese mecanismo es el que convierte una exploración en una herramienta reutilizable.
Convertir un notebook en aplicación
Un notebook con elementos de interfaz ya es una aplicación. marimo run lo sirve en solo lectura: los visitantes usan los deslizadores y los menús sin ver ni modificar el código. Publica este segundo puerto detrás de su propio vhost, protegido como el editor.
docker compose exec marimo marimo run /app/rapport.py --host 0.0.0.0 -p 8081Tus notebooks de Jupyter existentes se convierten con un solo comando; después revisa las celdas que redefinían una misma variable, algo que marimo rechaza por diseño.
docker compose exec marimo marimo convert /app/old.ipynb -o /app/new.pyTrabajar en equipo sobre los mismos notebooks
Un servidor de marimo es un editor compartido: todas las personas con la contraseña ven los mismos archivos. Para un equipo pequeño, la regla más sencilla es un notebook por persona y por tema, y un repositorio Git en /app para conservar el historial.
Como cada notebook es un archivo .py, se aplican las herramientas habituales del desarrollador: git diff muestra exactamente qué celda cambió, una solicitud de fusión se revisa como código, y un linter o formateador de Python se ejecuta sobre él sin adaptación. Un notebook puede incluso importarse como módulo o ejecutarse como script desde una tarea programada, para producir cada noche el mismo informe.
Dimensionar el VPS
marimo en sí es ligero; son tus datos los que fijan el tamaño del servidor. Cuenta con 2 GB de RAM para explorar archivos de unos cientos de megabytes con pandas, y sube a 4 u 8 GB si cargas conjuntos de datos más voluminosos o si varias personas trabajan a la vez. El procesador importa sobre todo para cálculos pesados: polars aprovecha todos los núcleos disponibles. Prevé por último disco suficiente para la imagen (unos 400 MB) y para tus archivos de datos, que crecen más rápido que los notebooks.
Copia de seguridad y actualización
Los notebooks viven en el volumen marimo-data. Lo más seguro es versionar /app en un repositorio Git; si no, archiva el volumen con regularidad.
docker run --rm -v marimo_marimo-data:/data -v "$PWD":/backup alpine \
tar czf /backup/marimo-$(date +%F).tar.gz -C /data .Para actualizar, cambia la etiqueta de la imagen en compose.yaml tras leer las notas de versión del proyecto y ejecuta docker compose pull && docker compose up -d. Los notebooks, simples archivos .py, no se tocan.
Instalación en un clic desde el Marketplace de ServOrbit
En un VPS de ServOrbit, marimo se instala desde el Marketplace de tu área de cliente: el script despliega el contenedor oficial, genera la contraseña del editor y crea el volumen de los notebooks. La contraseña aparece en tu área de cliente. Asocia un subdominio de uno de tus dominios, o el subdominio gratuito del VPS, para abrir el editor por HTTPS; sin dominio, el túnel SSH descrito más arriba funciona tal cual, con el puerto que aparece en tu área de cliente.