Fly.io
Despliegue en Fly.io
Sección titulada «Despliegue en Fly.io»Objetivo: OpenClaw Gateway ejecutándose en una máquina Fly.io con almacenamiento persistente, HTTPS automático y acceso a Discord/canales.
Lo que necesitas
Sección titulada «Lo que necesitas»- CLI flyctl instalada
- Cuenta de Fly.io (la capa gratuita funciona)
- Autenticación del modelo: clave API para tu proveedor de modelos elegido
- Credenciales del canal: token del bot de Discord, token de Telegram, etc.
Ruta rápida para principiantes
Sección titulada «Ruta rápida para principiantes»- Clonar repositorio → personalizar
fly.toml - Crear aplicación + volumen → establecer secretos
- Desplegar con
fly deploy - Entrar por SSH para crear la configuración o usar la UI de Control
Crear la app de Fly
Ventana de terminal # Clone the repogit clone https://github.com/openclaw/openclaw.gitcd openclaw# Create a new Fly app (pick your own name)fly apps create my-openclaw# Create a persistent volume (1GB is usually enough)fly volumes create openclaw_data --size 1 --region iadConsejo: Elige una región cercana a ti. Opciones comunes:
lhr(Londres),iad(Virginia),sjc(San José).Configurar fly.toml
Edita
fly.tomlpara que coincida con el nombre de tu aplicación y los requisitos.Nota de seguridad: La configuración predeterminada expone una URL pública. Para un despliegue reforzado sin IP pública, consulta Despliegue Privado o usa
fly.private.toml.app = "my-openclaw" # Your app nameprimary_region = "iad"[build]dockerfile = "Dockerfile"[env]NODE_ENV = "production"OPENCLAW_PREFER_PNPM = "1"OPENCLAW_STATE_DIR = "/data"NODE_OPTIONS = "--max-old-space-size=1536"[processes]app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan"[http_service]internal_port = 3000force_https = trueauto_stop_machines = falseauto_start_machines = truemin_machines_running = 1processes = ["app"][[vm]]size = "shared-cpu-2x"memory = "2048mb"[mounts]source = "openclaw_data"destination = "/data"Configuraciones clave:
Configuración Por qué --bind lanSe vincula a 0.0.0.0para que el proxy de Fly pueda alcanzar el gateway--allow-unconfiguredSe inicia sin un archivo de configuración (crearás uno después) internal_port = 3000Debe coincidir con --port 3000(oOPENCLAW_GATEWAY_PORT) para los controles de salud de Flymemory = "2048mb"512MB es muy poco; se recomiendan 2GB OPENCLAW_STATE_DIR = "/data"Persiste el estado en el volumen Establecer secretos
Ventana de terminal # Required: Gateway token (for non-loopback binding)fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)# Model provider API keysfly secrets set ANTHROPIC_API_KEY=sk-ant-...# Optional: Other providersfly secrets set OPENAI_API_KEY=sk-...fly secrets set GOOGLE_API_KEY=...# Channel tokensfly secrets set DISCORD_BOT_TOKEN=MTQ...Notas:
- Los enlaces que no son de bucle local (
--bind lan) requierenOPENCLAW_GATEWAY_TOKENpor seguridad. - Trate estos tokens como contraseñas.
- Prefiera las variables de entorno al archivo de configuración para todas las claves de API y tokens. Esto mantiene los secretos fuera de
openclaw.jsondonde podrían exponerse o registrarse accidentalmente.
- Los enlaces que no son de bucle local (
Desplegar
Ventana de terminal fly deployEl primer despliegue construye la imagen de Docker (~2-3 minutos). Los despliegues posteriores son más rápidos.
Después del despliegue, verifique:
Ventana de terminal fly statusfly logsDebería ver:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)[discord] logged in to discord as xxxCrear archivo de configuración
Acceda por SSH a la máquina para crear una configuración adecuada:
Ventana de terminal fly ssh consoleCree el directorio y el archivo de configuración:
Ventana de terminal mkdir -p /datacat > /data/openclaw.json << 'EOF'{"agents": {"defaults": {"model": {"primary": "anthropic/claude-opus-4-6","fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-4o"]},"maxConcurrent": 4},"list": [{"id": "main","default": true}]},"auth": {"profiles": {"anthropic:default": { "mode": "token", "provider": "anthropic" },"openai:default": { "mode": "token", "provider": "openai" }}},"bindings": [{"agentId": "main","match": { "channel": "discord" }}],"channels": {"discord": {"enabled": true,"groupPolicy": "allowlist","guilds": {"YOUR_GUILD_ID": {"channels": { "general": { "allow": true } },"requireMention": false}}}},"gateway": {"mode": "local","bind": "auto"},"meta": {}}EOFNota: Con
OPENCLAW_STATE_DIR=/data, la ruta de configuración es/data/openclaw.json.Nota: El token de Discord puede provenir de:
- Variable de entorno:
DISCORD_BOT_TOKEN(recomendado para secretos) - Archivo de configuración:
channels.discord.token
Si usa una variable de entorno, no es necesario agregar el token a la configuración. El gateway lee
DISCORD_BOT_TOKENautomáticamente.Reinicie para aplicar:
Ventana de terminal exitfly machine restart- Variable de entorno:
Acceder al Gateway
Interfaz de control
Sección titulada «Interfaz de control»Abrir en el navegador:
Ventana de terminal fly openO visite
https://my-openclaw.fly.dev/Pegue su token de gateway (el de
OPENCLAW_GATEWAY_TOKEN) para autenticarse.Registros
Sección titulada «Registros»Ventana de terminal fly logs # Live logsfly logs --no-tail # Recent logsConsola SSH
Sección titulada «Consola SSH»Ventana de terminal fly ssh console
Solución de problemas
Sección titulada «Solución de problemas»”La aplicación no está escuchando en la dirección esperada”
Sección titulada «”La aplicación no está escuchando en la dirección esperada”»El gateway se está vinculando a 127.0.0.1 en lugar de 0.0.0.0.
Solución: Agregue --bind lan a su comando de proceso en fly.toml.
Fallos en las comprobaciones de salud / conexión rechazada
Sección titulada «Fallos en las comprobaciones de salud / conexión rechazada»Fly no puede alcanzar el gateway en el puerto configurado.
Solución: Asegúrese de que internal_port coincida con el puerto de la pasarela (establezca --port 3000 o OPENCLAW_GATEWAY_PORT=3000).
Problemas de OOM / Memoria
Sección titulada «Problemas de OOM / Memoria»El contenedor se sigue reiniciando o finalizándose. Signos: SIGABRT, v8::internal::Runtime_AllocateInYoungGeneration o reinicios silenciosos.
Solución: Aumente la memoria en fly.toml:
[[vm]] memory = "2048mb"O actualice una máquina existente:
fly machine update <machine-id> --vm-memory 2048 -yNota: 512MB es demasiado poco. 1GB puede funcionar pero puede provocar OOM bajo carga o con registros detallados. Se recomiendan 2GB.
Problemas de bloqueo de la pasarela
Sección titulada «Problemas de bloqueo de la pasarela»La pasarela se niega a iniciarse con errores de “ya se está ejecutando”.
Esto sucede cuando el contenedor se reinicia pero el archivo de bloqueo PID persiste en el volumen.
Solución: Elimine el archivo de bloqueo:
fly ssh console --command "rm -f /data/gateway.*.lock"fly machine restart <machine-id>El archivo de bloqueo está en /data/gateway.*.lock (no en un subdirectorio).
Configuración no se está leyendo
Sección titulada «Configuración no se está leyendo»Si usa --allow-unconfigured, la pasarela crea una configuración mínima. Su configuración personalizada en /data/openclaw.json debería leerse al reiniciar.
Verifique que la configuración existe:
fly ssh console --command "cat /data/openclaw.json"Escribir configuración a través de SSH
Sección titulada «Escribir configuración a través de SSH»El comando fly ssh console -C no admite el redireccionamiento de shell. Para escribir un archivo de configuración:
# Use echo + tee (pipe from local to remote)echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json"
# Or use sftpfly sftp shell> put /local/path/config.json /data/openclaw.jsonNota: fly sftp puede fallar si el archivo ya existe. Elimínelo primero:
fly ssh console --command "rm /data/openclaw.json"El estado no persiste
Sección titulada «El estado no persiste»Si pierde credenciales o sesiones después de un reinicio, el directorio de estado se está escribiendo en el sistema de archivos del contenedor.
Solución: Asegúrese de que OPENCLAW_STATE_DIR=/data esté configurado en fly.toml y vuelva a implementar.
Actualizaciones
Sección titulada «Actualizaciones»# Pull latest changesgit pull
# Redeployfly deploy
# Check healthfly statusfly logsComando de actualización de máquina
Sección titulada «Comando de actualización de máquina»Si necesita cambiar el comando de inicio sin una implementación completa:
# Get machine IDfly machines list
# Update commandfly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y
# Or with memory increasefly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -yNota: Después de fly deploy, el comando de la máquina puede restablecerse a lo que está en fly.toml. Si realizó cambios manuales, aplíquelos nuevamente después de la implementación.
Implementación privada (Endurecida)
Sección titulada «Implementación privada (Endurecida)»De forma predeterminada, Fly asigna direcciones IP públicas, lo que hace que su pasarela sea accesible en https://your-app.fly.dev. Esto es conveniente pero significa que su implementación puede ser descubierta por escáneres de Internet (Shodan, Censys, etc.).
Para una implementación endurecida con sin exposición pública, use la plantilla privada.
Cuándo usar la implementación privada
Sección titulada «Cuándo usar la implementación privada»- Solo realiza salientes llamadas/mensajes (sin webhooks entrantes)
- Usa túneles ngrok o Tailscale para cualquier devolución de llamada de webhook
- Accedes a la puerta de enlace a través de SSH, proxy o WireGuard en lugar del navegador
- Quieres que el despliegue esté oculto para los escáneres de internet
Configuración
Sección titulada «Configuración»Usa fly.private.toml en lugar de la configuración estándar:
# Deploy with private configfly deploy -c fly.private.tomlO convierte un despliegue existente:
# List current IPsfly ips list -a my-openclaw
# Release public IPsfly ips release <public-ipv4> -a my-openclawfly ips release <public-ipv6> -a my-openclaw
# Switch to private config so future deploys don't re-allocate public IPs# (remove [http_service] or deploy with the private template)fly deploy -c fly.private.toml
# Allocate private-only IPv6fly ips allocate-v6 --private -a my-openclawDespués de esto, fly ips list debería mostrar solo una IP de tipo private:
VERSION IP TYPE REGIONv6 fdaa:x:x:x:x::x private globalAcceder a un despliegue privado
Sección titulada «Acceder a un despliegue privado»Dado que no hay una URL pública, usa uno de estos métodos:
Opción 1: Proxy local (el más sencillo)
# Forward local port 3000 to the appfly proxy 3000:3000 -a my-openclaw
# Then open http://localhost:3000 in browserOpción 2: VPN WireGuard
# Create WireGuard config (one-time)fly wireguard create
# Import to WireGuard client, then access via internal IPv6# Example: http://[fdaa:x:x:x:x::x]:3000Opción 3: Solo SSH
fly ssh console -a my-openclawWebhooks con despliegue privado
Sección titulada «Webhooks con despliegue privado»Si necesitas devoluciones de llamada de webhook (Twilio, Telnyx, etc.) sin exposición pública:
- Túnel ngrok - Ejecuta ngrok dentro del contenedor o como sidecar
- Tailscale Funnel - Expone rutas específicas a través de Tailscale
- Solo saliente - Algunos proveedores (Twilio) funcionan bien para llamadas salientes sin webhooks
Ejemplo de configuración de llamada de voz con ngrok:
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", tunnel: { provider: "ngrok" }, webhookSecurity: { allowedHosts: ["example.ngrok.app"], }, }, }, }, },}El túnel ngrok se ejecuta dentro del contenedor y proporciona una URL de webhook pública sin exponer la aplicación de Fly en sí. Establece webhookSecurity.allowedHosts al nombre de host del túnel público para que se acepten los encabezados de host reenviados.
Beneficios de seguridad
Sección titulada «Beneficios de seguridad»| Aspecto | Público | Privado |
|---|---|---|
| Escáneres de internet | Detectable | Oculto |
| Ataques directos | Posibles | Bloqueados |
| Acceso a la interfaz de control | Navegador | Proxy/VPN |
| Entrega de webhooks | Directa | Vía túnel |
- Fly.io utiliza la arquitectura x86 (no ARM)
- El Dockerfile es compatible con ambas arquitecturas
- Para el registro en WhatsApp/Telegram, usa
fly ssh console - Los datos persistentes residen en el volumen en
/data - Signal requiere Java + signal-cli; usa una imagen personalizada y mantén la memoria en 2GB o más.
Con la configuración recomendada (shared-cpu-2x, 2GB RAM):
- ~$10-15/mes dependiendo del uso
- El nivel gratuito incluye alguna asignación
Consulta los precios de Fly.io para obtener detalles.
Próximos pasos
Sección titulada «Próximos pasos»- Configura canales de mensajería: Canales
- Configura la puerta de enlace: Configuración de la puerta de enlace
- Mantén OpenClaw actualizado: Actualización