Hosting
Fly.io
Meta: OpenClaw Gateway em execução em uma máquina Fly.io com armazenamento persistente, HTTPS automático e acesso a Discord/canais.
O que você precisa
- flyctl CLI instalado
- Conta Fly.io (o plano gratuito funciona)
- Autenticação de modelo: chave de API para o provedor de modelo escolhido
- Credenciais de canal: token de bot do Discord, token do Telegram, etc.
Caminho rápido para iniciantes
- Clone o repositório → personalize
fly.toml - Crie o app + volume → defina secrets
- Faça deploy com
fly deploy - Entre via SSH para criar a configuração ou use a Control UI
Criar o app Fly
# Clone o repositóriogit clone https://github.com/openclaw/openclaw.gitcd openclaw # Crie um novo app Fly (escolha seu próprio nome)fly apps create my-openclaw # Crie um volume persistente (1 GB geralmente é suficiente)fly volumes create openclaw_data --size 1 --region iadDica: Escolha uma região próxima de você. Opções comuns: lhr (Londres), iad (Virgínia), sjc (San Jose).
Configurar fly.toml
Edite fly.toml para corresponder ao nome e aos requisitos do seu app.
Nota de segurança: A configuração padrão expõe uma URL pública. Para um deploy reforçado sem IP público, consulte Deploy privado ou use deploy/fly.private.toml.
app = "my-openclaw" # Nome do seu appprimary_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 = 3000 force_https = true auto_stop_machines = false auto_start_machines = true min_machines_running = 1 processes = ["app"] [[vm]] size = "shared-cpu-2x" memory = "2048mb" [mounts] source = "openclaw_data" destination = "/data"A imagem Docker do OpenClaw usa tini como entrypoint. Os comandos de processo do Fly substituem o CMD do Docker sem substituir o ENTRYPOINT, então o processo ainda executa sob tini.
Configurações principais:
| Configuração | Por quê |
|---|---|
--bind lan |
Vincula a 0.0.0.0 para que o proxy do Fly consiga alcançar o Gateway |
--allow-unconfigured |
Inicia sem um arquivo de configuração (você criará um depois) |
internal_port = 3000 |
Deve corresponder a --port 3000 (ou OPENCLAW_GATEWAY_PORT) para health checks do Fly |
memory = "2048mb" |
512 MB é pouco demais; 2 GB recomendado |
OPENCLAW_STATE_DIR = "/data" |
Persiste o estado no volume |
Definir secrets
# Obrigatório: token do Gateway (para binding não loopback)fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32) # Chaves de API do provedor de modelofly secrets set ANTHROPIC_API_KEY=example-anthropic-key-not-real # Opcional: outros provedoresfly secrets set OPENAI_API_KEY=example-openai-key-not-realfly secrets set GOOGLE_API_KEY=... # Tokens de canalfly secrets set DISCORD_BOT_TOKEN=example-discord-bot-tokenObservações:
- Bindings não loopback (
--bind lan) exigem um caminho válido de autenticação do Gateway. Este exemplo do Fly.io usaOPENCLAW_GATEWAY_TOKEN, masgateway.auth.passwordou um deploytrusted-proxynão loopback configurado corretamente também atendem ao requisito. - Trate esses tokens como senhas.
- Prefira variáveis de ambiente ao arquivo de configuração para todas as chaves de API e tokens. Isso mantém secrets fora de
openclaw.json, onde poderiam ser expostos ou registrados acidentalmente.
Fazer deploy
fly deployO primeiro deploy cria a imagem Docker (~2 a 3 minutos). Deploys posteriores são mais rápidos.
Após o deploy, verifique:
fly statusfly logsVocê deve ver:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)[discord] logged in to discord as xxxCriar arquivo de configuração
Entre via SSH na máquina para criar uma configuração adequada:
fly ssh consoleCrie o diretório e o arquivo de configuração:
mkdir -p /datacat > /data/openclaw.json << 'EOF'{ "agents": { "defaults": { "model": { "primary": "anthropic/claude-opus-4-6", "fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"] }, "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", "controlUi": { "allowedOrigins": [ "https://my-openclaw.fly.dev", "http://localhost:3000", "http://127.0.0.1:3000" ] } }, "meta": {}}EOFObservação: Com OPENCLAW_STATE_DIR=/data, o caminho da configuração é /data/openclaw.json.
Observação: Substitua https://my-openclaw.fly.dev pela origem real do seu app Fly. A inicialização do Gateway semeia origens locais da Control UI a partir dos valores de runtime --bind e --port para que a primeira inicialização possa prosseguir antes de a configuração existir, mas o acesso pelo navegador via Fly ainda precisa da origem HTTPS exata listada em gateway.controlUi.allowedOrigins.
Observação: O token do Discord pode vir de:
- Variável de ambiente:
DISCORD_BOT_TOKEN(recomendado para secrets) - Arquivo de configuração:
channels.discord.token
Se usar variável de ambiente, não é necessário adicionar o token à configuração. O Gateway lê DISCORD_BOT_TOKEN automaticamente.
Reinicie para aplicar:
exitfly machine restart <machine-id>Acessar o Gateway
Control UI
Abra no navegador:
fly openOu acesse https://my-openclaw.fly.dev/
Autentique-se com o segredo compartilhado configurado. Este guia usa o token do Gateway de OPENCLAW_GATEWAY_TOKEN; se você mudou para autenticação por senha, use essa senha.
Logs
fly logs # Logs ao vivofly logs --no-tail # Logs recentesConsole SSH
fly ssh consoleSolução de problemas
"App is not listening on expected address"
O Gateway está fazendo bind em 127.0.0.1 em vez de 0.0.0.0.
Correção: Adicione --bind lan ao comando de processo em fly.toml.
Health checks falhando / conexão recusada
O Fly não consegue alcançar o Gateway na porta configurada.
Correção: Garanta que internal_port corresponda à porta do Gateway (defina --port 3000 ou OPENCLAW_GATEWAY_PORT=3000).
OOM / Problemas de memória
O contêiner continua reiniciando ou sendo encerrado. Sinais: SIGABRT, v8::internal::Runtime_AllocateInYoungGeneration ou reinicializações silenciosas.
Correção: Aumente a memória em fly.toml:
[[vm]] memory = "2048mb"Ou atualize uma máquina existente:
fly machine update <machine-id> --vm-memory 2048 -yObservação: 512 MB é pouco demais. 1 GB pode funcionar, mas pode sofrer OOM sob carga ou com logging detalhado. 2 GB é recomendado.
Problemas de lock do Gateway
O Gateway se recusa a iniciar com erros de "already running".
Isso acontece quando o contêiner reinicia, mas o arquivo de lock de PID persiste no volume.
Correção: Exclua o arquivo de lock:
fly ssh console --command "rm -f /data/gateway.*.lock"fly machine restart <machine-id>O arquivo de lock fica em /data/gateway.*.lock (não em um subdiretório).
Configuração não está sendo lida
--allow-unconfigured apenas ignora a proteção de inicialização. Ele não cria nem repara /data/openclaw.json, então garanta que sua configuração real exista e inclua gateway.mode="local" quando quiser uma inicialização normal do Gateway local.
Verifique se a configuração existe:
fly ssh console --command "cat /data/openclaw.json"Escrevendo configuração via SSH
O comando fly ssh console -C não oferece suporte a redirecionamento de shell. Para escrever um arquivo de configuração:
# Use echo + tee (pipe do local para o remoto)echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json" # Ou use sftpfly sftp shell> put /local/path/config.json /data/openclaw.jsonObservação: fly sftp pode falhar se o arquivo já existir. Exclua primeiro:
fly ssh console --command "rm /data/openclaw.json"Estado não persistindo
Se você perder perfis de autenticação, estado de canal/provedor ou sessões após uma reinicialização, o diretório de estado está gravando no sistema de arquivos do contêiner.
Correção: Garanta que OPENCLAW_STATE_DIR=/data esteja definido em fly.toml e faça redeploy.
Atualizações
# Baixe as alterações mais recentesgit pull # Faça redeployfly deploy # Verifique a integridadefly statusfly logsAtualizando o comando da máquina
Se você precisar alterar o comando de inicialização sem um redeploy completo:
# Obtenha o ID da máquinafly machines list # Atualize o comandofly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y # Ou com aumento de memóriafly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -yObservação: Após fly deploy, o comando da máquina pode ser redefinido para o que está em fly.toml. Se você fez alterações manuais, reaplique-as após o deploy.
Deploy privado (reforçado)
Por padrão, o Fly aloca IPs públicos, tornando seu Gateway acessível em https://your-app.fly.dev. Isso é conveniente, mas significa que seu deploy pode ser descoberto por scanners da internet (Shodan, Censys, etc.).
Para um deploy reforçado sem nenhuma exposição pública, use o template privado.
Quando usar deploy privado
- Você faz apenas chamadas/mensagens de saída (sem webhooks de entrada)
- Você usa túneis ngrok ou Tailscale para quaisquer callbacks de Webhook
- Você acessa o Gateway via SSH, proxy ou WireGuard em vez do navegador
- Você quer o deploy oculto de scanners da internet
Configuração
Use deploy/fly.private.toml em vez da configuração padrão:
# Faça deploy com a configuração privadafly deploy -c deploy/fly.private.tomlOu converta um deploy existente:
# Liste os IPs atuaisfly ips list -a my-openclaw # Libere IPs públicosfly ips release <public-ipv4> -a my-openclawfly ips release <public-ipv6> -a my-openclaw # Mude para a configuração privada para que deploys futuros não realoquem IPs públicos# (remova [http_service] ou faça deploy com o template privado)fly deploy -c deploy/fly.private.toml # Aloque IPv6 somente privadofly ips allocate-v6 --private -a my-openclawDepois disso, fly ips list deve mostrar apenas um IP do tipo private:
VERSION IP TYPE REGIONv6 fdaa:x:x:x:x::x private globalAcessando um deploy privado
Como não há URL pública, use um destes métodos:
Opção 1: Proxy local (mais simples)
# Encaminhe a porta local 3000 para o appfly proxy 3000:3000 -a my-openclaw # Depois abra http://localhost:3000 no navegadorOpção 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]:3000Opção 3: somente SSH
fly ssh console -a my-openclawWebhooks com implantação privada
Se você precisar de callbacks de Webhook (Twilio, Telnyx etc.) sem exposição pública:
- Túnel ngrok - Execute o ngrok dentro do contêiner ou como sidecar
- Tailscale Funnel - Exponha caminhos específicos via Tailscale
- Somente saída - Alguns provedores (Twilio) funcionam bem para chamadas de saída sem Webhooks
Exemplo de configuração de chamada de voz com ngrok:
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", tunnel: { provider: "ngrok" }, webhookSecurity: { allowedHosts: ["example.ngrok.app"], }, }, }, }, },}O túnel ngrok é executado dentro do contêiner e fornece uma URL pública de Webhook sem expor o próprio app Fly. Defina webhookSecurity.allowedHosts como o nome de host público do túnel para que os cabeçalhos de host encaminhados sejam aceitos.
Benefícios de segurança
| Aspecto | Público | Privado |
|---|---|---|
| Scanners da internet | Detectável | Oculto |
| Ataques diretos | Possíveis | Bloqueados |
| Acesso à UI de controle | Navegador | Proxy/VPN |
| Entrega de Webhook | Direta | Via túnel |
Observações
- O Fly.io usa arquitetura x86 (não ARM)
- O Dockerfile é compatível com ambas as arquiteturas
- Para onboarding do WhatsApp/Telegram, use
fly ssh console - Dados persistentes ficam no volume em
/data - O Signal requer Java + signal-cli; use uma imagem personalizada e mantenha a memória em 2 GB ou mais.
Custo
Com a configuração recomendada (shared-cpu-2x, 2 GB de RAM):
- ~US$ 10-15/mês, dependendo do uso
- O nível gratuito inclui alguma cota
Veja preços da Fly.io para detalhes.
Próximos passos
- Configure canais de mensagens: Canais
- Configure o Gateway: Configuração do Gateway
- Mantenha o OpenClaw atualizado: Atualização