Skip to content

Deploy OpenClaw na Oracle Cloud com Nginx e Telegram

Guia de instalação do OpenClaw em uma VM Oracle Cloud (4 oCPU Ampere, 24 GB RAM, 150 GB storage) com Nginx como proxy reverso, SSL via Certbot, Telegram como canal de comunicação, integração com Google Workspace via gog e modelos locais via Ollama.

Pré-requisitos

  • VM Oracle Cloud provisionada e acessível via SSH
  • Docker e Docker Compose instalados
  • Entrada DNS tipo A apontando o subdomínio para o IP público da VM
  • Portas 80 e 443 liberadas no Security List da Oracle Cloud e no firewall do SO

Estrutura do Projeto

openclaw-docker/
├── docker-compose.yml
├── .env
├── nginx/
│   └── openclaw.conf
├── config/
│   └── openclaw.json
├── data/
│   ├── state/
│   └── gogcli/
└── workspace/
    ├── AGENTS.md
    ├── SOUL.md
    └── memory/

Crie a estrutura:

mkdir -p openclaw-docker/{nginx,config,data/state,data/gogcli,workspace/memory}
cd openclaw-docker

Arquivos de Configuração

docker-compose.yml

services:
  openclaw:
    image: node:22-slim
    container_name: openclaw-gateway
    restart: unless-stopped
    working_dir: /app/workspace
    command: >
      sh -c "
        apt-get update -qq &&
        apt-get install -y -qq git curl &&
        rm -rf /usr/local/lib/node_modules/openclaw &&
        npm install -g openclaw@latest &&
        curl -L https://github.com/steipete/gogcli/releases/download/v0.12.0/gogcli_0.12.0_linux_arm64.tar.gz -o /tmp/gogcli.tar.gz &&
        cd /tmp && tar -xzf gogcli.tar.gz &&
        mv /tmp/gog /usr/local/bin/gog &&
        chmod +x /usr/local/bin/gog &&
        openclaw gateway --port 3000
      "
    env_file:
      - .env
    environment:
      - NODE_ENV=production
      - OPENCLAW_STATE_DIR=/app/state
      - OPENCLAW_CONFIG=/app/config/openclaw.json
      - GOG_KEYRING_PASSWORD=sua-senha-do-keyring
      - GOG_KEYRING_BACKEND=file
      - GOG_ACCOUNT=seu@gmail.com
      - OLLAMA_API_KEY=ollama-local
      - OLLAMA_HOST=http://172.18.0.1:11434
    volumes:
      - ./config:/app/config:ro
      - ./data/state:/app/state
      - ./workspace:/app/workspace
      - ./data/gogcli:/root/.config/gogcli
    expose:
      - "3000"
    ports:
      - "4000:4000"
    networks:
      - openclaw-internal
    healthcheck:
      test: ["CMD-SHELL", "node -e \"const http = require('http'); http.get('http://localhost:3000/health', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))\""]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 512M

  nginx:
    image: nginx:alpine
    container_name: openclaw-nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/openclaw.conf:/etc/nginx/conf.d/openclaw.conf:ro
      - /etc/letsencrypt:/etc/letsencrypt:ro
      - /var/www/certbot:/var/www/certbot:ro
    networks:
      - openclaw-internal
    depends_on:
      - openclaw

networks:
  openclaw-internal:
    driver: bridge

Nota: O gog é instalado automaticamente a cada inicialização do container. As credenciais OAuth ficam persistidas em ./data/gogcli, mapeado como volume. O Ollama roda no host e é acessado pelo container via 172.18.0.1:11434.


.env

# NUNCA commite este arquivo!

# Provedores de LLM
GEMINI_API_KEY=sua-chave-google-ai-studio
OPENROUTER_API_KEY=sua-chave-openrouter

# Canal Telegram
TELEGRAM_BOT_TOKEN=token-do-seu-bot-telegram

# Token do OpenClaw
OPENCLAW_TOKEN=seu-openclaw-token

# Google Workspace (gog)
GOG_KEYRING_PASSWORD=sua-senha-do-keyring
GOG_KEYRING_BACKEND=file
GOG_ACCOUNT=seu@gmail.com

# Ollama (modelos locais)
OLLAMA_API_KEY=ollama-local
OLLAMA_HOST=http://172.18.0.1:11434

# Otimizações para container/VPS
NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache
OPENCLAW_NO_RESPAWN=1

# Configurações do gateway
OPENCLAW_LOG_LEVEL=info
OPENCLAW_HOST=0.0.0.0
OPENCLAW_PORT=3000

Proteja o arquivo:

echo ".env" >> .gitignore
chmod 600 .env

config/openclaw.json

Este arquivo é usado como referência inicial, mas o OpenClaw persiste sua configuração ativa em /app/state/openclaw.json.

{
  "models": {
    "default": "openrouter/google/gemini-2.0-flash-001",
    "providers": {
      "google": {
        "apiKey": "${GEMINI_API_KEY}"
      },
      "openrouter": {
        "apiKey": "${OPENROUTER_API_KEY}"
      }
    }
  },
  "gateway": {
    "host": "0.0.0.0",
    "port": 3000
  },
  "channels": {
    "telegram": {
      "enabled": true,
      "token": "${TELEGRAM_BOT_TOKEN}",
      "dmPolicy": "open",
      "allowFrom": ["*"],
      "groupPolicy": "open"
    }
  },
  "workspace": {
    "path": "/app/workspace"
  },
  "memory": {
    "enabled": true,
    "path": "/app/state/memory"
  },
  "logging": {
    "level": "info",
    "file": "/app/state/logs/gateway.log"
  }
}

workspace/SOUL.md

Personalize conforme sua necessidade. Inclua a seção de ferramentas Google para que o agente saiba usar o gog:

# SOUL.md
Você é um assistente pessoal operando via Telegram.

## Ferramentas Google Workspace
- Você tem acesso COMPLETO ao Google Workspace via ferramenta `exec` usando o comando `gog`
- O binário `gog` está disponível em `/usr/local/bin/gog`
- As variáveis `GOG_KEYRING_PASSWORD` e `GOG_ACCOUNT` já estão configuradas — nunca peça senha ou conta
- Serviços disponíveis: Gmail, Calendar, Drive, Docs, Sheets, Slides, Contacts, Tasks, Chat, Classroom, Forms, AppScript
- Exemplos de uso:
  - `gog calendar list` — listar calendários
  - `gog calendar events primary --from <iso> --to <iso>` — listar eventos
  - `gog gmail search "<query>"` — buscar emails
  - `gog gmail send --to <email> --subject "<assunto>" --body "<mensagem>"` — enviar email
  - `gog drive search "<query>"` — buscar arquivos no Drive
  - `gog contacts list` — listar contatos
  - `gog sheets get <sheetId> "Tab!A1:D10"` — ler planilha
- Nunca diga que não tem acesso ao Google Workspace — use sempre o `exec` com `gog`
- Confirme com o usuário antes de enviar emails, criar ou modificar eventos e arquivos

workspace/AGENTS.md

# AGENTS.md
Workspace do OpenClaw em Docker.

## Regras
- Mantenha logs em memory/
- Use paths relativos dentro do workspace

Certificado SSL

Instalar o Certbot

sudo apt update && sudo apt install certbot -y
sudo mkdir -p /var/www/certbot

Configurar o Nginx apenas com HTTP (temporário)

Crie nginx/openclaw.conf somente com o bloco HTTP para que o Certbot possa validar o domínio:

server {
    listen 80;
    server_name seu.subdominio.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

Subir o Nginx

docker compose up -d nginx

Emitir o certificado

sudo certbot certonly --webroot \
  -w /var/www/certbot \
  -d seu.subdominio.com \
  --email seu@email.com \
  --agree-tos --non-interactive

Os certificados serão salvos em /etc/letsencrypt/live/seu.subdominio.com/.


Nginx com HTTPS

Substitua o conteúdo de nginx/openclaw.conf pela versão completa com suporte a OAuth callback do gog:

server {
    listen 80;
    server_name seu.subdominio.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name seu.subdominio.com;

    ssl_certificate     /etc/letsencrypt/live/seu.subdominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/seu.subdominio.com/privkey.pem;

    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

    add_header X-Frame-Options SAMEORIGIN;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    # Rota para OAuth callback do gog (Google Workspace)
    location /oauth2/callback {
        proxy_pass         http://openclaw-gateway:4000;
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout    60s;
        proxy_connect_timeout 10s;
    }

    location / {
        proxy_pass         http://openclaw-gateway:3000;
        proxy_http_version 1.1;

        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_read_timeout    300s;
        proxy_connect_timeout  10s;
    }
}

Subir o Stack Completo

docker compose down && docker compose up -d

Verifique os logs:

docker compose logs -f openclaw

Teste o health:

curl https://seu.subdominio.com/health
# Esperado: {"ok":true,"status":"live"}

Configuração do State

O OpenClaw gera o arquivo /app/state/openclaw.json automaticamente na primeira execução. Execute o setup inicial:

docker compose exec openclaw openclaw setup
docker compose exec openclaw openclaw doctor --fix

Em seguida, ajuste o state para usar o modelo correto via OpenRouter, bind em todas as interfaces, políticas abertas do Telegram e modelos Ollama disponíveis. Crie o arquivo no host:

cat > /tmp/state.json << 'EOF'
{
  "meta": {
    "lastTouchedVersion": "2026.3.13",
    "lastTouchedAt": "2026-03-16T00:00:00.000Z"
  },
  "agents": {
    "defaults": {
      "workspace": "/app/workspace",
      "model": "openrouter/google/gemini-2.0-flash-001",
      "compaction": {
        "mode": "safeguard"
      }
    }
  },
  "commands": {
    "native": "auto",
    "nativeSkills": "auto",
    "restart": true,
    "ownerDisplay": "raw"
  },
  "channels": {
    "telegram": {
      "enabled": true,
      "dmPolicy": "open",
      "allowFrom": ["*"],
      "groupPolicy": "open",
      "streaming": "partial"
    }
  },
  "gateway": {
    "mode": "local",
    "bind": "lan",
    "port": 3000,
    "auth": {
      "mode": "token",
      "token": "seu-token-gerado-pelo-setup"
    },
    "trustedProxies": ["172.18.0.0/16"],
    "controlUi": {
      "allowedOrigins": [
        "https://seu.subdominio.com",
        "https://app.openclaw.ai"
      ]
    }
  },
  "models": {
    "providers": {
      "ollama": {
        "baseUrl": "http://172.18.0.1:11434/v1",
        "apiKey": "ollama-local",
        "api": "openai-completions",
        "models": [
          { "id": "gemma3:12b", "name": "Gemma 3 12B (local)", "contextWindow": 131072, "maxTokens": 8192 },
          { "id": "qwen2.5:14b", "name": "Qwen 2.5 14B (local)", "contextWindow": 131072, "maxTokens": 8192 },
          { "id": "mistral:7b", "name": "Mistral 7B (local)", "contextWindow": 32768, "maxTokens": 8192 },
          { "id": "llama3.1:8b", "name": "Llama 3.1 8B (local)", "contextWindow": 131072, "maxTokens": 8192 }
        ]
      }
    }
  }
}
EOF

Importante: o token em gateway.auth.token é gerado automaticamente pelo openclaw setup. Para verificar o token ativo, execute: bash docker compose exec openclaw openclaw dashboard

Copie o arquivo para o container e reinicie:

docker cp /tmp/state.json openclaw-gateway:/app/state/openclaw.json
docker compose down && docker compose up -d

Verifique o modelo ativo:

docker compose logs openclaw | grep "agent model"
# Esperado: agent model: openrouter/google/gemini-2.0-flash-001

Acesso ao Control UI

O Control UI fica disponível em https://seu.subdominio.com. Na primeira conexão de um novo browser, o gateway exige aprovação do dispositivo.

Aprovar o dispositivo

Acesse a URL no browser e aguarde alguns segundos. Em seguida, liste os dispositivos pendentes:

docker compose exec openclaw openclaw devices list

Aprove pelo Request ID:

docker compose exec openclaw openclaw devices approve <requestId>

Após aprovação, o browser terá acesso permanente ao painel (a menos que os dados do browser sejam limpos).


Integração com Google Workspace (gog)

O gog é um CLI que permite ao agente acessar Gmail, Calendar, Drive, Docs, Sheets, Contacts e outros serviços Google. Ele é instalado automaticamente pelo docker-compose.yml a cada inicialização do container, e as credenciais OAuth ficam persistidas no volume ./data/gogcli.

Pré-requisitos no Google Cloud Console

  1. Acesse console.cloud.google.com e crie um projeto
  2. Ative as APIs necessárias em APIs e Serviços → Biblioteca:
  3. Gmail API
  4. Google Calendar API
  5. Google Drive API
  6. (demais APIs que quiser usar)
  7. Configure a Tela de Consentimento OAuth:
  8. Tipo: Externo
  9. Preencha nome do app e email de suporte
  10. Adicione seu email como usuário de teste em Público-alvo
  11. Crie as credenciais em APIs e Serviços → Credenciais:
  12. Clique em Criar credenciais → ID do cliente OAuth
  13. Tipo: Aplicativo da Web
  14. Origens JavaScript autorizadas: https://seu.subdominio.com
  15. URIs de redirecionamento autorizados: https://seu.subdominio.com/oauth2/callback
  16. Baixe o JSON das credenciais

Copiar credenciais para a VPS

scp /caminho/local/client_secret_*.json ubuntu@sua-vps:/home/ubuntu/

Copiar credenciais para o container

docker cp ~/client_secret_*.json openclaw-gateway:/app/state/google-credentials.json

Autenticar com o Google

Execute o comando abaixo — ele iniciará um servidor OAuth temporário na porta 4000:

docker compose exec -it openclaw bash -c "gog auth credentials /app/state/google-credentials.json && gog auth login --services=all --listen-addr=0.0.0.0:4000 --redirect-host=seu.subdominio.com --force-consent"

Acesse no browser:

http://SEU_IP_PUBLICO:4000

Clique em Connect with Google, faça login e autorize todos os serviços. Quando a tela de confirmação aparecer, a autenticação foi concluída.

Quando solicitado no terminal:

Enter passphrase to unlock "/root/.config/gogcli/keyring":

Digite a senha definida em GOG_KEYRING_PASSWORD no .env.

Verificar autenticação

docker compose exec openclaw bash -c "gog calendar list"

Se listar seus calendários sem pedir senha, está funcionando corretamente.

Habilitar a skill gog no Control UI

Acesse o Control UI → Skills → encontre gog → clique em Enable.

Serviços disponíveis

Com o gog autenticado, o agente tem acesso a:

Serviço Exemplo de comando
Calendar gog calendar events primary --from 2026-03-19T00:00:00 --to 2026-03-19T23:59:59
Gmail gog gmail search "is:unread"
Drive gog drive search "relatório"
Contacts gog contacts list
Sheets gog sheets get <sheetId> "Aba!A1:D10"
Docs gog docs cat <docId>

Modelos Locais com Ollama

O Ollama roda diretamente no host da VPS (fora do Docker) e é acessado pelo container OpenClaw via rede interna Docker (172.18.0.1).

Instalação

curl -fsSL https://ollama.com/install.sh | sh

Verifique:

ollama --version
ollama list

Modelos recomendados para 4 oCPU ARM + 24 GB RAM

Modelo Tamanho RAM necessária Melhor uso
llama3.1:8b ~5 GB 8 GB Uso geral, conversação
gemma3:12b ~8 GB 10 GB Raciocínio, multimodal
qwen2.5:14b ~9 GB 12 GB Código, análise técnica
mistral:7b ~4 GB 6 GB Tarefas rápidas
nomic-embed-text ~274 MB 1 GB Embeddings para memória semântica

Instale os modelos desejados:

ollama pull llama3.1:8b
ollama pull gemma3:12b
ollama pull qwen2.5:14b
ollama pull mistral:7b
ollama pull nomic-embed-text

Verificar acesso do container ao Ollama

docker compose exec openclaw bash -c "curl -s http://172.18.0.1:11434/api/tags | head -c 100"

Se retornar a lista de modelos, a conectividade está correta.

Listar modelos disponíveis no OpenClaw

docker compose exec openclaw openclaw models list 2>&1 | grep -i ollama

Os modelos aparecerão com o prefixo ollama/:

ollama/gemma3:12b    text  128k  no  yes
ollama/llama3.1:8b  text  128k  no  yes
ollama/mistral:7b   text   32k  no  yes
ollama/qwen2.5:14b  text  128k  no  yes

Trocar de modelo

Via Telegram ou Control UI, use o comando /model:

/model ollama/llama3.1:8b

Para voltar ao modelo padrão:

/model openrouter/google/gemini-2.0-flash-001

Ou para resetar ao padrão definido no state:

/model reset

Recomendações de uso

Em CPU pura (sem GPU), os modelos Ollama produzem cerca de 5–15 tokens/segundo, o que torna a conversa interativa lenta. Use o modelo certo para cada situação:

Situação Modelo recomendado
Conversação geral, agenda, Gmail openrouter/google/gemini-2.0-flash-001 (padrão)
Tarefas privadas que não podem sair da VPS ollama/llama3.1:8b
Análise técnica de código privado ollama/qwen2.5:14b
Embeddings de memória semântica nomic-embed-text (configurar no OpenClaw)
Experimentos e aulas de IA Ollama diretamente no terminal da VPS

Importante: modelos Ollama sem suporte a tool calling (como gemma3:12b) retornam erro does not support tools quando usados no OpenClaw, pois o agente depende de chamadas de ferramenta para funcionar. Prefira llama3.1:8b ou qwen2.5:14b para uso interativo.

Comandos úteis do Ollama

# Listar modelos instalados
ollama list

# Baixar novo modelo
ollama pull <modelo>

# Remover modelo
ollama rm <modelo>

# Testar modelo diretamente no terminal
ollama run llama3.1:8b

# Ver status do serviço
systemctl status ollama

# Reiniciar o serviço
sudo systemctl restart ollama

Renovação Automática do SSL

sudo crontab -e

Adicione a linha:

0 3 * * * certbot renew --quiet && docker compose -f /home/ubuntu/openclaw-docker/docker-compose.yml restart nginx

Comandos Úteis

# Ver logs em tempo real
docker compose logs -f openclaw

# Reiniciar o gateway após mudanças no state
docker compose restart openclaw

# Parar tudo
docker compose down

# Subir tudo
docker compose up -d

# Verificar status dos containers
docker compose ps

# Entrar no container
docker compose exec openclaw bash

# Ver token e URL do dashboard
docker compose exec openclaw openclaw dashboard

# Listar dispositivos pareados
docker compose exec openclaw openclaw devices list

# Verificar autenticação do gog
docker compose exec openclaw bash -c "gog calendar list"

# Listar todos os modelos disponíveis
docker compose exec openclaw openclaw models list --all 2>&1 | grep -E "ollama|openrouter|default"

Fluxo de Funcionamento

Telegram ──► OpenClaw Gateway (porta 3000, rede interna Docker)
Internet ──► :443 ──► Nginx ──► openclaw-gateway:3000
OAuth    ──► :443/oauth2/callback ──► Nginx ──► openclaw-gateway:4000
Container ──► 172.18.0.1:11434 ──► Ollama (host)

O OpenClaw recebe mensagens do Telegram via polling, processa com o modelo configurado (Gemini 2.0 Flash via OpenRouter por padrão) e responde diretamente no chat. Para requisições ao Google Workspace, o agente usa o gog via ferramenta exec. Para modelos locais, o container acessa o Ollama rodando no host via rede interna Docker.