[{"data":1,"prerenderedAt":255},["ShallowReactive",2],{"seo-verification":3,"blog-windmill-en-vps-workflows-typescriptpython-sin-dependencias-es":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-windmill-en-vps-workflows-typescriptpython-sin-dependencias-es",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":32,"intro":35,"sections":36,"ctaTitle":190,"ctaBody":191,"ctaButton":192,"ctaUrl":193,"relatedPosts":194},438,"windmill-en-vps-workflows-typescriptpython-sin-dependencias",{"fr":12,"en":13,"ar":14,"es":10},"windmill-workflow-engine-vps","windmill-on-vps-typescriptpython-workflows-without-lock-in","محرك-سير-العمل-windmill-على-vps-python-typescript","Windmill en VPS: workflows TypeScript\u002FPython sin dependencias","Despliega Windmill v1.830 en un VPS en menos de una hora: workflows TypeScript\u002FPython, crons, webhooks e interfaz integrada, sin depender de n8n ni Make.",11,0,false,"2026-10-13T00:00:00+00:00","2026-10-13T14:10:28+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},2,"Automatización","automatisation","bg-brand-action\u002F10 text-brand-action",[28],{"id":23,"name":24,"slug":25,"color":26,"icon":25},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fwindmill-workflow-engine-vps-poster.svg",{"categorySlug":33,"appSlug":34},"automatizacion","windmill","n8n 3.0, lanzado en octubre de 2026, impone Docker como única vía de despliegue y elimina más de 30 nodos históricos. Para los equipos que evalúan alternativas, Windmill destaca como la opción más directa: escribe TypeScript o Python nativo, ejecuta scripts directamente desde el editor web y orquesta decenas de workers en un único VPS. Sin plan de pago para variables secretas, sin nodos propietarios — solo código versionado en un workspace respaldado por Git. Esta guía te lleva a una instancia Windmill v1.830 lista para producción en menos de una hora.",[37,41,51,54,62,87,90,98,101,109,113,116,124,127,136],{"type":38,"title":39,"body":40},"h2","Por qué Windmill en lugar de n8n o Make en 2026","n8n 3.0 marca un punto de inflexión: Docker es obligatorio, se eliminan más de 30 nodos y los nodos Code ya no pueden leer variables de entorno. Make sigue siendo un SaaS cerrado con límites de operaciones mensuales. Windmill toma el camino opuesto: tu código es un script de primera clase, versionado, testeable unitariamente y ejecutable desde un terminal igual que desde la interfaz. La licencia AGPLv3 garantiza que la versión autoalojada sea funcionalmente idéntica a la oferta cloud — sin características reservadas para empresas en el uso cotidiano.",{"type":42,"title":43,"items":44},"ul","Beneficios concretos para equipos DevOps y agencias",[45,46,47,48,49,50],"**TypeScript y Python nativos** — los scripts se ejecutan en un worker Node.js o Python sin transpilación ni capas intermedias; las dependencias npm\u002Fpip se resuelven automáticamente en la primera ejecución.","**Editor web con ejecución directa** — escribe, prueba y relanza un script desde el navegador en segundos, sin hacer push de un commit ni reiniciar ningún servicio.","**Multi-tenancy integrado** — un único despliegue soporta múltiples workspaces aislados, ideal para una agencia que gestiona varios clientes o un equipo con entornos dev\u002Fstaging\u002Fprod.","**Cron jobs y webhooks sin plugins** — programar un job con `0 9 * * 1-5` o exponer un endpoint webhook es una operación nativa, no un add-on.","**Variables secretas cifradas** — los secretos se cifran con AES-256 en base de datos y nunca se exponen en logs; cada workspace tiene su propio ámbito de secretos.","**Sin vendor lock-in** — todos los scripts, flows y recursos son exportables en JSON\u002FYAML e importables en cualquier otro despliegue de Windmill.",{"type":38,"title":52,"body":53},"Requisitos mínimos en cifras","Windmill se apoya en PostgreSQL para la persistencia y en uno o más workers para la ejecución. El servidor HTTP es ligero; la carga de los workers determina el dimensionamiento del VPS. Cuenta 1 worker por vCPU disponible y aproximadamente 1 a 2 GB de RAM por worker Python activo.",{"type":42,"title":55,"items":56},"Configuración mínima y recomendada",[57,58,59,60,61],"**Mínimo absoluto** — 2 vCPU, 4 GB RAM, 20 GB SSD; adecuado para un workspace individual con 1 worker y jobs ocasionales.","**Equipo pequeño (recomendado)** — 4 vCPU, 8 GB RAM, 40 GB SSD; soporta 3 workers concurrentes y PostgreSQL en el mismo host sin presión de memoria.","**Equipo o multi-cliente** — 8 vCPU, 16 GB RAM, 80 GB SSD; soporta 6 a 8 workers y múltiples workspaces activos.","**Sistema operativo** — Ubuntu 22.04 LTS o Debian 12; Docker Engine 24+ y Docker Compose v2 requeridos.","**Red** — una IPv4 dedicada y un nombre de dominio para el certificado TLS; Windmill expone el puerto 8000 por defecto detrás de un reverse proxy.",{"type":63,"title":64,"steps":65},"steps","Despliegue con Docker Compose en 7 pasos",[66,69,72,75,78,81,84],{"title":67,"body":68},"Instalar Docker y Docker Compose v2","En Ubuntu 22.04 o Debian 12: `curl -fsSL https:\u002F\u002Fget.docker.com | sh && docker compose version`. Verifica que el comando devuelva `Docker Compose version v2.x.x` (sin guion). Si tu sistema aún tiene `docker-compose` (v1), desinstálalo: `apt remove docker-compose`.",{"title":70,"body":71},"Obtener el docker-compose.yml oficial","Crea un directorio dedicado y descarga la configuración de referencia: `mkdir -p \u002Fopt\u002Fwindmill && cd \u002Fopt\u002Fwindmill && curl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002Fwindmill-labs\u002Fwindmill\u002Fmain\u002Fdocker-compose.yml -o docker-compose.yml`. Este archivo declara cuatro servicios: `db` (PostgreSQL 16), `windmill_server`, `windmill_worker` y `lsp` (servidor de completado de código).",{"title":73,"body":74},"Crear el archivo .env","Windmill requiere dos variables obligatorias. Genera una clave aleatoria: `openssl rand -hex 32`. Luego crea `\u002Fopt\u002Fwindmill\u002F.env` con: `WM_BASE_URL=https:\u002F\u002Fwindmill.tu-dominio.com` y `WINDMILL_SECRET_KEY=\u003Cclave-generada>`. Nunca hagas commit de este archivo.",{"title":76,"body":77},"Ajustar el número de workers","Por defecto `docker-compose.yml` inicia 1 réplica de `windmill_worker`. Para iniciar 3: `docker compose up -d --scale windmill_worker=3`. En un VPS con 4 vCPU \u002F 8 GB, 2 o 3 workers es el equilibrio óptimo.",{"title":79,"body":80},"Configurar Nginx como reverse proxy con TLS","Instala Nginx y Certbot: `apt install -y nginx certbot python3-certbot-nginx`. Crea `\u002Fetc\u002Fnginx\u002Fsites-available\u002Fwindmill` con un bloque `server` escuchando en el puerto 80, `proxy_pass http:\u002F\u002F127.0.0.1:8000;` y las cabeceras para WebSocket. Obtén el certificado: `certbot --nginx -d windmill.tu-dominio.com`.",{"title":82,"body":83},"Iniciar la stack y crear el workspace inicial","Lanza la stack: `cd \u002Fopt\u002Fwindmill && docker compose up -d`. Espera 30 segundos a que PostgreSQL esté listo y abre `https:\u002F\u002Fwindmill.tu-dominio.com`. La interfaz te pide crear un workspace y definir la cuenta de administrador.",{"title":85,"body":86},"Activar el reinicio automático y verificar logs","En `docker-compose.yml` asegúrate de que cada servicio tenga `restart: unless-stopped`. Verifica los logs del servidor: `docker compose logs -f windmill_server`. La línea `Windmill server started on port 8000` confirma que la instancia funciona.",{"type":38,"title":88,"body":89},"Configuración: workspace, variables secretas y crons","Una vez la instancia arrancada, hay tres áreas de configuración que dominar antes de crear tus primeros workflows.",{"type":42,"title":91,"items":92},"Ajustes esenciales tras la instalación",[93,94,95,96,97],"**Workspace y permisos** — en `Settings → Workspace` define la zona horaria (usada para crons) y activa `Auto-approve executions` solo si todos los miembros son de confianza.","**Variables y recursos** — `Variables` almacena claves escalares cifradas con AES-256. `Resources` almacena objetos estructurados con esquema JSON (conexiones de base de datos, credenciales OAuth).","**Schedules (crons)** — en el editor de un script, haz clic en `Add schedule`. La sintaxis aceptada es el formato cron estándar de 5 campos. La zona horaria del workspace se aplica automáticamente.","**Webhooks** — cada script expone un endpoint de la forma `\u002Fapi\u002Fw\u002F\u003Cworkspace>\u002Fjobs\u002Frun\u002Fp\u002F\u003Cpath>`. Autentica las llamadas entrantes con un token generado en `Settings → Tokens`.","**Git Sync** — en `Settings → Git Sync` conecta un repositorio Git para sincronizar automáticamente todos los scripts, flows y recursos en cada modificación.",{"type":38,"title":99,"body":100},"Ejemplo de workflow Python completo","Un script Python concreto: consulta una API externa, filtra los resultados e inserta filas en PostgreSQL mediante un recurso Windmill. Crea un nuevo script Python 3.11 y ejecútalo directamente desde el editor.",{"type":42,"title":102,"items":103},"Script Python: importación API → filtro → PostgreSQL",[104,105,106,107,108],"**Declaración de dependencias** — las líneas `# requirements:` al inicio del script indican a Windmill qué paquetes pip instalar en el sandbox aislado.","**Firma de la función principal** — Windmill siempre llama a `def main(...)`. Los parámetros se inyectan desde la UI, el cron o el cuerpo del webhook.","**Llamada HTTP con httpx** — `import httpx; resp = httpx.get(api_url, timeout=10); resp.raise_for_status(); data = resp.json()`. Windmill captura las excepciones no manejadas y las muestra en el log de ejecución.","**Filtrado e inserción** — `rows = [r for r in data if r.get('active')]; conn = psycopg2.connect(**db); cur.executemany('INSERT INTO items ...', rows); conn.commit()`. El recurso `db` se pasa como dict Python.","**Valor de retorno** — `return {'inserted': len(rows), 'source': api_url}`. El valor retornado se muestra en la UI y es accesible a los pasos siguientes de un Flow.",{"type":110,"title":111,"body":112},"tip","Endurecimiento y seguridad","Bloquea el puerto 8000 en UFW (`ufw deny 8000\u002Ftcp`) — solo Nginx debe acceder a él vía localhost. Añade cabeceras de seguridad en Nginx: `add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff`. Configura backups de PostgreSQL: `docker exec windmill-db-1 pg_dump -U windmill windmill | gzip > \u002Fbackups\u002Fwindmill-$(date +%Y%m%d).sql.gz`. Activa la política de contraseñas en `Settings → Security` y fuerza 2FA para las cuentas admin.",{"type":38,"title":114,"body":115},"Resolución de problemas — errores frecuentes","Estos son los cinco problemas más comunes en un primer despliegue de Windmill, con sus causas reales y soluciones.",{"type":42,"title":117,"items":118},"5 errores reales y sus correcciones",[119,120,121,122,123],"**`connection refused` al arrancar el servidor** — el contenedor `windmill_server` arranca antes de que PostgreSQL esté listo. Añade un `healthcheck` al servicio `db` y una cláusula `depends_on: db: condition: service_healthy`.","**Workers que permanecen `IDLE` indefinidamente** — causa clásica: `DATABASE_URL` apunta a `localhost` en vez del nombre del servicio Docker (`db`). El valor correcto: `postgresql:\u002F\u002Fwindmill:windmill@db\u002Fwindmill`.","**Scripts Python que fallan con `ModuleNotFoundError`** — Windmill resuelve las dependencias pip en la primera ejecución. Si el worker no tiene acceso a internet, la instalación falla silenciosamente. Abre el puerto 443 saliente para `pypi.org`.","**Webhook devuelve 403 Forbidden** — el script está en modo `Require approval`. Desactívalo en el editor o usa un token de servicio con el rol `executor`.","**Cron que no se dispara a la hora prevista** — la zona horaria del workspace es UTC por defecto. Verifica el ajuste en `Settings → Workspace → Timezone` y reinicia: `docker compose restart windmill_server`.",{"type":38,"title":125,"body":126},"Hacia la producción: checklist final","Antes de exponer Windmill a tráfico real o jobs críticos, repasa esta lista.",{"type":42,"title":128,"items":129},"Puntos de validación antes de ir a producción",[130,131,132,133,134,135],"**TLS válido y HSTS** — verifica que `https:\u002F\u002Fwindmill.tu-dominio.com` responde sin advertencias y añade `Strict-Transport-Security: max-age=31536000`.","**Backups probados** — haz un dump de PostgreSQL, restáuralo en un contenedor de prueba y verifica que la interfaz conecta.","**Monitorización de workers** — la página `Admin → Workers` muestra el estado en tiempo real. Configura una alerta si el número de workers activos cae por debajo de 1.","**Rotación de secretos** — si pierdes `WINDMILL_SECRET_KEY`, los secretos cifrados en base de datos son irrecuperables. Guarda la clave en un gestor de secretos separado del VPS.","**Versión fijada en docker-compose.yml** — reemplaza `:latest` por `:1.830.0` para evitar actualizaciones automáticas no controladas.","**Git Sync activado** — conecta un repositorio privado para versionar todos tus scripts y flows.",{"type":137,"title":138,"headers":139,"rows":144},"comparison","Windmill vs n8n vs Temporal",[140,141,142,143],"Criterio","Windmill 1.830","n8n 3.x","Temporal (cloud\u002Fautoalojado)",[145,150,155,160,165,170,175,180,185],[146,147,148,149],"Lenguaje de workflows","TypeScript, Python, Go, Bash","JavaScript (nodos) + Code nodes limitados","Go, Java, Python, TypeScript vía SDK",[151,152,153,154],"Modelo de despliegue","Docker Compose, imagen única","Docker obligatorio desde v3.0","Docker o Temporal Cloud SaaS",[156,157,158,159],"Licencia","AGPLv3 (autoalojado completo)","Sustainable Use License (restricciones agencias)","MIT (núcleo) + oferta cloud de pago",[161,162,163,164],"Variables secretas (autoalojado)","Incluidas, cifradas AES-256","Incluidas","Incluidas (Temporal Namespace)",[166,167,168,169],"Editor web integrado","Sí — IDE completo con autocompletado","Sí — canvas visual","No — solo desarrollo local",[171,172,173,174],"Multi-tenancy","Sí — workspaces aislados nativos","Parcial — instancias separadas recomendadas","Sí — Temporal Namespaces",[176,177,178,179],"RAM mínima","4 GB (1 worker + PostgreSQL)","2 GB (SQLite), 4 GB (PostgreSQL)","4 GB (autoalojado) \u002F N\u002FA (cloud)",[181,182,183,184],"Duración máxima del workflow","Ilimitada (jobs de larga duración)","Limitada por timeout del nodo","Ilimitada (durabilidad de actividades)",[186,187,188,189],"Curva de aprendizaje","Baja — código Python\u002FTS estándar","Baja — canvas visual","Alta — modelo de actividades\u002Fseñales","Un VPS listo para Windmill en minutos","ServOrbit ofrece VPS con acceso root, IPv4 dedicada y elección de OS Ubuntu\u002FDebian. Monta tu stack Windmill con Docker Compose desde el primer acceso SSH.","Desplegar Windmill en VPS ServOrbit","\u002Fmarketplace\u002Fautomatizacion\u002Fwindmill",[195,213,237],{"id":196,"slug":197,"slugs":198,"title":202,"excerpt":203,"readTime":204,"views":23,"isPinned":19,"publishedAt":205,"updatedAt":206,"category":207,"categories":208,"featuredImage":29,"bgImage":30,"posterImage":210,"relatedSolution":211},3,"instalar-n8n-en-vps-con-docker",{"fr":199,"en":200,"ar":201,"es":197},"installer-n8n-vps","install-n8n-on-vps-with-docker-complete-2026-guide","تثبيت-n8n-على-vps-مع-docker-دليل-شامل-2026","Instalar n8n en un VPS con Docker: guía completa 2026","Despliegue n8n en VPS con Docker, reverse proxy y HTTPS. Crash V8, 502 nginx, migración de npm a Docker y seguridad de ejecuciones persistidas (advisory agosto 2026).",16,"2026-06-05T00:00:00+00:00","2026-09-23T15:23:17+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[209],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Finstaller-n8n-vps-poster.svg",{"categorySlug":33,"appSlug":212},"n8n",{"id":214,"slug":215,"slugs":216,"title":220,"excerpt":221,"readTime":222,"views":18,"isPinned":19,"publishedAt":223,"updatedAt":224,"category":225,"categories":231,"featuredImage":29,"bgImage":30,"posterImage":233,"relatedSolution":234},359,"stack-ia-open-source-vps-ollama-openwebui-n8n",{"fr":217,"en":218,"ar":219,"es":215},"construire-stack-ia-open-source-vps","open-source-ai-stack-vps-ollama-openwebui-n8n","بيئة-ذكاء-اصطناعي-ذاتية-الاستضافة-vps","Stack de IA open source en VPS: Ollama, Open WebUI y n8n","Ensamble Ollama, Open WebUI y n8n en un solo VPS: motor LLM local, interfaz de chat y automatización, 100% self-hosted sin ninguna API cloud.",8,"2026-09-18T00:00:00+00:00","2026-09-21T15:22:03+00:00",{"id":226,"name":227,"slug":228,"color":229,"icon":230},1,"Inteligencia Artificial","intelligence-artificielle","bg-purple-500\u002F10 text-purple-400","ia",[232],{"id":226,"name":227,"slug":228,"color":229,"icon":230},"\u002Fblog\u002Fcovers\u002Fconstruire-stack-ia-open-source-vps-poster.svg",{"categorySlug":235,"appSlug":236},"inteligencia-artificial","open-webui",{"id":238,"slug":239,"slugs":240,"title":243,"excerpt":244,"readTime":17,"views":18,"isPinned":19,"publishedAt":245,"updatedAt":21,"category":246,"categories":252,"featuredImage":29,"bgImage":30,"posterImage":254,"relatedSolution":29},436,"laravel-octane-vps-frankenphp-docker-traefik",{"fr":241,"en":239,"ar":242,"es":239},"deployer-laravel-vps-octane","laravel-octane-على-vps-frankenphp-docker-traefik","Laravel Octane en VPS: FrankenPHP, Docker y Traefik","Migrar de PHP-FPM a Laravel Octane con FrankenPHP en Docker Compose detrás de Traefik, entender los cambios del ciclo de vida.","2026-10-12T00:00:00+00:00",{"id":247,"name":248,"slug":249,"color":250,"icon":251},4,"Desarrollo","developpement","bg-warning\u002F10 text-warning","dev",[253],{"id":247,"name":248,"slug":249,"color":250,"icon":251},"\u002Fblog\u002Fcovers\u002Fdeployer-laravel-vps-octane-poster.svg",1791901124803]