# RTCloud — documentação completa > RTCloud é uma hospedagem em nuvem brasileira para bots (Discord, Telegram, WhatsApp), sites, APIs e bancos de dados gerenciados (PostgreSQL, MySQL, MongoDB e Redis). Painel em português, deploy por ZIP ou GitHub (com deploy automático a cada push), API pública, pagamento por Pix Automático, subdomínio grátis em rtsystems.app, domínio próprio, snapshots, logs e métricas ao vivo e uma assistente de IA (ReactorAI) que lê os logs e sugere correções. Servidores AMD EPYC com NVMe e proteção DDoS. O painel também é aplicativo: Android, iPhone, iPad, Windows, Mac e Linux. Assistentes como Claude, ChatGPT e Cursor se conectam à conta pelo servidor MCP. Site: https://rtcloud.com.br · Documentação: https://docs.rtcloud.com.br · API: https://docs.rtcloud.com.br/referencia-api ## Planos - **Free**: 512 MB de RAM, 1 vCPU, até 1 aplicações, 0 bancos de dados — grátis (teste) - **Spark**: 1 GB de RAM, 1 vCPU, até 4 aplicações, 0 bancos de dados — R$ 16,24/mês - **Steel**: 2 GB de RAM, 2 vCPU, até 8 aplicações, 0 bancos de dados — R$ 32,49/mês - **Carbon**: 4 GB de RAM, 4 vCPU, até 16 aplicações, 4 bancos de dados — R$ 58,49/mês - **Ruby**: 8 GB de RAM, 4 vCPU, até 32 aplicações, 8 bancos de dados — R$ 110,49/mês - **Volt**: 16 GB de RAM, 8 vCPU, até 64 aplicações, 16 bancos de dados — R$ 233,99/mês - **Apex**: 32 GB de RAM, 16 vCPU, até 128 aplicações, 32 bancos de dados — R$ 389,87/mês - **Obsidian Shard**: 48 GB de RAM, 16 vCPU, até 192 aplicações, 48 bancos de dados — R$ 584,87/mês - **Obsidian Blade**: 96 GB de RAM, 16 vCPU, até 384 aplicações, 96 bancos de dados — R$ 1.169,87/mês - **Obsidian Forge**: 160 GB de RAM, 16 vCPU, até 640 aplicações, 96 bancos de dados — R$ 1.949,87/mês - **Obsidian Bastion**: 224 GB de RAM, 16 vCPU, até 896 aplicações, 96 bancos de dados — R$ 2.729,87/mês - **Obsidian Citadel**: 288 GB de RAM, 16 vCPU, até 1152 aplicações, 96 bancos de dados — R$ 3.509,87/mês - **Obsidian Monolith**: 384 GB de RAM, 16 vCPU, até 1536 aplicações, 96 bancos de dados — R$ 4.679,87/mês - **Obsidian Sovereign**: 512 GB de RAM, 16 vCPU, até 2048 aplicações, 96 bancos de dados — R$ 6.239,87/mês - **Obsidian Eternal**: 768 GB de RAM, 16 vCPU, até 3072 aplicações, 96 bancos de dados — R$ 9.359,87/mês ## Status da plataforma Fonte ao vivo: https://rtcloud.com.br/status · JSON: https://rtcloud.com.br/api/public/status Situação em 2026-11-08T22:05:25.367Z: **Todos os sistemas operacionais**. Disponibilidade nos últimos 90 dias: 99,96%. - Site, painel e API: operacional (90 dias: 99,78%) - Hospedagem das aplicações: operacional (90 dias: 100,00%) - Armazenamento de arquivos: operacional (90 dias: 100,00%) - ReactorAI: operacional (90 dias: 99,96%) - E-mails: operacional (90 dias: 100,00%) - Pagamentos via Pix: operacional (90 dias: 100,00%) - Bot do Discord: operacional (90 dias: 99,98%) Serviços de terceiros (não mudam a situação geral): - Cloudflare: operacional — Funcionando. Instabilidade só em partes que a RTCloud não usa (CDN Cache Purge, Spectrum) — sem efeito por aqui. 7 de 30 pontos da rede no Brasil desviando o tráfego para o vizinho mais próximo — rotina, sem queda dos sites. - GitHub: operacional — Funcionando normalmente. - Discord: operacional — Funcionando normalmente. - Google: operacional — Funcionando normalmente. Como é medido: a cada minuto o painel abre o site pelo endereço público e confere a hospedagem das aplicações, o armazenamento e a ReactorAI; e-mails a cada 10 minutos; pagamentos e o bot do Discord pelo funcionamento real. O bot do Discord também confere o site de fora. Terceiros (Cloudflare, GitHub, Discord, Google) são lidos das páginas oficiais a cada 5 minutos, contando só o que a RTCloud usa. As aplicações dos clientes rodam separadas do painel: uma instabilidade no painel não derruba bots, sites e APIs no ar. ## Guia para iniciantes Fonte: https://docs.rtcloud.com.br/guia-para-iniciantes O que é a RTCloud, o que dá para hospedar aqui e como sair do zero em dez minutos. A RTCloud hospeda o seu projeto num servidor que fica ligado 24 horas por dia. Você envia o código, a plataforma instala as dependências, liga o processo e mantém ele de pé. Não é preciso saber configurar servidor, Linux ou Docker. ### O que dá para hospedar - Bots de Discord, Telegram e WhatsApp - APIs e back-ends em Node.js, Python, Go, PHP, Java, Ruby, Rust e .NET - Sites e painéis (React, Next.js, Vue, Astro, HTML puro) - Automações e workers que rodam em segundo plano - Bancos de dados gerenciados (MongoDB, PostgreSQL, MySQL e Redis) ### Os três conceitos que você precisa entender - **Aplicação** — é o seu projeto rodando. Cada aplicação tem seu próprio espaço, seus arquivos e sua memória. - **Memória (RAM)** — o quanto a aplicação pode usar. Um bot simples vive bem com 256 MB; um site precisa de 512 MB no mínimo. - **Plano** — o total de memória que a sua conta tem para dividir entre as aplicações. Um plano de 1 GB comporta quatro bots de 256 MB, ou dois sites de 512 MB. ### Seu primeiro deploy, em cinco passos 1. Deixe o projeto pronto na sua máquina, com o arquivo de dependências (package.json no Node, requirements.txt no Python). 2. Compacte a pasta do projeto em um .zip. Não precisa incluir node_modules — a plataforma instala tudo. 3. No painel, abra **Deploy**, arraste o .zip e escolha se é um bot ou um site. 4. Confira o arquivo principal que o painel detectou (index.js, main.py…) e a memória. 5. Clique em publicar e acompanhe o log ao vivo até aparecer “no ar”. > **É normal o primeiro deploy demorar mais** — A primeira publicação instala todas as dependências do zero. As próximas são bem mais rápidas porque só os arquivos mudam. ## Como criar uma aplicação Fonte: https://docs.rtcloud.com.br/criar-aplicacao O passo a passo do envio do pacote, o que o painel detecta sozinho e o que você precisa informar. Criar uma aplicação é enviar um .zip com o seu projeto. A RTCloud lê o pacote, identifica a linguagem, encontra o arquivo principal e monta o ambiente. ### Preparando o pacote - Compacte o **conteúdo** do projeto, não a pasta acima dele — o arquivo principal precisa ficar na raiz do .zip ou num caminho que você informe. - Inclua o arquivo de dependências: `package.json` (Node), `requirements.txt` ou `pyproject.toml` (Python), `go.mod` (Go), `composer.json` (PHP). - Não precisa incluir `node_modules`, `.venv`, `.git` nem pastas de build. O painel remove tudo isso antes de enviar, o que deixa o pacote muito menor. > **O pacote preparado pode ter no máximo 100.0 MB** — O limite é medido depois da limpeza automática. Se o seu pacote passar disso, quase sempre há mídia (vídeo, áudio, imagens grandes) ou um banco de dados dentro do projeto — esses arquivos devem ficar fora do código. ### O que o painel detecta sozinho - A linguagem e a versão adequada do runtime - O arquivo principal (index.js, main.py, server.js, app.js…) - As dependências que faltam declarar no arquivo de dependências - A porta em que o seu código escuta — e reescreve para a porta da plataforma - Variáveis do arquivo `.env` incluído no pacote ### O que você informa | Campo | Para que serve | | --- | --- | | Nome | Como a aplicação aparece no painel. | | Tipo | Bot (roda em segundo plano) ou Site/API (recebe acessos por um endereço). | | Subdomínio | Só para sites. Define o endereço público da aplicação. | | Memória | Quanto do seu plano essa aplicação reserva. Mínimo de 256 MB para bot e 512 MB para site. | | Versão da linguagem | Deixe em “recomendada” a menos que o seu projeto exija uma versão específica. | ## Como hospedar um bot Fonte: https://docs.rtcloud.com.br/hospedar-bot Discord, Telegram e WhatsApp: o que muda em cada um e o erro que derruba quase todo bot novo. Um bot é uma aplicação que roda em segundo plano e não recebe acessos por um endereço. Ele se conecta sozinho ao serviço (Discord, Telegram, WhatsApp) e fica escutando. > **O erro que derruba quase todo bot novo** — O token não pode estar escrito no código. Além de ser um risco de segurança, qualquer atualização do projeto sobrescreve o arquivo. Guarde o token em Variáveis de Ambiente e leia com process.env no código. ### Discord ```javascript const { Client, GatewayIntentBits } = require("discord.js"); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], }); client.once("ready", () => { console.log(`Bot online como ${client.user.tag}`); }); // O token vem das Variáveis de Ambiente, nunca do código. client.login(process.env.DISCORD_TOKEN); ``` No portal do Discord, ative os Privileged Gateway Intents que o seu bot usa (Message Content, Server Members). Sem eles o bot conecta mas não recebe eventos — e o log fica silencioso, o que confunde muita gente. ### Telegram Bots de Telegram funcionam em dois modos. Em *polling*, o bot pergunta ao Telegram se há mensagens novas — é o modo mais simples e funciona sem configurar nada. Em *webhook*, o Telegram avisa o seu servidor; nesse caso a aplicação precisa ser do tipo Site, ter um endereço público e escutar na porta 80. ### WhatsApp Bibliotecas que abrem um navegador (whatsapp-web.js, Venom, Puppeteer) funcionam: o navegador já vem instalado no ambiente. Duas exigências práticas: - Suba o navegador com o argumento `--no-sandbox` — sem ele o processo não inicia dentro de container. - Reserve 512 MB ou mais de memória. Um navegador headless sozinho já consome perto de 300 MB. - O QR Code aparece no console da aplicação, na aba Logs. Escaneie a partir dali. ```javascript const client = new Client({ authStrategy: new LocalAuth(), puppeteer: { args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"], }, }); ``` > **Bibliotecas sem navegador consomem muito menos** — Para WhatsApp, bibliotecas que falam direto com o protocolo (como Baileys) rodam confortavelmente em 256 MB, contra os 512 MB ou mais de uma solução com navegador. ## Aplicativo da RTCloud Fonte: https://docs.rtcloud.com.br/aplicativo Como instalar a RTCloud no Android, no iPhone, no iPad, no Windows, no Mac e no Linux, e o que muda em relação ao site. O aplicativo da RTCloud é o seu painel em tela cheia, com ícone no aparelho e sem barra de endereço. Suas aplicações, deploys, bancos, domínios, assinatura e a página de status abrem dentro dele, com a mesma conta do site. > **Onde baixar** — Tudo fica em rtcloud.com.br/aplicativo, com uma página e um passo a passo ilustrado para cada aparelho. O app é grátis para todas as contas. | Aparelho | Como instala | Requisito | Página | | --- | --- | --- | --- | | Android | APK assinado pela RTCloud | Android 6.0 ou mais novo | rtcloud.com.br/aplicativo/android | | iPhone e iPad | Pelo Safari, sem baixar arquivo | iOS e iPadOS 15 ou mais novo | rtcloud.com.br/aplicativo/iphone | | Windows | Instalador que não pede administrador | Windows 10 ou 11 | rtcloud.com.br/aplicativo/windows | | Mac e Linux | Pelo navegador | Chrome, Edge ou Safari 17+ | rtcloud.com.br/aplicativo/mac-e-linux | ### Android 1. Entre em rtcloud.com.br/aplicativo/android e toque em Baixar para Android. 2. Abra o arquivo. Na primeira vez, o Android pede permissão: toque em Configurações e ligue Permitir desta fonte. 3. Volte para a instalação e toque em Instalar. 4. Abra a RTCloud pelo ícone e entre com a sua conta. Se o Play Protect avisar, toque em Mais detalhes e em Instalar mesmo assim: ele avisa em todo app instalado fora da loja. ### iPhone e iPad 1. Abra rtcloud.com.br pelo Safari e toque em Compartilhar, na barra de baixo. 2. Role a lista de opções e toque em Adicionar à Tela de Início. 3. Toque em Adicionar, no canto de cima. 4. Abra a RTCloud pelo ícone da tela de início. Abriu o link pelo Instagram ou pelo WhatsApp? Toque em ⋯ e escolha Abrir no Safari primeiro: o navegador desses apps não tem a opção de adicionar à tela de início. ### Windows 1. Entre em rtcloud.com.br/aplicativo/windows e clique em Baixar para Windows. 2. Abra o arquivo. Se aparecer O Windows protegeu o computador, clique em Mais informações e em Executar assim mesmo. 3. Clique em Instalar. A RTCloud vai para o Menu Iniciar e para a Área de Trabalho. 4. Abra pelo Menu Iniciar e entre com e-mail e senha, ou com Google, GitHub ou Discord, pelo seu navegador. ### Mac e Linux 1. Entre em rtcloud.com.br pelo Chrome, pelo Edge ou pelo Safari do Mac. 2. No Chrome e no Edge, clique no ícone de instalar, no fim da barra de endereço. No Safari do Mac: Arquivo, Adicionar ao Dock. 3. Confirme em Instalar. 4. A RTCloud abre numa janela própria, com ícone no Dock ou na barra de tarefas. ### Preciso baixar de novo a cada atualização? Não. O app abre o painel direto do servidor, então cada novidade chega nele sozinha. Só o ícone e a tela de abertura ficam no aparelho: quando mudarem, baixe de novo e instale por cima. No iPhone, apague o atalho e adicione de novo. ### O que muda em relação ao site - A página de status e a documentação abrem dentro do app, sem ir para o navegador. - Sem internet, o app mostra uma tela própria e volta sozinho quando a conexão voltar. - A conta é a mesma: tudo que você faz no app aparece no site, e vice-versa. - Cada aparelho aparece em Meu perfil, na aba Segurança, onde dá para encerrar a sessão quando quiser. ## Conectar ferramentas MCP Fonte: https://docs.rtcloud.com.br/mcp Como conectar Claude Code, Grok, Codex, ChatGPT, Cursor e outros à RTCloud pelo servidor MCP para cuidar das suas aplicações em linguagem normal. O servidor MCP liga a sua ferramenta de IA à sua conta da RTCloud. Depois de conectar, você pede em linguagem normal e ela lê os logs, confere métricas, corrige arquivos e reinicia a aplicação, sempre dentro do que você autorizou. Vale para todas as contas, sem custo. > **Endereço do servidor** — https://rtcloud.com.br/mcp. É o mesmo para todas as ferramentas. > **Passo a passo com imagens** — Cada ferramenta tem um tutorial próprio, com as telas que vão aparecer. No site, abra Ferramentas. No painel, abra Ferramentas MCP, em Recursos Avançados. ### Com quais ferramentas funciona | Assistente | Onde conectar | Como entra | | --- | --- | --- | | Claude Code | Terminal: claude mcp add | Autorização | | Grok Build | Terminal: grok mcp add | Autorização | | Codex | Terminal: codex mcp add e codex mcp login | Autorização | | Claude | Customize, Connectors, Add custom connector | Autorização | | Grok | grok.com/connectors, New Connector, Custom | Autorização | | ChatGPT | chatgpt.com/plugins, Add custom MCP server | Autorização | | VS Code | Paleta de comandos: MCP: Add Server | Autorização | | Cursor | Arquivo .cursor/mcp.json | Autorização | | Google Antigravity | Arquivo mcp_config.json | Autorização | | Devin Desktop | Customize, MCPs, arquivo mcp_config.json | Autorização | | Outros | Streamable HTTP ou a ponte mcp-remote | Chave MCP | ### Claude Code em dois comandos ```bash claude mcp add --transport http --scope user rtcloud https://rtcloud.com.br/mcp claude ``` Rode no terminal, não em uma conversa. Depois, dentro do Claude Code, digite /mcp, escolha rtcloud, selecione Authenticate e autorize no navegador. ### Grok Build em dois comandos ```bash grok mcp add --transport http rtcloud https://rtcloud.com.br/mcp grok ``` A autorização abre no navegador no primeiro uso. Se não abrir, digite /mcps dentro do Grok Build, escolha rtcloud e aperte a tecla i. ### Com chave MCP Quem conecta sem navegador gera uma chave em Ferramentas MCP e envia no cabeçalho Authorization, no transporte Streamable HTTP. Veja o modelo para arquivo de configuração: ```json { "mcpServers": { "rtcloud": { "url": "https://rtcloud.com.br/mcp", "headers": { "Authorization": "Bearer ${env:RTCLOUD_MCP_KEY}" } } } } ``` ### O que pedir - Meu bot caiu. Olha os logs e me diz o motivo. - Quanto de memória o meu site usou nos últimos 7 dias? - Corrige esse erro no index.js e reinicia a aplicação. - Por que o meu domínio ainda não está ativo? - Cria um snapshot antes de mexer no código. > **Confira antes de aprovar** — Mudanças valem na hora. Leia o que a ferramenta vai fazer antes de aprovar, principalmente ao desligar, restaurar um snapshot, apagar arquivo ou trocar variáveis. A lista completa está em Ferramentas do servidor MCP, e as permissões em Permissões e segurança do MCP. ## Ferramentas do servidor MCP Fonte: https://docs.rtcloud.com.br/mcp-ferramentas Tudo que uma ferramenta de IA pode fazer na sua conta pelo servidor MCP, com a permissão e o limite de cada ação. A ferramenta só enxerga as ferramentas das permissões que você liberou. Todas respeitam o seu papel em cada aplicação e o seu plano. ### Aplicações | Ferramenta | O que faz | Permissão | Por minuto | | --- | --- | --- | --- | | list_applications | Lista as aplicações | apps:read | 30 | | get_application_status | CPU, memória, rede e tempo no ar | apps:read | 20 | | get_application_logs | Logs recentes, com credenciais mascaradas | apps:read | 10 | | get_deployments | Histórico de publicações | apps:read | 15 | | get_metrics_history | Média e pico de CPU e memória | apps:read | 10 | | start_application | Liga a aplicação | apps:control | 10 | | stop_application | Desliga a aplicação | apps:control | 10 | | restart_application | Reinicia a aplicação | apps:control | 10 | | commit_application | Publica um .zip de até 1 MB | files:write | 3 | ### Arquivos | Ferramenta | O que faz | Permissão | Por minuto | | --- | --- | --- | --- | | list_files | Lista uma pasta | files:read | 20 | | read_file | Lê um arquivo, em páginas de 64 KB | files:read | 20 | | write_file | Cria ou substitui um arquivo de até 256 KB | files:write | 10 | | patch_file | Edita trechos: se um falhar, nada é gravado | files:write | 10 | | rename_file | Renomeia ou move | files:write | 10 | | delete_file | Apaga arquivo ou pasta | files:write | 5 | ### Variáveis, snapshots e bancos | Ferramenta | O que faz | Permissão | Por minuto | | --- | --- | --- | --- | | list_env_vars | Só os nomes das variáveis | envs:read | 10 | | set_env_vars | Adiciona, troca e remove variáveis | envs:write | 6 | | list_snapshots | Lista os snapshots | snapshots:read | 15 | | create_snapshot | Cria um snapshot | snapshots:write | 4 | | restore_snapshot | Restaura, guardando antes o estado atual | snapshots:write | 3 | | list_databases | Lista os bancos, sem senha | databases:read | 15 | | get_database | Motor, versão, memória e estado | databases:read | 15 | | start_database | Liga o banco | databases:write | 6 | | stop_database | Desliga o banco | databases:write | 6 | | restart_database | Reinicia o banco | databases:write | 6 | ### Domínio e rede | Ferramenta | O que faz | Permissão | Por minuto | | --- | --- | --- | --- | | list_dns_records | Registros DNS e o motivo de não estarem ativos | apps:read | 10 | | get_network_analytics | Requisições, visitantes e bytes | apps:read | 5 | | get_network_errors | Erros HTTP por código e caminho | apps:read | 5 | | get_network_performance | Tempos de resposta e caminhos lentos | apps:read | 5 | | purge_network_cache | Limpa o cache do site | apps:write | 5 | ### Conta e ajuda Estas não pedem permissão e não leem dados das aplicações. | Ferramenta | O que faz | Por minuto | | --- | --- | --- | | get_account | Plano, memória e limites da conta | 20 | | search_docs | Busca na documentação | 15 | | read_doc | Lê um artigo da documentação | 15 | | get_platform_status | Situação da plataforma agora | 10 | | list_plans | Planos da RTCloud | 10 | ### Limites - 60 chamadas por minuto em cada conexão, somando todas as ferramentas. - Passou do limite, a ferramenta responde TOOL_RATE_LIMITED com quantos segundos esperar. - Projetos maiores que 1 MB são publicados pelo painel, pela API ou pelo GitHub. ## Permissões e segurança do MCP Fonte: https://docs.rtcloud.com.br/mcp-seguranca O que escolher ao conectar uma ferramenta, o que nunca chega à IA, como limitar a algumas aplicações e como cancelar o acesso. ### Permissões | Permissão | O que libera | | --- | --- | | apps:read | Status, logs, métricas, publicações, DNS e relatórios do site | | apps:control | Ligar, desligar e reiniciar aplicações | | apps:write | Limpar o cache do site | | files:read | Listar e ler arquivos | | files:write | Criar, editar, renomear, apagar e publicar | | envs:read | Só os nomes das variáveis | | envs:write | Criar, trocar e remover variáveis | | snapshots:read | Listar snapshots | | snapshots:write | Criar e restaurar snapshots | | databases:read | Estado e métricas dos bancos | | databases:write | Ligar, desligar e reiniciar bancos | Na tela de autorização, só as permissões de leitura vêm marcadas. Para liberar alterações, clique em Liberar tudo ou marque uma a uma. Para uma chave MCP, escolha Somente leitura, Leitura e alteração ou Sob medida. ### Limitar a algumas aplicações Ao gerar uma chave MCP, marque Limitar a algumas aplicações e bancos. O que ficar de fora nem aparece para a ferramenta, e qualquer tentativa de usar responde RESOURCE_NOT_ALLOWED. ### O que nunca chega à ferramenta - Valores de variáveis de ambiente: ela vê só os nomes. - Arquivos .env, chaves privadas e certificados. O .env.example pode ser lido. - Senha e endereço de conexão dos bancos de dados. - Dados de cobrança e de pagamento. - Credenciais reconhecidas em logs e arquivos, que saem mascaradas. > **O mascaramento ajuda, mas não adivinha tudo** — Senha com formato incomum pode passar. Mantenha segredos nas variáveis de ambiente, nunca no código nem nos logs. ### O que só você faz, no painel - Excluir aplicações e bancos de dados. - Ver senhas, tokens e valores de variáveis. - Mudar de plano, pagar e cuidar da conta. - Convidar pessoas para a equipe. ### Snapshot de segurança Antes de restaurar, a RTCloud guarda um snapshot do estado atual. Se ele ainda estiver sendo gerado, a restauração não acontece e a resposta é SNAPSHOT_NOT_READY: é só repetir em cerca de 2 minutos. ### Cuidado com instruções escondidas Logs e arquivos podem conter texto escrito por outras pessoas, como um visitante do seu site. Um texto assim pode tentar dar ordens à ferramenta. Por isso, confira as ações antes de aprovar e prefira permissões de leitura em quem não precisa alterar nada. ### Acompanhar e cancelar - Toda alteração feita por ferramenta aparece em Meu perfil, Atividade, no filtro Ferramentas MCP, com o nome da conexão. Leituras não são registradas. - Para cancelar, abra Ferramentas MCP, em Recursos Avançados, e clique em Desconectar ou Revogar. O acesso acaba na hora. - A conexão por autorização vale por 90 dias. Depois disso, é só conectar de novo. - Chaves MCP começam com rtm_ e só funcionam no servidor MCP. Chaves da API começam com rtc_ e não funcionam nele. - Cada conta tem até 10 chaves ativas, somando as da API e as das ferramentas. A mesma ferramenta pode ficar conectada em dois computadores ao mesmo tempo. ## Deploy e atualização Fonte: https://docs.rtcloud.com.br/fazer-deploy Como publicar uma versão nova, o que acontece em cada etapa e por que o log ao vivo importa. Publicar uma versão nova de uma aplicação existente chama-se commit. Ele está na aba **Commit** dentro da aplicação e substitui os arquivos sem apagar o que já está lá. ### As etapas de uma publicação 1. **Preparando** — o painel abre o seu .zip, remove pastas pesadas, confere o arquivo principal e ajusta a porta. 2. **Enviando** — o pacote sobe. A barra mostra bytes reais transferidos. 3. **Instalando** — o ambiente instala as dependências do seu arquivo de dependências. É a etapa mais demorada. 4. **Iniciando** — o processo sobe e imprime as primeiras linhas no console. 5. **No ar** — a aplicação está de pé e respondendo. > **O log é o do seu container, ao vivo** — As linhas que aparecem durante o deploy não são mensagens genéricas da plataforma: é a saída real do seu processo. Se uma dependência falhar ao instalar, o erro exato aparece ali na hora. ### Envio somando arquivos Um commit ADICIONA e SOBRESCREVE arquivos, mas não remove o que não veio no pacote. Isso é proposital — protege dados que a aplicação gravou em disco. Se você renomeou ou apagou arquivos no projeto, remova as versões antigas pelo Explorador de Arquivos. ### Projeto completo ou arquivo solto | Você envia | O que acontece | | --- | --- | | Um .zip | Passa pelo preparo automático (limpeza de pastas pesadas, conferência do arquivo principal e da porta) e é extraído na raiz da aplicação. Limite de 100.0 MB. | | Um arquivo qualquer | Vai do jeito que está, sem preparo, para a pasta de destino que você escolher (em branco = raiz). Serve para trocar um `config.json` ou um único script sem reenviar o projeto inteiro. | A opção **Reiniciar a aplicação depois do commit** vem ligada. Desligue quando estiver enviando vários arquivos seguidos e reinicie só no último — o processo relê tudo de uma vez. ### Deixando arquivos de fora com .rtcloudignore Crie um arquivo chamado `.rtcloudignore` na raiz do seu .zip, com a mesma sintaxe do `.gitignore`. O que casar com as regras não é enviado. O arquivo principal e o arquivo de dependências nunca são ignorados, mesmo que uma regra os pegue. ```text # .rtcloudignore .env.local logs/ *.log tests/ !tests/fixtures/essencial.json ``` > **Pastas pesadas já saem sozinhas** — `node_modules`, `.git`, `__pycache__`, `.venv` e similares são removidos pelo preparo automático — não precisa listá-los. O ambiente reinstala as dependências a partir do seu arquivo de dependências. ### Publicação automática pelo GitHub Na aba Deploy você pode conectar um repositório. A partir daí, todo push na branch escolhida publica uma versão nova sozinho. O histórico de cada publicação, com as etapas e os arquivos alterados, fica na aba **Publicações**. ## Ligar, desligar e reiniciar Fonte: https://docs.rtcloud.com.br/ligar-desligar-reiniciar O que cada botão faz de verdade e quando usar cada um. | Ação | O que acontece | Quando usar | | --- | --- | --- | | Ligar | Cria o container e inicia o processo. Uma aplicação parada há dias demora mais porque o ambiente é remontado. | Depois de uma parada manual ou de uma queda. | | Reiniciar | Encerra o processo e sobe de novo, na mesma versão dos arquivos. | Para o processo reler arquivos ou variáveis que você acabou de mudar. | | Desligar | Encerra o processo. A memória volta para o seu plano e os arquivos ficam intactos. | Para liberar memória para outra aplicação sem apagar nada. | > **Mudou uma variável de ambiente? Reinicie.** — Variáveis são lidas quando o processo sobe. Salvar uma variável nova não afeta um processo que já está rodando — só o reinício aplica. O **reinício automático** (na aba Ambiente) faz a plataforma subir a aplicação sozinha sempre que o processo cair. É útil em produção, mas com uma ressalva: se a aplicação cai por um erro de código logo na inicialização, o reinício automático vira um laço de quedas. Nesse caso, desligue-o, corrija o erro e ligue de novo. Sem abrir a aplicação: na lista de Aplicações, o menu **⋯** de cada cartão tem ligar, reiniciar e parar, favoritar (as favoritas aparecem primeiro), atalhos para console, arquivos, monitor e configurações, copiar o ID e excluir. O cartão mostra também **no ar há** — quanto tempo o processo está ligado desde a última partida; um reinício recomeça a conta. ## Console e logs Fonte: https://docs.rtcloud.com.br/ver-logs Onde ver o que a sua aplicação está imprimindo, em tempo real, e como usar isso para achar problemas. A aba **Logs** mostra a saída da sua aplicação em tempo real: cada linha aparece no instante em que o seu código a imprime. É a mesma coisa que você veria no terminal rodando o projeto na sua máquina. ### O que aparece ali - Tudo que o seu código escreve com `console.log`, `print`, `fmt.Println` e equivalentes - Erros não tratados, com o rastro completo - As mensagens da instalação de dependências durante um deploy - Avisos do próprio runtime (memória, versões incompatíveis) > **Limpar o console é permanente** — O botão Limpar grava um ponto de corte: o histórico anterior não volta nem ao recarregar a página, nem em outro dispositivo. As linhas novas continuam aparecendo normalmente. ### Boas práticas de log - Imprima uma linha quando a aplicação terminar de subir — é o que confirma que ela está pronta. - Nunca imprima token, senha ou chave. O console é visível para todo mundo que tem acesso à aplicação. - Prefira uma linha por evento a blocos gigantes. Log muito verboso esconde o erro no meio do ruído. - Em produção, registre erros com contexto: o que estava sendo feito quando falhou. ## Explorador de arquivos Fonte: https://docs.rtcloud.com.br/arquivos Ver, editar, criar, renomear e apagar arquivos dentro da aplicação, direto do painel. A aba **Arquivos** mostra o disco da sua aplicação como ele está agora. Dá para abrir e editar um arquivo, criar pastas, renomear, apagar e baixar. > **Editar aqui não reinicia a aplicação** — O arquivo é gravado na hora, mas o processo que já está rodando continua com a versão antiga em memória. Reinicie a aplicação para a mudança valer. ### O que fica de fora da lista Alguns arquivos de configuração interna da plataforma não aparecem no explorador. Tudo que eles controlam — memória, versão da linguagem, comando de início, reinício automático, subdomínio — está na aba **Ambiente**, que é o lugar certo para mexer nisso. ### Arquivos que a aplicação grava Dados escritos em disco pela aplicação (um arquivo JSON, um SQLite, uploads) sobrevivem a reinícios e a novos deploys. Eles NÃO sobrevivem à exclusão da aplicação. Para dados que você não pode perder, use um banco de dados gerenciado ou faça snapshots. ## Variáveis de ambiente Fonte: https://docs.rtcloud.com.br/variaveis-de-ambiente O lugar certo para tokens, senhas e chaves — e como lê-los no código de cada linguagem. Variáveis de ambiente guardam configurações que não devem ficar no código: tokens, senhas de banco, chaves de API, endereços de webhook. Elas ficam na aba **Variáveis de Ambiente** e são injetadas no processo quando ele sobe. ### Como ler no código ```javascript // Node.js const token = process.env.DISCORD_TOKEN; # Python import os token = os.environ["DISCORD_TOKEN"] // Go token := os.Getenv("DISCORD_TOKEN") // PHP $token = getenv('DISCORD_TOKEN'); ``` > **Reinicie depois de alterar** — As variáveis entram no processo no momento em que ele sobe. Uma variável salva agora só passa a valer no próximo reinício. ### Variáveis que a plataforma define sozinha | Variável | Valor | Por quê | | --- | --- | --- | | PORT | 80 | É a porta em que a RTCloud procura o seu site. Escutar em outra porta faz a aplicação subir e não responder no domínio. | | HOST | 0.0.0.0 | Escutar em localhost aceitaria conexões apenas de dentro do próprio container. | ### Importando do seu .env Se o seu .zip incluir um arquivo `.env`, o painel importa as variáveis dele automaticamente no primeiro deploy. Em commits seguintes, apenas as variáveis novas são adicionadas — as que você já ajustou pelo painel não são sobrescritas. ## Endereços e domínio próprio Fonte: https://docs.rtcloud.com.br/dominios O endereço que vem junto, como trocar pelo seu próprio domínio e o que criar no DNS. Toda aplicação do tipo Site nasce com um endereço da RTCloud e certificado SSL automático — algo como `meusite.rtsystems.app`. Você escolhe o nome no deploy, ou depois, e ele já funciona. Não precisa comprar domínio para colocar um site no ar. ### Quando trocar pelo seu domínio O endereço da RTCloud serve para sempre. Trocar faz sentido quando o site é de um cliente, de uma marca, ou quando você quer o endereço curto que já divulgou. A troca é reversível e leva alguns minutos. ### Como trocar 1. No menu, abra **Domínios**, escreva o seu domínio e escolha a aplicação. 2. O painel mostra **um registro** para você criar. Cada valor tem botão de copiar. 3. Vá ao painel onde o domínio foi registrado — Cloudflare, Hostinger, Registro.br, GoDaddy — e crie o registro exatamente como está. 4. Volte e clique em **Já criei — verificar agora**. > **Na Cloudflare, o proxy fica desligado** — Se o seu domínio usa Cloudflare, o registro precisa ficar com a RTCloud CINZA (DNS only). Com o proxy ligado, o site responde com erro e o certificado nunca é emitido — é o motivo mais comum de um domínio não subir. > **Os dois endereços funcionam juntos** — Ligar o seu domínio não desliga o endereço `.rtsystems.app`: os dois continuam respondendo pelo mesmo site. Pode divulgar o seu domínio sem medo de quebrar links antigos. > **O SSL é emitido sozinho** — Assim que o DNS aponta certo, o certificado é emitido e renovado automaticamente. Você não gera, não instala e não renova nada. ### Links com o endereço certo (URL automática) Se o seu app monta links sozinho — documentação da API, Swagger, `base_url`, e-mails com link —, ele precisa saber o endereço público. A RTCloud entrega isso de três jeitos, e as respostas do seu site já saem com o endereço público mesmo quando o código usa outro. - **Variável `RTCLOUD_URL`** — criada em todo deploy de site, com o endereço completo (ex.: `https://meusite.rtsystems.app`). É o jeito mais simples: `process.env.RTCLOUD_URL` no Node, `os.environ["RTCLOUD_URL"]` no Python. - **Cabeçalhos de proxy** — cada visita chega com `X-Forwarded-Host`, `X-Forwarded-Proto: https` e `Forwarded`. Frameworks que leem esses cabeçalhos montam o endereço certo sozinhos: no Express, `app.set("trust proxy", true)`; no FastAPI/uvicorn, `--proxy-headers --forwarded-allow-ips="*"`; no Laravel, `TrustProxies`. - **Cabeçalho `X-RTCloud-Public-URL`** — o endereço público pronto, para quem prefere ler direto do pedido. - **Domínio próprio** — com o seu domínio ligado, o pedido já chega com ele: nada a configurar. ### Se não conectar - **Esperou pouco.** A propagação leva de alguns minutos a uma hora. O botão de verificar pode ser usado quantas vezes quiser. - **O proxy está ligado.** Na Cloudflare, deixe a RTCloud cinza. - **O registro ficou no nome errado.** Para `meusite.com` o nome costuma ser `@`; para `app.meusite.com`, é `app`. - **Sobrou um registro antigo.** Se já existia um registro com o mesmo nome apontando para outro lugar, apague-o — dois registros iguais brigam entre si. > **Domínios com acento funcionam** — Pode escrever `café.com.br` ou `promoção.com` normalmente. O painel mostra o domínio como você escreveu e, ao lado, a forma técnica que vai no DNS (`xn--caf-dma.com.br`). Alguns provedores pedem essa forma técnica no campo do nome — é só copiar. ### Requisitos - Domínio próprio está disponível a partir do plano Carbon. - A aplicação precisa ser do tipo Site. - O domínio precisa estar registrado e com o DNS sob o seu controle. ## Relatórios de acesso e desempenho Fonte: https://docs.rtcloud.com.br/relatorios-de-acesso Quantas pessoas entraram, de onde vieram, o que deu erro e quanto tempo esperaram. Sites e APIs têm relatórios da camada que atende o domínio antes da sua aplicação. Eles respondem perguntas que o log do processo não responde — inclusive sobre requisições que nem chegaram ao seu código. ### O que cada aba mostra | Aba | Responde | | --- | --- | | Analytics, Tráfego | Requisições, visitas, banda, países, rotas, referências, provedores, sistemas, navegadores, códigos de status, bots e IPs do site. | | Analytics, Recursos | CPU, memória e rede da aplicação, com histórico de 24 horas ou 7 dias. | | Erros | Requisições que terminaram em erro, por status e por caminho. | | Desempenho | Quanto tempo o visitante esperou, separando o tempo da rede do tempo do seu código. | ### Filtrar, comparar e acompanhar - **Filtro em tudo:** toque em um país, rota, navegador, status ou IP e todos os painéis passam a mostrar só aquele tráfego. - **Comparar:** ligue a comparação para ver cada número contra o período anterior. - **Período:** 1 hora, 6 horas, 24 horas, 3 dias, 7 dias ou o intervalo que você escolher, dentro dos últimos 7 dias. - **Atualização:** o relatório é renovado a cada 5 minutos, e a tela lê de novo sozinha a cada minuto. O selo no topo mostra quando foi a última medição. - **IPs:** ficam ocultos ao abrir a página. O dono da aplicação pode mostrar os endereços completos com um toque. > **E os bots?** — Bots não recebem visitas por um domínio, então não existem requisições, países ou rotas para contar. O que existe de verdade é a rede do processo, na aba Analytics: tudo o que o bot enviou e recebeu. ### Como ler os percentis A mediana (p50) é a experiência típica: metade dos visitantes esperou menos que isso. O p95 é a experiência ruim: 5% esperaram mais. Otimizar olhando só a média esconde justamente as pessoas que estão sofrendo — é o p95 que revela isso. > **Borda alta e origem baixa** — Quando o tempo da aplicação está bom e o total está ruim, o problema não é o seu código: é peso de página, rede ou cache mal aproveitado. ## Monitor do site (e do bot) e página de status Fonte: https://docs.rtcloud.com.br/monitor-do-site A RTCloud abre o seu site como um visitante, recebe o sinal de vida do seu bot, avisa quando algo cair e mantém uma página de status para os seus clientes. Todo site hospedado na RTCloud ganha um monitor ligado, sem configurar nada. O servidor da RTCloud abre o endereço do site de tempos em tempos — como um visitante faria — e guarda o que viu. Ele pega o caso que o aviso de queda da aplicação não pega: o processo está ligado, mas o site está quebrado. ### De quanto em quanto tempo | Plano | Teste | | --- | --- | | Teste grátis | a cada 10 min | | Spark e Steel | a cada 5 min | | Carbon, Quartz e Ruby | a cada 2 min | | Onyx, Volt, Titan e Apex | a cada 1 min | ### O que conta como fora do ar | Situação | Quando | | --- | --- | | No ar | O site respondeu (inclusive 3xx, 401, 403 e 404 — é o seu site respondendo). | | Lento | Respondeu, mas levou 4 segundos ou mais para começar a responder. | | Com erro | Respondeu 5xx, ou abriu sem a palavra que você pediu para conferir. | | Fora do ar | Não respondeu em 12 segundos, o endereço não tem aplicação respondendo, ou o domínio/certificado falhou. | > **Sem alarme falso** — A queda só é registrada depois de 2 testes seguidos com falha — depois da primeira falha, o próximo teste vem em 1 minuto. Quando o site não responde nada (tempo esgotado, DNS, conexão), são 3 testes: antes de contar, a RTCloud confere a própria rede, repete o teste na hora e confere o domínio por fora — se o problema for da verificação, nada é contado. Durante uma publicação, um reinício ou um ligar (até 4 minutos depois), falha não abre queda. Aplicação desligada por você ou com plano vencido fica com o monitor pausado e não conta contra a porcentagem. O "no ar há" conta desde que a aplicação ligou — o mesmo tempo do topo da tela. Só uma queda confirmada recomeça a conta; uma falha isolada, que nem chegou a abrir queda, não zera nada. ### Avisos - No sino do painel e no privado do Discord (escolha em /avisos, no tipo Quedas), quando cai e quando volta. - Por e-mail, se a opção estiver marcada na aba Monitor. - Se o próprio processo caiu, você recebe só o aviso de queda da aplicação — sem aviso repetido. ### Configurar 1. Abra a aplicação e entre na aba Monitor. 2. Em Caminho testado, use uma rota leve do seu site, como / ou /health. 3. Opcional: em Palavra que precisa aparecer, coloque um texto que sempre está na página — pega página em branco ou de erro com código 200. 4. Use Testar agora para conferir na hora. ### Página pública de status Ligue Página pública na aba Monitor e escolha o endereço: o seu site ganha uma página em status.rtcloud.com.br/seu-endereco, com a situação ao vivo, a porcentagem no ar, as barras dos últimos 90 dias, o tempo de resposta e o histórico de quedas. Ela não mostra o caminho testado nem detalhes técnicos. Há também um selo para o README ou o rodapé do site: ```markdown [![Status](https://status.rtcloud.com.br/seu-endereco/badge.svg)](https://status.rtcloud.com.br/seu-endereco) ``` Na mesma aba fica o selo **Hospedado na RTCloud**, para o rodapé do site ou o README do projeto — opcional e grátis. As versões escura, clara e compacta, com o código pronto para colar, estão em rtcloud.com.br/selo. ### Monitor do bot (sinal de vida) Bot não tem endereço para abrir — então o monitor funciona ao contrário: o seu bot chama um endereço secreto da RTCloud a cada intervalo (1, 5, 10, 30 ou 60 minutos, você escolhe). Se o sinal atrasar além do intervalo mais uma folga, a queda abre e você é avisado. É o que pega o bot ligado mas travado, ou desconectado do Discord — o painel mostra online, o monitor sabe que não está. 1. Abra o bot no painel e entre na aba Monitor. 2. Copie o código pronto (discord.js, discord.py ou curl) — ele já vem com o seu endereço secreto e o intervalo escolhido. 3. Cole no código do bot e publique. O monitor começa no primeiro sinal; antes disso nenhum aviso sai. ```javascript const SINAL = "https://rtcloud.com.br/api/ping/SEU-ENDERECO-SECRETO"; client.once("ready", () => { const sinal = () => client.isReady() && fetch(SINAL).catch(() => {}); sinal(); setInterval(sinal, 5 * 60_000); }); ``` - O bot também pode avisar um problema: chame o mesmo endereço com `?falha=o motivo` — a queda abre na hora, com o texto que ele mandou. - Trate o endereço como senha. Vazou? Use **Gerar endereço novo** na aba Monitor: o antigo para de valer na hora. - Bot desligado por você, plano vencido ou painel religando não contam como queda — o prazo do sinal recomeça. - A página pública e o selo também existem para bots ("funcionando" / "sem sinal"). ### Erros depois de publicar (Carbon para cima) Entre 12 e 45 minutos depois de cada publicação — pelo painel, pelo Discord, pela API ou pelo GitHub — a RTCloud compara os erros 5xx de TODAS as rotas do site com o mesmo tempo antes da publicação. Se subirem muito (pelo menos 20, e mais que o triplo de antes), você recebe o aviso com a rota que mais errou e o atalho para voltar um snapshot. > **O monitor não substitui o seu log** — Ele diz QUE o site caiu e QUANDO. O porquê está nos logs da aplicação e na aba Erros. ## Bancos de dados gerenciados Fonte: https://docs.rtcloud.com.br/bancos-de-dados Criar um MongoDB, PostgreSQL, MySQL ou Redis e conectar a sua aplicação nele. Um banco gerenciado roda separado da sua aplicação, com o próprio endereço e as próprias credenciais. Ele continua de pé mesmo quando a aplicação é reiniciada, atualizada ou apagada — que é exatamente o que dados importantes precisam. ### Motores disponíveis | Motor | Versão | Memória mínima | Bom para | | --- | --- | --- | --- | | MongoDB | 8 | 1 GB | Bots e APIs — estrutura flexível, sem esquema. | | PostgreSQL | 17 | 1 GB | Dados relacionais, consultas complexas. | | MySQL | 9 | 1 GB | Relacional clássico, ampla compatibilidade. | | Redis | 8 | 512 MB | Cache, filas e sessões. | Todo banco novo nasce na versão mais recente da linha (a da tabela), com as correções de segurança em dia. Bancos criados antes continuam na versão em que foram criados. > **A senha aparece uma única vez** — A senha e a string de conexão são exibidas apenas na tela de criação. Copie e guarde na hora. Depois disso só é possível gerar uma nova senha — e isso derruba todas as aplicações conectadas até você atualizar a variável de ambiente delas. ### Certificado de conexão (TLS) PostgreSQL, MySQL e MongoDB gerenciados aceitam conexão cifrada. Baixe o arquivo na tela do banco, em **Baixar certificado (.pem)** — ele vem pronto para uso, com o certificado e a chave que identificam a sua aplicação. > **O certificado pode ser baixado de novo — mas é credencial** — Diferente da senha, ele não some depois da criação: baixe quantas vezes precisar. Mas o arquivo traz a chave privada que identifica a sua aplicação no banco, então guarde com o mesmo cuidado — nunca o publique em repositório aberto. ```javascript // Node.js + PostgreSQL — TLS com o certificado do banco const fs = require("fs"); const { Client } = require("pg"); const pem = fs.readFileSync("./certificado.pem", "utf8"); const client = new Client({ connectionString: process.env.DATABASE_URL, // o certificado é conferido; o nome do servidor não (o endereço é da RTCloud) ssl: { ca: pem, cert: pem, key: pem, checkServerIdentity: () => undefined }, }); await client.connect(); ``` ### Conectando a aplicação 1. Crie o banco e copie a string de conexão. 2. Abra a aplicação → **Variáveis de Ambiente**. 3. Crie uma variável (por exemplo `DATABASE_URL`) com a string de conexão. 4. Se for usar verificação de certificado, envie o arquivo `.pem` junto com o projeto. 5. Reinicie a aplicação. ```javascript // Node.js + MongoDB const { MongoClient } = require("mongodb"); const client = new MongoClient(process.env.DATABASE_URL); await client.connect(); # Python + PostgreSQL import os, psycopg conn = psycopg.connect(os.environ["DATABASE_URL"]) ``` Bancos gerenciados estão disponíveis a partir do plano Carbon. A memória do banco sai do total do seu plano, igual a uma aplicação. ### Acompanhando o uso A aba Uso de cada banco mostra a memória e a CPU das últimas 24 horas (uma amostra a cada 5 minutos), com a linha da memória reservada desenhada no gráfico, e o volume de rede do dia. Se a memória passar de 90% do reservado, o aviso aparece ali mesmo — aumente a memória em Ajustes antes que o banco fique lento ou reinicie. ## Snapshots e backups Fonte: https://docs.rtcloud.com.br/snapshots Como guardar uma cópia completa da aplicação e voltar atrás depois de um deploy ruim. Um snapshot é uma cópia de todos os arquivos da aplicação no momento em que foi criado. Ele serve para duas coisas: baixar tudo para a sua máquina e voltar a aplicação a um estado anterior. ### Criando Na aba **Snapshots** da aplicação, clique em criar. Aplicações grandes levam alguns minutos; nesse caso o snapshot aparece na lista sozinho quando terminar — não é preciso ficar clicando de novo. ### Restaurando Restaurar substitui os arquivos atuais pelos do snapshot. Reinicie a aplicação depois para o processo assumir os arquivos restaurados. > **Snapshot não é banco de dados** — Um snapshot congela os arquivos no momento da criação. Dados gravados depois disso não estão nele. Para dados que mudam o tempo todo, use um banco gerenciado — que tem os próprios snapshots. Snapshots automáticos diários estão disponíveis a partir do plano Carbon. Nos planos abaixo, você pode criar snapshots manualmente quando quiser. ## Problemas comuns Fonte: https://docs.rtcloud.com.br/problemas-comuns Os oito casos que respondem pela maioria dos chamados, com a causa e a correção de cada um. ### A aplicação sobe e cai em seguida Na quase totalidade dos casos, o processo terminou por um erro logo na inicialização. Abra a aba Logs: a última linha antes da parada diz o motivo. Os campeões são token ausente, dependência não declarada e erro de sintaxe. ### O site sobe mas o endereço não abre O código precisa escutar em 0.0.0.0 na porta 80. Escutar em localhost aceita conexões apenas de dentro do container, e escutar em outra porta faz o roteador não encontrar o processo. ```javascript // certo app.listen(process.env.PORT || 80, "0.0.0.0"); // errado — não responde no domínio app.listen(3000, "localhost"); ``` ### “Cannot find module” ou “ModuleNotFoundError” A biblioteca não está no arquivo de dependências. Adicione-a ao `package.json` ou ao `requirements.txt` e publique de novo. Instalar na sua máquina não basta: o ambiente monta as dependências a partir desse arquivo. ### A aplicação foi derrubada por falta de memória O processo passou do limite da aplicação e foi encerrado. Duas saídas: aumentar a memória da aplicação (se o plano permitir) ou reduzir o consumo. As causas mais comuns são carregar arquivos grandes inteiros na memória, guardar cache sem limite e navegador headless sem fechar as abas. ### O deploy falha dizendo que o pacote é grande demais O limite por envio é de 100.0 MB, medido depois da limpeza automática. Se o seu pacote passa disso, procure por vídeos, áudios, imagens não otimizadas ou um banco de dados dentro do projeto. ### Alterei uma variável e nada mudou Variáveis são lidas quando o processo sobe. Reinicie a aplicação. ### O bot conecta mas não responde a comandos No Discord, quase sempre é intent faltando: ative Message Content Intent no portal do desenvolvedor e reinicie. Verifique também as permissões do bot no servidor. ### Editei um arquivo e a aplicação não mudou O arquivo foi gravado, mas o processo em execução continua com a versão antiga carregada. Reinicie. ## Como interpretar os erros Fonte: https://docs.rtcloud.com.br/interpretar-erros O que cada tipo de mensagem quer dizer e onde procurar a causa real. ### Erros no console da aplicação | Mensagem | O que é | O que fazer | | --- | --- | --- | | Cannot find module / ModuleNotFoundError | Dependência não instalada. | Declare no arquivo de dependências e publique de novo. | | EADDRINUSE | Duas partes do código tentaram abrir a mesma porta. | Garanta um único listen na aplicação. | | ECONNREFUSED | Um serviço externo (banco, API) recusou a conexão. | Confira endereço, porta e se o serviço está de pé. | | JavaScript heap out of memory | O processo estourou a memória. | Aumente a memória ou reduza o que é carregado de uma vez. | | 401 / 403 de uma API externa | Credencial errada, expirada ou sem permissão. | Verifique a variável de ambiente e as permissões da chave. | ### Erros que aparecem para o visitante do site | Status | Significado | Onde investigar | | --- | --- | --- | | 404 | A rota não existe na aplicação. | Confira o caminho e se o arquivo subiu no pacote. | | 500 | O seu código lançou uma exceção. | O rastro está no console, na aba Logs. | | 502 / 503 | A aplicação não respondeu. | Ela caiu, está reiniciando ou não escuta na porta certa. | | 504 | A resposta demorou demais. | Alguma operação está travando — normalmente uma consulta lenta. | > **Na dúvida, pergunte ao assistente** — O assistente de IA lê o log real da sua aplicação e explica o erro em português, apontando a linha. Ele está na aba ReactorAI, dentro da aplicação. ## Correção de crash em 1 clique Fonte: https://docs.rtcloud.com.br/correcao-de-crash Quando a aplicação cai com um erro conhecido, o painel mostra exatamente o que mudar, aplica, reinicia e confere se funcionou. Com a aplicação fora do ar, a **Visão geral** e a aba **Logs** leem o log e procuram as causas de queda mais comuns. Quando reconhecem uma, aparece o cartão **Encontramos o motivo da queda**, com a linha do log que provou o diagnóstico e a mudança exata que resolve. ### O que ele corrige sozinho | Erro | Correção | | --- | --- | | Cannot find module 'x' (npm) | Adiciona o pacote ao package.json com a versão atual do npm | | No module named 'x' (Python) | Adiciona o pacote certo ao requirements.txt (ex.: cv2 → opencv-python) | | ERESOLVE / conflito de peer dependencies | Cria o .npmrc com legacy-peer-deps=true | | invalid ELF header / binário de outro sistema | Apaga o node_modules enviado — ele é reinstalado no Linux | | Cannot use import statement outside a module | Adiciona "type": "module" ao package.json | | Arquivo principal inexistente | Aponta o arquivo principal para o ponto de entrada encontrado | | Pacote exige Node mais novo | Muda para a versão mais recente e reconstrói o ambiente | | Scripts de instalação bloqueados | Libera o pacote em allowScripts no package.json | | Dependência instalada via Git | Troca pela versão publicada no npm | > **Só corrige o que consegue provar** — Um módulo que é arquivo do seu projeto nunca é oferecido como pacote para instalar, e o pacote sugerido precisa existir no registro. Se você editou o arquivo depois do diagnóstico, nada é sobrescrito: o diagnóstico é refeito. ### Depois de aplicar A aplicação reinicia (ou é reconstruída, quando a correção muda a versão) e o cartão acompanha o resultado: avisa quando funcionou, quando o mesmo erro voltou ou quando a aplicação não subiu. Casos que dependem de você — intents do Discord, token inválido, falta de memória — aparecem explicados, com o passo a passo. **Pedir ajuda à ReactorAI** abre a conversa já com o diagnóstico, a linha do log e a correção sugerida, para ela olhar o seu código junto. ## ReactorAI Fonte: https://docs.rtcloud.com.br/assistente-ia A assistente que lê o console e os arquivos da sua aplicação antes de responder. A **ReactorAI** não responde de memória: ela vai buscar. Quando você pergunta sobre um erro, ela abre o console daquela aplicação, lê as últimas linhas e responde apontando o que encontrou. Se a pergunta for sobre código, ela abre o arquivo. ### Onde encontrar - **Dentro de uma aplicação**, na aba ReactorAI — a conversa já sabe de qual aplicação você está falando. - **No menu lateral**, em ReactorAI — aqui você escolhe a aplicação num seletor, ou deixa em nenhuma para uma pergunta geral. ### O que ela consegue consultar - O status atual: se está no ar, uso de memória e de processador - As últimas linhas do console - A árvore de arquivos, busca no código, criar/editar/apagar/renomear - Ligar, parar, reiniciar e limpar o console quando você pedir - Suas aplicações, limites do plano e o mapa completo do painel ### Perguntas que funcionam bem - Por que minha aplicação caiu? - Explique o último erro do console - Como reduzo o uso de memória? - Meu plano dá conta do que eu preciso? > **Ela edita o projeto de verdade** — Se você pedir para ajeitar, criar ou corrigir, a ReactorAI grava o arquivo, reinicia e confere o log. Variáveis de ambiente ela não grava — ensina o caminho na aba Variáveis. Apagar aplicação, trocar plano e cobrança também ficam só no painel. > **Seus segredos são mascarados antes de sair** — Tokens, senhas e chaves que aparecem no console são substituídos automaticamente antes de qualquer coisa ser enviada. Mesmo assim, não cole credenciais no chat — para configurar segredos use a aba Variáveis de Ambiente. ### Histórico e cota As conversas ficam guardadas por **24 horas** e depois são apagadas — o prazo é curto de propósito, porque a conversa carrega trechos do seu console. Cada plano tem uma cota diária de uso, mostrada na barra abaixo do campo de escrever, e ela renova todo dia às 21h (horário de Brasília). ### Sem plano ou abaixo do Carbon A ReactorAI completa — que lê o console, abre arquivos e mexe no projeto — está disponível a partir do plano **Carbon**. Sem plano, no teste grátis ou nos planos Spark e Steel, ela continua respondendo **dúvidas sobre a RTCloud**: como fazer deploy, qual plano escolher, como funciona o Pix Automático, se um pagamento já caiu. Ela só não entra nas suas aplicações. ## Blob Storage: arquivos públicos e privados Fonte: https://docs.rtcloud.com.br/armazenamento Guarde imagens, vídeos e backups fora da aplicação: endereço público com CDN, arquivos privados, links temporários e de compartilhamento, pastas, regras e envios de até 10 GiB. O **Blob Storage** guarda arquivos fora da sua aplicação: a foto que o usuário envia, o relatório que o bot gera, a mídia do site, o backup do banco. Ele está incluso nos planos pagos — de 5 GB no Spark a 250 GB nos planos maiores — e não cobra por transferência. ### Por que não deixar dentro da aplicação - Arquivo dentro do pacote **some a cada novo deploy** — o container é recriado do zero. - Pacote grande demora mais para subir e conta contra o limite de envio. - Arquivo público no Blob é servido por CDN, então chega rápido para quem está longe. ### Público ou privado | | Público | Privado | | --- | --- | --- | | Endereço | Permanente: rtcloud.com.br/cdn/… | Não tem — só por link | | Para quê | Imagens do site, anexos do bot, arquivos que outros sistemas buscam | Documentos, backups, arquivos de clientes | | Como entregar | Copie o endereço | Link temporário ou link de compartilhamento | > **Trocar a visibilidade muda o endereço** — Tornar um arquivo privado tira o endereço público do ar em cerca de 1 minuto, e os links de compartilhamento dele param de funcionar. Envie arquivos sensíveis já como privados. ### Os três tipos de link | Tipo | Duração | Pode revogar? | Quando usar | | --- | --- | --- | --- | | Endereço público | Enquanto o arquivo for público | Tornando o arquivo privado | Incorporar em site e bot | | Link temporário | 1 minuto a 24 horas | Não | Entregar um arquivo agora (botão de download, e-mail) | | Link de compartilhamento | Até 30 dias | Sim | Mandar para uma pessoa, com limite de downloads e senha | O link de compartilhamento abre uma página da RTCloud com o nome do arquivo, o tamanho, a validade e o botão de baixar. Nos planos **Onyx, Volt, Titan e Apex** ele também pode pedir uma senha. O link temporário suporta vídeo e download retomável. ### Como enviar 1. Abra **Armazenamento** no menu lateral e entre na pasta desejada (ou crie uma em **Nova pasta**). 2. Arraste os arquivos para qualquer lugar da tela, ou use **Enviar arquivos**. Vários de uma vez, até 10 GiB cada. 3. Acompanhe a fila no canto da tela. Arquivos grandes sobem em partes: se a conexão cair, escolha o mesmo arquivo de novo e o envio continua de onde parou. 4. Clique no arquivo para copiar o endereço, gerar links, renomear, mover ou mudar a visibilidade. ### Regras de pasta Uma regra vale para tudo dentro de uma pasta: visibilidade e expiração padrão, cache, tamanho máximo, tipos aceitos e **exclusão automática** depois de N dias. Spark, Steel, Carbon, Quartz e Ruby têm 5 regras; Onyx, Volt e Titan têm 10; Apex tem 20. A exclusão automática só começa 24 horas depois de salvar — tempo de corrigir uma regra ampla demais. > **Recursos por plano** — Senha em link e metadados: Onyx em diante. Expiração abaixo de 7 dias e arquivos sem cache: Apex. Executáveis e instaladores (.exe, .apk, .bat…) não são aceitos. Com o plano vencido você ainda pode ver, baixar, tornar privado e excluir. ### Ações em lote Selecione vários arquivos para torná-los públicos ou privados, mudar a expiração, mover ou excluir de uma vez. O painel mostra o progresso e, se algum falhar, deixa repetir só os que falharam. ## Balanceamento de carga Fonte: https://docs.rtcloud.com.br/balanceamento Dois ou mais servidores no mesmo endereço: se um cair, o site continua no ar. **Balanceamento** é apontar o mesmo domínio para mais de uma aplicação. Os acessos são divididos entre elas e, quando uma sai do ar, o tráfego vai inteiro para as que continuam. Para quem visita o site, nada muda. ### Para que serve na prática - **Publicar sem derrubar o site.** Atualize uma instância enquanto a outra atende. - **Aguentar mais acesso.** Duas instâncias dividem o que uma sozinha não daria conta. - **Sobreviver a uma queda.** Se uma trava, a outra continua respondendo. ### Como ligar 1. Aponte seu domínio para a primeira aplicação, em **Domínios**. 2. Publique a segunda aplicação com o mesmo código. 3. Abra **Balanceamento**, encontre o domínio e toque em **Adicionar aplicação**. 4. Pronto: o domínio passa a dividir o tráfego. O DNS não muda. > **As instâncias não compartilham disco** — Cada aplicação tem o próprio sistema de arquivos. Se o seu código grava dados em disco, use um banco de dados gerenciado ou o Armazenamento — senão cada instância terá uma versão diferente da verdade. ### Como o tráfego é dividido - **Rodízio:** cada requisição vai para a próxima aplicação do grupo, sem sticky session. O que fica só na memória, como sessões locais, precisa ir para um banco de dados. - **Quando uma cai:** com a conexão recusada, qualquer requisição, inclusive POST, é atendida por outra aplicação do grupo. No caso mais raro em que o servidor responde com tempo esgotado, só requisições sem corpo (GET, HEAD) são reenviadas. - **Quando ela volta:** passa a receber requisições de novo, sem nenhuma ação sua. | Plano | Aplicações por domínio | | --- | --- | | Carbon e Ruby | até 2 | | Volt | até 5 | | Apex | até 10 | O balanceamento vem incluído com o domínio próprio: não há cobrança por requisição. O número em vigor na sua conta aparece na tela de Balanceamento. ## Como escolher um plano Fonte: https://docs.rtcloud.com.br/escolher-plano Quanta memória o seu projeto precisa e o que cada plano libera. O plano define quanta memória a sua conta tem para dividir entre as aplicações. Você escolhe quanto cada aplicação reserva; a soma não pode passar do total do plano. ### Quanta memória o seu projeto precisa | Projeto | Memória recomendada | | --- | --- | | Bot simples de Discord ou Telegram | 256 MB | | Bot com banco de dados e comandos pesados | 512 MB | | Bot de WhatsApp com navegador | 512 MB a 1 GB | | Site estático ou landing page | 512 MB | | API em produção | 512 MB a 1 GB | | Aplicação Next.js ou similar | 1 GB | | Banco de dados gerenciado | 512 MB (cache) a 1 GB | | API com muito tráfego, loja ou SaaS | 4 GB a 32 GB, com balanceamento entre instâncias | | Projeto de empresa acima de 32 GB | Obsidian, de 48 GB a 768 GB | > **Projeto grande** — Os planos de tabela chegam a 16 vCPU dedicadas e 32 GB de RAM (Apex), e o mesmo domínio pode ser atendido por até 10 instâncias com balanceamento de carga. Precisa de mais? O Obsidian é o plano empresarial: de 48 GB a 768 GB de RAM, escolhidos deslizando a memória na tela Mudar de plano e assinados por Pix, como qualquer plano. Acima de 768 GB, ou com termos de contrato próprios, a equipe monta com você. ### Os planos | Plano | Memória | Preço | Comporta | | --- | --- | --- | --- | | Spark | 1 GB | R$ 16,24/mês | até 4 bots ou 2 sites | | Steel | 2 GB | R$ 32,49/mês | até 8 bots ou 4 sites | | Carbon | 4 GB | R$ 58,49/mês | até 16 bots ou 8 sites | | Ruby | 8 GB | R$ 110,49/mês | até 32 bots ou 16 sites | | Volt | 16 GB | R$ 233,99/mês | até 64 bots ou 32 sites | | Apex | 32 GB | R$ 389,87/mês | até 128 bots ou 64 sites | ### Obsidian (empresarial) | Faixa | Memória | Preço | | --- | --- | --- | | Obsidian Shard | 48 GB | R$ 584,87/mês | | Obsidian Blade | 96 GB | R$ 1.169,87/mês | | Obsidian Forge | 160 GB | R$ 1.949,87/mês | | Obsidian Bastion | 224 GB | R$ 2.729,87/mês | | Obsidian Citadel | 288 GB | R$ 3.509,87/mês | | Obsidian Monolith | 384 GB | R$ 4.679,87/mês | | Obsidian Sovereign | 512 GB | R$ 6.239,87/mês | | Obsidian Eternal | 768 GB | R$ 9.359,87/mês | Todas as faixas têm 16 vCPU, 250 GB de armazenamento de arquivos, tudo liberado e suporte empresarial dedicado. A memória é uma só para dividir entre bots, sites e bancos de dados. ### A partir de qual plano cada recurso libera - **Spark** — hospedagem de bots e sites, console ao vivo, histórico de 24 h, explorador de arquivos, deploy pelo GitHub. - **Carbon** — banco de dados gerenciado, domínio próprio, relatórios de acesso, assistente de IA, snapshots automáticos, compartilhar acesso com a equipe. - **Ruby e acima** — tudo liberado, com mais memória e prioridade no suporte. > **Trocar de plano** — Subir de plano vale na hora: você paga a mensalidade do plano novo no Pix e os dias que sobraram do plano atual viram dias a mais nele. Descer também vale na hora: o vencimento continua o mesmo (sem devolução dos dias pagos), os recursos do plano maior saem na hora e, se as aplicações passarem do limite do plano menor, você escolhe quais continuam ligadas antes de confirmar. ## Assinatura e pagamento Fonte: https://docs.rtcloud.com.br/assinatura-e-pagamento Como funciona o Pix Automático, os períodos com desconto (3 meses, 6 meses e 1 ano), os recibos em PDF, o que acontece se atrasar e como cancelar. A RTCloud cobra por assinatura no **Pix Automático**, no período que você escolher: **mensal, 3 meses, 6 meses ou 1 ano**. Você paga o primeiro período e autoriza o débito no app do seu banco; a partir daí a renovação acontece sozinha, no mesmo período e no mesmo dia — sem gerar código novo nem lembrar da data. ### Períodos e descontos | Período | Desconto | Renovação | | --- | --- | --- | | Mensal | — | Todo mês | | 3 meses | 5% | A cada 3 meses | | 6 meses | 10% | A cada 6 meses | | 1 ano | 2 meses grátis (paga 10, leva 12) | Todo ano | O valor de cada período aparece na hora de assinar, já com o desconto e com quanto sai por mês. O período maior é pago de uma vez, no Pix — e continua **sem fidelidade**: você pode cancelar a renovação quando quiser. ### Assinando 1. Abra **Faturamento** no painel e clique em **Mudar de plano** (ou em **Evoluir**, no cartão do seu plano). 2. Escolha o plano — no Obsidian, deslize a memória — e o **período** (mensal, 3 meses, 6 meses ou 1 ano). O **Resumo da cobrança** mostra o valor exato do Pix, o desconto e até quando vale. 3. Na primeira assinatura, preencha os dados de cobrança (nome, CPF ou CNPJ, telefone e endereço): o Pix recorrente exige. Eles ficam salvos — e dá para clicar em **Salvar para depois** e pagar outra hora. 4. Escaneie o QR ou copie o código Pix e pague no aplicativo do seu banco, autorizando o Pix Automático. 5. Pronto. A liberação é automática — a tela avisa sozinha quando o pagamento cai, e o recibo em PDF chega no seu e-mail. > **Pode fechar a janela depois de pagar** — A confirmação não depende da página aberta: a plataforma confere o pagamento com o banco sozinha, a cada poucos minutos, mesmo com você desconectado. Se quiser acelerar, o botão **Já paguei — conferir agora** consulta o banco na hora. ### Como funciona a renovação - O débito acontece no período escolhido (todo mês, a cada 3 ou 6 meses, ou todo ano), no dia mostrado em **Próxima cobrança**. - Cada período pago estende o plano exatamente pelos meses dele, a partir do vencimento anterior — pagar alguns dias antes não faz você perder dias, e nada é cobrado duas vezes no mesmo ciclo. - Quer mudar de período (por exemplo, do mensal para o anual)? Escolha o novo período do mesmo plano: os meses novos entram no fim do que já está pago, e a renovação antiga é encerrada no primeiro pagamento — sem cobrança em dobro. - Subindo de plano, o que sobrava do atual vira dias a mais no novo, pelo valor que você pagou por mês (com o desconto do período, se tinha). - Três dias antes do débito você recebe um lembrete por e-mail. Não precisa fazer nada. - Se o banco atrasar a confirmação, suas aplicações continuam no ar durante a carência enquanto a cobrança é conferida. > **Dados de cobrança** — O Pix Automático pede nome, CPF ou CNPJ, telefone e endereço de quem paga. Você preenche uma vez e eles ficam em **Faturamento → Dados de cobrança**, onde dá para atualizar quando quiser. Os recibos saem com essa identificação — o que ajuda quem precisa pedir reembolso na empresa ou lançar a despesa na contabilidade. ### O que aparece em Faturamento - **Seu plano**: tempo restante, quando renova ou vence e a memória em uso - A renovação automática — ligada, com o valor e a data da próxima cobrança, ou o botão para ativar - **Assinatura e faturas**: a situação da assinatura e **Minhas faturas**, com o tipo de cada cobrança (assinatura, renovação automática ou avulsa) e o recibo em PDF - **Dados de cobrança** e o atalho para **mudar para um plano menor**, com o que fica de fora antes de você decidir ### Se uma cobrança não for confirmada Nada sai do ar de imediato. O banco tenta o débito de novo automaticamente por alguns dias e, com a renovação automática ligada, suas aplicações seguem funcionando durante a carência. Se mesmo assim o pagamento não entrar, as aplicações são desligadas — os arquivos ficam guardados — e você recebe um e-mail explicando. Assim que um pagamento cair, elas voltam ao ar sozinhas, do jeito que estavam. ### Trocando de plano Subir de plano vale na hora: você paga a mensalidade do plano novo no Pix e o que sobrou do ciclo atual vira dias a mais nele. - **Descer de plano** também vale na hora, sem Pix: o vencimento continua o mesmo e não há devolução dos dias já pagos. - Os recursos do plano maior (memória, vagas de aplicação, bancos, domínio próprio…) saem na hora — a tela mostra a lista antes de você confirmar. - Se as aplicações não couberem no plano menor, você escolhe quais continuam ligadas. As outras são desligadas e só religam quando couberem — diminuindo a memória, apagando outra ou subindo de plano. - Bancos de dados e domínio próprio que o plano menor não comporta precisam ser resolvidos antes: a tela avisa o que fazer. - A renovação automática do plano anterior é encerrada (ela cobraria o valor maior). Ative a do plano novo em Faturamento quando quiser. ### Cancelando O botão de cancelar a renovação está na própria tela Faturamento. Ele interrompe as cobranças futuras; o plano continua valendo até o fim do período já pago (nos períodos de 3, 6 ou 12 meses, até o fim deles — sem reembolso proporcional dos meses restantes, salvo nos casos previstos em lei). Depois disso as aplicações são desligadas, mas os arquivos não são apagados — voltam ao ar quando você assinar de novo. > **O cancelamento é definitivo** — Não existe reativar a mesma assinatura. Para voltar, é preciso assinar de novo — o que leva os mesmos dois cliques da primeira vez. ### Recibos e nota fiscal Todo pagamento confirmado gera um recibo em PDF, com número próprio, período coberto, identificação do Pix e os dados de quem pagou. Ele chega anexado no e-mail de confirmação e fica disponível em **Faturamento → Minhas faturas** para ver ou baixar a qualquer momento. > **O recibo não substitui NFS-e** — É um documento comercial de cobrança. Se você precisa de nota fiscal de serviço, fale com o suporte informando os dados da empresa. ### Paguei e o plano não liberou 1. Em **Faturamento**, clique em **Já paguei — conferir agora**. A plataforma consulta o banco na hora. 2. Se o banco ainda não confirmou, espere alguns minutos: a conferência automática continua rodando sozinha. 3. Ainda nada? Pergunte à **ReactorAI** — ela confere o pagamento da sua conta — ou abra um chamado com o comprovante do banco. ## Segurança Fonte: https://docs.rtcloud.com.br/seguranca Como proteger a sua conta, suas aplicações e as credenciais dos seus projetos. ### Sua conta - Use uma senha longa e exclusiva desta plataforma. - Prefira entrar com Google, GitHub ou Discord: a conta fica protegida pela verificação em duas etapas do provedor. - Não compartilhe login. Para dar acesso a alguém, use **Equipes** — assim cada pessoa entra com a própria conta e você controla o que ela pode fazer. - Confira as sessões ativas em Configurações e encerre o que não reconhecer. ### Suas credenciais - Token, senha e chave sempre em **Variáveis de Ambiente** — nunca no código, nunca em arquivo commitado. - Se um token vazou (apareceu num print, num repositório público, numa conversa), gire-o imediatamente. Considerar comprometido é sempre mais barato que descobrir depois. - Não imprima segredo no console: quem tem acesso à aplicação vê o log. - Use uma credencial por finalidade. Uma chave que faz tudo, quando vaza, entrega tudo. ### Sua aplicação - Valide toda entrada que vem de fora antes de usar em consulta, comando ou caminho de arquivo. - Mantenha as dependências atualizadas — a maior parte das invasões entra por biblioteca desatualizada. - Limite a taxa de requisições nos endpoints públicos. - Não confie em dado do cliente para decidir permissão: confira no servidor. ### O que a RTCloud faz do lado dela - Cada aplicação roda isolada, com memória e CPU próprias. - SSL automático em todos os endereços, renovado sem intervenção. - Proteção contra ataques de volume na camada que atende os domínios. - As credenciais da plataforma nunca chegam ao navegador. - Excluir uma aplicação pede uma verificação humana rápida antes de liberar o botão — um clique distraído ou um robô com a sua sessão não apagam nada. - O histórico de **Atividade** guarda o horário e o IP de cada ação na conta, para você reconhecer o que não fez. ## Boas práticas Fonte: https://docs.rtcloud.com.br/boas-praticas O que separa uma aplicação que dá trabalho de uma que roda sozinha. ### Encerre com elegância Quando a plataforma reinicia a aplicação, ela pede ao processo que termine. Tratar esse pedido evita perder trabalho em andamento. ```javascript process.on("SIGTERM", async () => { console.log("Encerrando com cuidado…"); await servidor.close(); await banco.disconnect(); process.exit(0); }); ``` ### Não guarde estado só na memória Um reinício apaga tudo que estava em memória. Fila, sessão e cache importantes devem viver num banco ou no disco da aplicação. ### Fixe a versão da linguagem quando tiver dependência compilada Bibliotecas com código compilado dependem da versão exata do runtime. Deixando a versão em “mais recente”, o dia em que a plataforma promover uma versão nova é o dia em que a sua aplicação para de subir — sem você ter tocado em nada. Escolha uma versão fixa na aba Ambiente. ### Log que serve para alguma coisa - Uma linha quando a aplicação terminou de subir. - Erros com contexto: o que estava sendo feito. - Nada de imprimir objeto gigante a cada requisição. - Nunca imprimir credencial. ### Antes de publicar em produção - Teste o pacote localmente com as mesmas variáveis de ambiente. - Crie um snapshot antes de uma mudança grande. - Publique fora do horário de pico do seu público. - Acompanhe o console pelos primeiros minutos depois de publicar. ## Perguntas frequentes Fonte: https://docs.rtcloud.com.br/perguntas-frequentes Respostas rápidas para o que mais chega ao suporte. ### A aplicação fica ligada 24 horas? Sim. Ela só sai do ar se você desligar, se o plano vencer ou se o processo cair por um erro do próprio código. ### Tem aplicativo? Tem, grátis para todas as contas: Android, iPhone, iPad, Windows, Mac e Linux. É o painel em tela cheia, com status e documentação dentro do app. Baixe em rtcloud.com.br/aplicativo. ### Dá para usar a RTCloud pelo Claude, Grok, ChatGPT ou Cursor? Dá, e também pelo Grok, pelo Codex e por outros. O servidor MCP conecta a sua ferramenta de IA à sua conta, sem custo. Você autoriza, escolhe o que ela pode fazer e pede em linguagem normal: ver logs, corrigir um arquivo, reiniciar. Veja o passo a passo em Conectar ferramentas MCP. ### Tem teste grátis? Sim. Cada conta pode colocar um bot no ar por 24 horas, com até 512 MB de memória, uma única vez — sem cartão e sem Pix. É tempo de sobra para ver o deploy, o console e a ReactorAI funcionando. As 24 horas contam a partir do primeiro deploy: apagar o bot de teste e subir de novo não reinicia o relógio. ### Posso trocar de plano depois? Pode, as duas coisas na hora, em Faturamento → Mudar de plano. Subir: você paga a mensalidade do plano novo e os dias que sobraram viram dias a mais nele. Descer: sem cobrança, o vencimento continua o mesmo e, se as aplicações não couberem no plano menor, você escolhe quais ficam ligadas. ### O que acontece se eu não renovar? As aplicações são desligadas, mas nada é apagado. Renovando, é só ligar de novo. ### Consigo acessar por SSH? Não há acesso SSH. Tudo que normalmente se faria por terminal está no painel: ver e editar arquivos, ler o console em tempo real, definir variáveis, reiniciar e restaurar snapshots. ### Posso hospedar mais de uma aplicação? Sim, quantas couberem na memória do seu plano. Cada aplicação reserva a memória que você definir para ela. ### Meus dados ficam salvos entre reinícios? Ficam. Arquivos gravados pela aplicação sobrevivem a reinícios e a novos deploys. Eles não sobrevivem à exclusão da aplicação — para dados críticos, use um banco gerenciado. ### Como dou acesso a outra pessoa? Pelo menu **Equipes**. A pessoa entra com a conta dela e você escolhe o que ela pode fazer. Nunca compartilhe a sua senha. ### Qual o limite de tamanho do envio? 100.0 MB por envio, medido depois da limpeza automática que remove node_modules, .git e pastas de build. ### Vocês oferecem reembolso? Sim, dentro de 7 dias da contratação, conforme o Código de Defesa do Consumidor. Fale com o suporte. ## Linguagens e versões Fonte: https://docs.rtcloud.com.br/linguagens-suportadas Quais linguagens rodam na RTCloud, como cada uma é reconhecida, como sobe e o que já vem instalado no ambiente. Cada aplicação roda num container isolado com a linguagem já instalada. Você não escolhe imagem nem configura servidor: o painel lê o pacote, reconhece a linguagem pelos arquivos que já existem no projeto e monta o ambiente. | Linguagem | Reconhecida por | Como sobe sem comando de início | | --- | --- | --- | | Node.js e TypeScript | `package.json` | `node` no arquivo principal (TypeScript roda direto) | | Python | `requirements.txt`, `pyproject.toml` ou arquivos `.py` | `python` no arquivo principal | | Java | arquivo `.jar`, `pom.xml` ou `build.gradle` | `java -jar` no arquivo principal | | Go | `go.mod` ou arquivos `.go` | `go run` no arquivo principal | | Rust | `Cargo.toml` | `cargo run --release` | | Ruby | `Gemfile` ou arquivos `.rb` | `ruby` no arquivo principal | | PHP | `composer.json` ou arquivos `.php` | servidor embutido do PHP em 0.0.0.0:80 | | C# / .NET | o `.csproj` escolhido como arquivo principal | `dotnet restore` e `dotnet run --project` | | Elixir | `mix.exs` e o arquivo `.ex` principal | `mix run --no-halt` | | Site estático | `index.html` | servidor estático da RTCloud, sem processo seu | **Bun** e **Deno** rodam por cima do ambiente Node.js, instalados como dependência do projeto — cada um tem um guia próprio nesta seção. ### Versão da linguagem A versão fica na aba **Geral** da aplicação (e em **Opções avançadas** no Novo deploy). Toda linguagem tem duas opções; o painel mostra o número exato de cada uma: - **Estável (recomendada)** — a versão testada que roda a maior parte das aplicações. Recebe correções sem quebrar nada. Na dúvida, é esta. - **Mais recente** — acompanha o lançamento da linguagem. Boa para quem precisa de um recurso novo; muda sozinha quando sai uma versão nova. - **Versão fixa** — no Node.js dá para fixar 22, 20 ou 18; no Python, 3.12 ou 3.11. Útil quando uma biblioteca ainda não suporta a versão nova. > **Dependência compilada pede versão estável** — Bibliotecas com código nativo (`sharp`, `canvas`, `better-sqlite3`, `bcrypt`) dependem da versão exata do runtime. Com elas, prefira a Estável ou uma versão fixa. Mudar a versão reconstrói a aplicação do zero. ### O que já vem instalado | Ferramenta | Para quê | | --- | --- | | Chromium e ChromeDriver | Puppeteer, Playwright, Selenium e whatsapp-web.js. O driver fica em `/usr/bin/chromedriver`. | | FFmpeg | Bots de música, conversão de áudio e vídeo. | | Bibliotecas gráficas | `canvas`, `sharp`, OpenCV e geração de imagem. | | Ferramentas de build | `git`, `curl` e compiladores para dependências nativas. | | Node.js e npm | Presentes em todos os ambientes — servem para compilar os assets de um projeto PHP, Python ou Ruby. | Não envie binários dessas ferramentas no pacote (uma pasta `ffmpeg`, um Chromium baixado pelo Puppeteer): além de pesar, o binário feito para o seu sistema não roda no Linux do servidor. ### Comando de início Com o comando de início vazio, a RTCloud roda o arquivo principal com o interpretador da linguagem. Preenchido, ele é executado do jeito que está escrito — é assim que se usa `npm run start`, `gunicorn`, `bundle exec` ou um binário compilado. Quando você informa um comando de build no deploy, ele entra na frente do de start, ligado por `&&`. O campo aceita até 256 caracteres e fica na aba **Geral**. ## Node.js Fonte: https://docs.rtcloud.com.br/nodejs Como a RTCloud reconhece, instala e sobe um projeto Node.js — e o que fazer com TypeScript, ES Modules e nodemon. Um projeto Node.js precisa de duas coisas no pacote: o `package.json` e o arquivo que inicia a aplicação. O resto — instalar dependências, escolher a versão do Node e manter o processo de pé — é com a plataforma. ### Como o arquivo principal é escolhido - O campo `main` do `package.json`, se ele existir. - O arquivo de um script `start` simples, como `node src/index.js`. - Os nomes de sempre: `index.js`, `bot.js`, `app.js`, `main.js`, `src/index.js`, `src/index.ts`, `dist/index.js`. Se o script `start` fizer mais do que rodar um arquivo (por exemplo `node --env-file=.env server.js` ou `next start`), o painel usa `npm run start` como comando de início. Dá para conferir e trocar o arquivo na tela do deploy e, depois, na aba **Geral**. ### Dependências A instalação é feita a partir do `package.json`, em modo de produção. Não envie `node_modules`: além de pesado, ele traz binários compilados para o seu sistema, que não rodam no Linux do servidor (é o erro “invalid ELF header”). Se o código usar uma biblioteca que não está declarada, o painel avisa no deploy e instala junto. > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila. Sem isso o build falha com “command not found” ou “Cannot find module”. > **nodemon é ferramenta de desenvolvimento** — Um `start` com `nodemon` ou `ts-node-dev` não funciona em produção, porque eles ficam em `devDependencies`. O painel troca esse start pelo próprio runtime (`node` ou `tsx`) e avisa no log. ### TypeScript Arquivo principal `.ts` roda direto, sem configurar nada. Para produção, compilar é mais leve e sobe mais rápido: deixe o `typescript` em `dependencies`, preencha **Comando de build** com `npm run build` (o seu `tsc`) e **Comando de start** com `node dist/index.js`. Não envie a pasta `dist` — ela é gerada aqui. ```json { "scripts": { "build": "tsc", "start": "node dist/index.js" }, "dependencies": { "typescript": "5.6.3" } } ``` ### import ou require Projeto com `import`/`export` precisa de `"type": "module"` no `package.json`; projeto com `require` não pode ter essa linha. Errar isso derruba a aplicação logo no início com “Cannot use import statement outside a module” ou “require is not defined” — e a correção de crash em 1 clique ajusta sozinha. ### Site ou API > **Escute em 0.0.0.0, porta 80** — É nessa porta que a RTCloud procura o seu site. A variável `PORT` já chega com 80 e `HOST` com 0.0.0.0 — usar as duas no código é o jeito mais seguro. Escutar em `localhost` ou noutra porta faz a aplicação subir e não responder no endereço. ```javascript const http = require("http"); const porta = process.env.PORT || 80; http .createServer((req, res) => res.end("Olá da RTCloud!")) .listen(porta, "0.0.0.0", () => console.log("No ar na porta " + porta)); ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`index.js`) e reserve pelo menos **256 MB num bot e 512 MB num site** de memória. 5. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **Memória e versão** — Bot simples vive bem com 256 MB; site e API começam em 512 MB. Na versão do Node, a Estável é a mais segura para dependências nativas — veja “Linguagens e versões”. ## Como montar o package.json Fonte: https://docs.rtcloud.com.br/package-json Scripts, dependências, versões fixas e os campos que fazem diferença na hora de publicar um projeto Node.js. O `package.json` é o manifesto do projeto Node.js: diz quais bibliotecas instalar, como iniciar e qual é o arquivo de entrada. É a partir dele que a RTCloud monta o ambiente — o que não estiver aqui não é instalado. ### Criando ```bash # pergunta campo a campo npm init # aceita tudo e cria na hora npm init -y ``` ### Os campos que importam | Campo | Para que serve | | --- | --- | | `main` | O arquivo de entrada (`index.js`, `src/index.js`). É a primeira pista que o painel usa para achar o arquivo principal. | | `type` | `"module"` para `import`/`export`. Sem ele, o Node usa `require`. | | `scripts.start` | Como a aplicação inicia. Se for só `node arquivo.js`, o painel roda o arquivo direto; se for mais que isso, usa `npm run start`. | | `scripts.build` | Compilação (TypeScript, Vite, Next). Quando existe, o painel sugere `npm run build` como comando de build. | | `dependencies` | Tudo que o código precisa para rodar — e para compilar. | | `devDependencies` | Ferramentas só da sua máquina (eslint, prettier, nodemon). **Não são instaladas na RTCloud.** | ### Adicionando bibliotecas ```bash npm install discord.js # vai para dependencies npm install -D eslint # vai para devDependencies ``` > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Versões que não mudam sozinhas O `^` em `"^14.14.1"` deixa o npm instalar qualquer 14.x mais nova. Para uma biblioteca crítica, tire o `^` e fixe a versão: o ambiente instala a partir do `package.json`, então é ele — não o `package-lock.json` — que garante a versão que roda aqui. ### Recursos úteis - **`overrides`** força a versão de uma sub-dependência — o jeito certo de corrigir uma vulnerabilidade apontada pelo `npm audit`. - **`imports`** cria atalhos de caminho nativos (`#utils/*`), sem `../../../`. - **`allowScripts`** libera scripts de instalação de pacotes que precisam deles (`esbuild`, `sharp`, `bcrypt`). Se um pacote falhar por script bloqueado, a correção de crash em 1 clique adiciona a liberação. ```json { "name": "meu-bot", "version": "1.0.0", "main": "src/index.js", "type": "module", "scripts": { "start": "node src/index.js", "lint": "eslint ." }, "imports": { "#servicos/*": "./src/servicos/*.js" }, "overrides": { "pacote-vulneravel": "2.0.1" }, "dependencies": { "discord.js": "14.16.3", "dotenv": "16.4.5" }, "devDependencies": { "eslint": "9.12.0" } } ``` ### Erros comuns | Erro | Causa | Correção | | --- | --- | --- | | Cannot find module 'x' | Biblioteca usada no código e não declarada. | `npm install x` e publique de novo. | | Unexpected token no package.json | JSON inválido (aspas simples, chave sem aspas). Comentário, vírgula sobrando e BOM a RTCloud já corrige no deploy. | Valide o arquivo antes de enviar. | | npm ERR! code ERESOLVE | Duas bibliotecas pedem versões incompatíveis de uma terceira. | Ajuste as versões ou crie um `.npmrc` com `legacy-peer-deps=true`. | | SELF_SIGNED_CERT_IN_CHAIN / UNABLE_TO_VERIFY_LEAF_SIGNATURE | Registry privado com certificado próprio — o npm valida todo certificado. | Aponte o certificado no `.npmrc` do projeto (`cafile=certificado.pem`) ou use o registry público. | ## Bun Fonte: https://docs.rtcloud.com.br/bun Rodar uma aplicação com o runtime Bun na RTCloud: o pacote no projeto, o comando de start e um servidor HTTP de exemplo. O Bun roda por cima do ambiente Node.js da RTCloud: ele entra no projeto como uma dependência comum e é chamado com `npx`. Assim a versão do Bun fica declarada no próprio `package.json` e é instalada junto com o resto. ### Preparando o projeto ```bash npm install bun ``` ```json { "name": "app-bun", "scripts": { "start": "bun run index.ts" }, "dependencies": { "bun": "1.1.30" } } ``` > **As dependências são instaladas pelo npm** — A instalação segue o `package.json`, não o `bun.lockb`. Declare tudo que o código usa em `dependencies`. ### Servidor HTTP com Bun ```typescript const servidor = Bun.serve({ hostname: "0.0.0.0", port: Number(process.env.PORT) || 80, fetch() { return new Response("Olá do Bun na RTCloud!"); }, }); console.log("No ar em " + servidor.url); ``` > **Escute em 0.0.0.0, porta 80** — É nessa porta que a RTCloud procura o seu site. A variável `PORT` já chega com 80 e `HOST` com 0.0.0.0 — usar as duas no código é o jeito mais seguro. Escutar em `localhost` ou noutra porta faz a aplicação subir e não responder no endereço. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`index.ts`) e reserve pelo menos **256 MB num bot e 512 MB num site** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com `npx bun index.ts`. 6. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. Prefere usar os scripts do `package.json`? O comando de start pode ser `npx bun run start`. ## Deno Fonte: https://docs.rtcloud.com.br/deno Rodar uma aplicação Deno na RTCloud: o pacote no projeto, permissões, tasks do deno.json e um servidor de exemplo. Assim como o Bun, o Deno roda por cima do ambiente Node.js da RTCloud: instale o pacote `deno` no projeto e chame-o com `npx` no comando de start. O projeto precisa de um `package.json` para isso. ```bash npm install deno ``` ### Servidor HTTP com Deno ```typescript Deno.serve( { hostname: "0.0.0.0", port: Number(Deno.env.get("PORT") ?? 80) }, () => new Response("Olá do Deno na RTCloud!"), ); ``` > **Escute em 0.0.0.0, porta 80** — É nessa porta que a RTCloud procura o seu site. A variável `PORT` já chega com 80 e `HOST` com 0.0.0.0 — usar as duas no código é o jeito mais seguro. Escutar em `localhost` ou noutra porta faz a aplicação subir e não responder no endereço. ### Permissões O Deno não acessa rede, variáveis nem disco sem permissão explícita. Dê só o que a aplicação usa: `--allow-net` para servidor e chamadas HTTP, `--allow-env` para ler variáveis de ambiente, `--allow-read` e `--allow-write` para arquivos. ```json // deno.json { "tasks": { "start": "deno run --allow-net --allow-env --allow-read main.ts" } } ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`main.ts`) e reserve pelo menos **256 MB num bot e 512 MB num site** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com `npx deno run --allow-net --allow-env --allow-read main.ts`. 6. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. Com tasks no `deno.json`, o comando de start pode ser só `npx deno task start`. Imports remotos (`jsr:`, `npm:`, URLs) são baixados quando a aplicação sobe — não envie a pasta de cache do Deno. ## Python Fonte: https://docs.rtcloud.com.br/python Hospedar um projeto Python: os arquivos que o painel procura, como as dependências são instaladas, o log que demora a aparecer e o caminho para sites e APIs. Um projeto Python precisa do arquivo que inicia a aplicação e de um arquivo de dependências: `requirements.txt` ou `pyproject.toml`. A RTCloud cria o ambiente isolado, instala as bibliotecas com `pip` e roda `python` no arquivo principal. ### Arquivo principal O painel procura `main.py`, `bot.py`, `app.py`, `index.py`, `run.py` e `server.py`, nessa ordem. Se o seu tiver outro nome ou estiver numa pasta, escolha na tela do deploy — por exemplo `src/bot.py`. ### Dependências - Declare tudo no `requirements.txt` (ou no `pyproject.toml`) — veja os guias de cada um nesta seção. - Se o código importar algo que não está declarado, o painel acrescenta o pacote no deploy e avisa no log. - O nome do import nem sempre é o nome do pacote: `cv2` é `opencv-python`, `PIL` é `Pillow`. A correção de crash em 1 clique conhece os casos comuns. - **Poetry não é usado na instalação.** O `poetry.lock` é ignorado; exporte as dependências para um `requirements.txt`. > **Não envie .venv nem binários** — A pasta do ambiente virtual (`.venv`, `venv`) sai do pacote automaticamente e é recriada aqui. O FFmpeg e o Chromium já vêm instalados — não precisa mandar. ### O log demora a aparecer? Fora de um terminal, o Python guarda o `print` num buffer e só escreve em blocos — o console fica parado e depois despeja várias linhas de uma vez. Crie a variável `PYTHONUNBUFFERED` com o valor `1` em **Variáveis de Ambiente**, ou use `print(..., flush=True)`. ### Sites e APIs Flask, FastAPI e Django são reconhecidos pelo `requirements.txt` e o tipo vira Site ou API sozinho. O servidor de desenvolvimento deles não é feito para produção: use Gunicorn (Flask, Django) ou Uvicorn (FastAPI) no comando de start. Os guias de cada framework estão em “APIs e back-end”. > **Escute em 0.0.0.0, porta 80** — É nessa porta que a RTCloud procura o seu site. A variável `PORT` já chega com 80 e `HOST` com 0.0.0.0 — usar as duas no código é o jeito mais seguro. Escutar em `localhost` ou noutra porta faz a aplicação subir e não responder no endereço. ```python import os from flask import Flask app = Flask(__name__) @app.get("/") def inicio(): return "Olá da RTCloud!" if __name__ == "__main__": app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 80))) ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`main.py`) e reserve pelo menos **256 MB num bot e 512 MB num site** de memória. 5. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. A versão do Python fica na aba **Geral**: Estável, Mais recente, 3.12 ou 3.11. Bibliotecas científicas grandes (pandas, torch) pedem mais memória — comece com 1 GB. ## Como montar o requirements.txt Fonte: https://docs.rtcloud.com.br/requirements-txt Listar as bibliotecas do projeto Python com versões fixas, gerar o arquivo sem lixo e acertar os nomes que confundem. O `requirements.txt` é a lista de pacotes externos que o projeto usa, um por linha, com a versão. É ele que a RTCloud lê para instalar as dependências com `pip install -r requirements.txt`. ### Escrevendo à mão (recomendado) ```text discord.py==2.4.0 requests==2.32.3 python-dotenv==1.0.1 ``` Use `==` com a versão exata. Sem versão, cada deploy instala a mais nova que existir naquele dia — e o projeto pode quebrar sem você ter mudado nada. ### Gerando a partir do ambiente virtual ```bash # crie e ative um ambiente só do projeto python -m venv venv venv\Scripts\activate # Windows source venv/bin/activate # Linux e macOS # instale o que o projeto usa e gere a lista pip install discord.py requests python-dotenv pip freeze > requirements.txt ``` > **pip freeze fora do ambiente virtual traz lixo** — Rodado no Python global, o `pip freeze` lista tudo que já foi instalado na sua máquina. Gere sempre dentro de um ambiente virtual do projeto e revise o arquivo antes de enviar. ### O que a RTCloud corrige sozinha no deploy - **Arquivo em UTF-16** — o `pip freeze > requirements.txt` do PowerShell grava assim e o pip lê lixo. Vira UTF-8. - **Nome e lugar** — `Requirements.txt`, `requirements.txt.txt` (extensão escondida do Windows) ou o arquivo dentro da pasta do bot: vai para a raiz com o nome certo. - **Pacote só de Windows ou Mac** (`pywin32`, `pyobjc`) — fica de fora no servidor, que é Linux; o resto instala. - **Linhas do seu computador** (`pacote @ file:///C:/...`, `-e .`) — viram o pacote do PyPI ou saem. - **Pacote repetido** com versões diferentes — vale a primeira linha. - **Versão exata antiga de biblioteca compilada** (`aiohttp`, `yarl`, `numpy`, `pydantic`…) — o servidor usa o Python 3.14 e versões de um Python antigo não têm pacote pronto para ele. A RTCloud libera a mais nova da mesma série (`aiohttp==3.9.1` → `aiohttp>=3.9.1,<4`). - **Arquivos do próprio projeto** (`import config`, `from cogs import musica`) nunca entram no requirements como se fossem bibliotecas. Tudo o que foi ajustado aparece no log do deploy, em português. ### Nome do import × nome do pacote | No código | No requirements.txt | | --- | --- | | `import cv2` | `opencv-python-headless` (sem interface gráfica, ideal para servidor) | | `from PIL import Image` | `Pillow` | | `import yaml` | `PyYAML` | | `import discord` | `discord.py` | | `from dotenv import load_dotenv` | `python-dotenv` | | `from bs4 import BeautifulSoup` | `beautifulsoup4` | | `import telebot` | `pyTelegramBotAPI` | | `from telegram import Bot` | `python-telegram-bot` | | `import jwt` | `PyJWT` | | `import sklearn` | `scikit-learn` | ### Boas práticas - Teste num ambiente novo antes de publicar: `pip install -r requirements.txt` não pode falhar. - Não liste bibliotecas da própria linguagem (`os`, `random`, `datetime`, `asyncio`). - Mantenha o arquivo no repositório — com o deploy pelo GitHub, ele vai junto em cada push. ## Como montar o pyproject.toml Fonte: https://docs.rtcloud.com.br/pyproject-toml O formato moderno de dependências do Python: metadados, dependências de produção e de desenvolvimento e o sistema de build. O `pyproject.toml` reúne num arquivo só os dados do projeto, as dependências e a forma de instalar. A RTCloud aceita ele no lugar do `requirements.txt`. ```toml [project] name = "meu-bot" version = "1.0.0" description = "Bot de Discord da comunidade" requires-python = ">=3.11" dependencies = [ "discord.py==2.4.0", "python-dotenv==1.0.1", ] [project.optional-dependencies] dev = ["pytest", "ruff"] [build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" ``` ### O que vai em cada parte - **`[project]`** — nome (letras, números, `-`, `_` e `.`, sem começar ou terminar com símbolo), versão e a versão mínima do Python. - **`dependencies`** — o que o código precisa para rodar. É isto que é instalado aqui. - **`optional-dependencies`** — grupos extras, como as ferramentas de teste. Não são instalados em produção. - **`[build-system]`** — como o `pip` instala o projeto. O `setuptools` atende a quase todos. > **Projeto em Poetry** — As dependências precisam estar no padrão `[project]`. Listas só em `[tool.poetry.dependencies]` e o `poetry.lock` não são usados na instalação — exporte para um `requirements.txt` com `poetry export -f requirements.txt --output requirements.txt --without-hashes`. ### Testando antes de enviar ```bash pip install . # só produção pip install ".[dev]" # com as ferramentas de desenvolvimento ``` Se a instalação passar num ambiente virtual novo, vai passar na RTCloud. Prefira versões exatas (`==`) nas dependências de produção. ## Java Fonte: https://docs.rtcloud.com.br/java Publicar um .jar na RTCloud: gerar o jar com as dependências, onde colocá-lo no pacote e como ajustar a memória da JVM. Java roda a partir de um arquivo `.jar` já compilado. Com o comando de início vazio, a RTCloud executa `java -jar` no arquivo principal — então o jar precisa trazer as dependências dentro dele (o chamado fat jar). ### Gerando o jar | Ferramenta | Comando | Onde sai o jar | | --- | --- | --- | | Maven | `mvn clean package` | `target/` | | Gradle | `./gradlew build` | `build/libs/` | Para o jar levar as bibliotecas junto, use o `maven-shade-plugin` (Maven), o plugin Shadow (Gradle) ou o plugin do Spring Boot, que já faz isso. Confira com `java -jar seu-app.jar` na sua máquina antes de enviar. > **Copie o jar para a raiz do .zip** — As pastas `target` e `build` saem do pacote na limpeza automática — elas costumam ter só lixo de compilação. Coloque o `.jar` na raiz do .zip (junto com arquivos de configuração que ele lê) ou escolha como arquivo principal o caminho dentro da pasta (`target/app.jar`), e aí a pasta é mantida. ### Memória da JVM Por padrão a JVM usa só uma fração da memória do container para o heap. Para aproveitar o que você reservou sem estourar o limite, preencha o comando de início com a porcentagem: ```bash java -XX:MaxRAMPercentage=75 -jar app.jar ``` ### Site ou API > **Escute em 0.0.0.0, porta 80** — É nessa porta que a RTCloud procura o seu site. A variável `PORT` já chega com 80 e `HOST` com 0.0.0.0 — usar as duas no código é o jeito mais seguro. Escutar em `localhost` ou noutra porta faz a aplicação subir e não responder no endereço. No Spring Boot, isso é `server.port=${PORT:80}` e `server.address=0.0.0.0` no `application.properties` — veja o guia do Spring Boot. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`app.jar`) e reserve pelo menos **512 MB** de memória. 5. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ## Go Fonte: https://docs.rtcloud.com.br/go Publicar um projeto Go: go.mod, compilar um binário no deploy e um servidor HTTP que escuta no lugar certo. O painel reconhece Go pelo `go.mod` e procura `main.go` (ou `cmd/main.go`). Com o comando de início vazio, a RTCloud roda `go mod tidy` e depois `go run` no arquivo principal. ### Arquivos do pacote - `main.go` — o ponto de entrada. - `go.mod` (ou `go.work`) — o módulo e as dependências. - `go.sum` — opcional, mas garante que as dependências baixadas são as mesmas da sua máquina. ### Compilar em vez de go run O `go run` compila numa pasta temporária a cada início. Gerar um binário deixa claro o que está rodando e economiza memória do processo: | Campo (Opções avançadas) | Valor | | --- | --- | | Comando de build | `go build -o app .` | | Comando de start | `./app` | ### Servidor HTTP ```go package main import ( "fmt" "net/http" "os" ) func main() { porta := os.Getenv("PORT") if porta == "" { porta = "80" } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Olá da RTCloud!") }) // ":" + porta escuta em todas as interfaces (0.0.0.0) http.ListenAndServe(":"+porta, nil) } ``` > **Escute em 0.0.0.0, porta 80** — É nessa porta que a RTCloud procura o seu site. A variável `PORT` já chega com 80 e `HOST` com 0.0.0.0 — usar as duas no código é o jeito mais seguro. Escutar em `localhost` ou noutra porta faz a aplicação subir e não responder no endereço. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`main.go`) e reserve pelo menos **256 MB num bot e 512 MB num site** de memória. 5. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ## Rust Fonte: https://docs.rtcloud.com.br/rust Publicar um projeto Rust: o Cargo.toml, o binário em modo release e a memória que a compilação pede. O painel reconhece Rust pelo `Cargo.toml` e já sugere os dois comandos do deploy: **Comando de build** `cargo build --release` e **Comando de start** `./target/release/`. Sem eles, a RTCloud roda `cargo run --release`. > **Confira o nome do binário** — O binário sai com o `name` da seção `[package]` do `Cargo.toml`. O painel sugere o nome a partir do pacote enviado — se for diferente, corrija o comando de start (`./target/release/meu_bot`), senão a aplicação compila e não encontra o que executar. ### Arquivos do pacote - `Cargo.toml` e `Cargo.lock` (o lock garante as mesmas versões da sua máquina). - `src/main.rs` e o resto do código. - **Não envie `target/`** — a pasta sai do pacote e é gerada aqui, no Linux do servidor. ### Servidor HTTP ```rust use std::io::{Read, Write}; use std::net::TcpListener; fn main() { let porta = std::env::var("PORT").unwrap_or_else(|_| "80".into()); let servidor = TcpListener::bind(format!("0.0.0.0:{porta}")).unwrap(); println!("No ar na porta {porta}"); for conexao in servidor.incoming() { let mut c = conexao.unwrap(); let mut buffer = [0; 1024]; let _ = c.read(&mut buffer); let corpo = "Olá da RTCloud!"; let resposta = format!( "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{corpo}", corpo.len() ); let _ = c.write_all(resposta.as_bytes()); } } ``` Com Axum, Actix ou Rocket a regra é a mesma: endereço `0.0.0.0` e a porta da variável `PORT`. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Reserve pelo menos **1 GB (a compilação em release pede mais que o programa rodando)** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `cargo build --release` e **Comando de start** com `./target/release/`. 6. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ## Ruby Fonte: https://docs.rtcloud.com.br/ruby Publicar um projeto Ruby com Bundler: Gemfile, comando de start com bundle exec e um servidor Sinatra de exemplo. O painel reconhece Ruby pelo `Gemfile` (ou por arquivos `.rb`) e procura `main.rb`, `bot.rb`, `app.rb` e `index.rb`. Com o comando de início vazio, a RTCloud roda `ruby` no arquivo principal. ### Arquivos do pacote - `main.rb` — o ponto de entrada. - `Gemfile` — as gems do projeto. - `Gemfile.lock` — recomendado: garante as mesmas versões da sua máquina. ### Bundler As gems são instaladas pelo Bundler. Para o código enxergá-las do jeito certo, use `bundle exec` no comando de início. E, para não instalar gems de teste e desenvolvimento em produção, crie a variável `BUNDLE_WITHOUT` com o valor `development:test` em **Variáveis de Ambiente**. ```ruby # app.rb require "sinatra" set :bind, "0.0.0.0" set :port, ENV.fetch("PORT", 80) get "/" do "Olá da RTCloud!" end ``` > **Escute em 0.0.0.0, porta 80** — É nessa porta que a RTCloud procura o seu site. A variável `PORT` já chega com 80 e `HOST` com 0.0.0.0 — usar as duas no código é o jeito mais seguro. Escutar em `localhost` ou noutra porta faz a aplicação subir e não responder no endereço. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`app.rb`) e reserve pelo menos **256 MB num bot e 512 MB num site** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com `bundle exec ruby app.rb`. 6. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ## PHP Fonte: https://docs.rtcloud.com.br/php Publicar um site PHP: o servidor embutido, a pasta pública, Composer, assets com npm e Swoole para mais desempenho. O painel trata projeto PHP como Site e procura `index.php`, `public/index.php` ou `bot.php`. Com o comando de início vazio, a RTCloud sobe o servidor embutido do PHP em `0.0.0.0:80`, servindo a raiz do projeto. ### Composer Se o pacote tiver `composer.json`, as dependências são instaladas automaticamente. Não envie a pasta `vendor` — ela é gerada aqui. ### Pasta pública Quando o `index.php` fica em `public/` (Laravel, Slim, Symfony), diga ao servidor qual pasta servir no comando de início: ```bash php -S 0.0.0.0:80 -t public ``` ### Assets com npm O Node.js também está no ambiente do PHP, mas as dependências do `package.json` não são instaladas sozinhas num projeto PHP. Coloque a instalação e o build no comando de início, antes do servidor: ```bash npm install && npm run build && php -S 0.0.0.0:80 -t public ``` ### Swoole O Swoole atende várias requisições ao mesmo tempo e abre caminho para websockets e filas. No Laravel, ele roda pelo Octane — um comando de início completo fica assim: ```bash composer install --no-interaction --prefer-dist --optimize-autoloader && php artisan optimize && php artisan migrate --force && php artisan octane:start --server=swoole --host=0.0.0.0 --port=80 --workers=4 --task-workers=8 ``` O comando de início aceita até 256 caracteres. Se o seu passar disso, coloque os passos num script (`start.sh`) e use `sh start.sh`. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`index.php`) e reserve pelo menos **512 MB** de memória. 5. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ## C# e .NET Fonte: https://docs.rtcloud.com.br/csharp-dotnet Publicar um projeto .NET: o .csproj como arquivo principal, compilar em Release e configurar a porta do ASP.NET Core. Um projeto .NET é publicado a partir do arquivo `.csproj`. Escolha-o como **Arquivo principal** no deploy — se estiver numa pasta, com o caminho completo (`MeuApp/MeuApp.csproj`). Com o comando de início vazio, a RTCloud roda `dotnet restore` e `dotnet run --project` nesse arquivo. > **O painel não adivinha projetos .NET** — Como o `.csproj` pode estar em qualquer pasta, a detecção automática não o escolhe sozinha. Confira o campo **Arquivo principal** antes de publicar. ### Compilar em Release O `dotnet run` compila em modo Debug. Para produção, publique em Release e rode a DLL — sobe mais rápido e gasta menos memória: | Campo (Opções avançadas) | Valor | | --- | --- | | Comando de build | `dotnet publish MeuApp/MeuApp.csproj -c Release -o publicado` | | Comando de start | `dotnet publicado/MeuApp.dll` | Use um nome de pasta como `publicado`: `bin`, `obj`, `build` e `out` são tratadas como lixo de compilação. Não envie `bin` nem `obj` no pacote. ### ASP.NET Core Crie a variável `ASPNETCORE_URLS` com `http://0.0.0.0:80` em **Variáveis de Ambiente** — o Kestrel passa a escutar no lugar certo sem mudar o código. Ou defina no próprio código: ```csharp var builder = WebApplication.CreateBuilder(args); var porta = Environment.GetEnvironmentVariable("PORT") ?? "80"; builder.WebHost.UseUrls($"http://0.0.0.0:{porta}"); var app = builder.Build(); app.MapGet("/", () => "Olá da RTCloud!"); app.Run(); ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`MeuApp/MeuApp.csproj`) e reserve pelo menos **512 MB** de memória. 5. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ## Elixir Fonte: https://docs.rtcloud.com.br/elixir Publicar um projeto Elixir com Mix: dependências, o comando que mantém a aplicação viva e o ambiente de produção. Um projeto Elixir precisa do `mix.exs` e do código em `lib/`. Escolha como **Arquivo principal** o arquivo `.ex` de entrada (por exemplo `lib/main.ex`) — é ele que diz à RTCloud que o projeto é Elixir. ### Como a aplicação sobe - O Hex e o Rebar são instalados no ambiente. - As dependências do `mix.exs` são baixadas com `mix deps.get`. - Com o comando de início vazio, a aplicação sobe com `mix run --no-halt` — o `--no-halt` mantém o processo vivo depois de iniciar a árvore de supervisão. Crie a variável `MIX_ENV` com o valor `prod` em **Variáveis de Ambiente** para compilar e rodar com a configuração de produção. Não envie as pastas `_build` e `deps`. ```elixir # lib/main.ex — uma aplicação OTP mínima # (no mix.exs: def application, do: [mod: {Main.Application, []}]) defmodule Main.Application do use Application def start(_type, _args) do IO.puts("Aplicação no ar") Supervisor.start_link([], strategy: :one_for_one, name: Main.Supervisor) end end ``` Para sites com Phoenix, siga o guia do Phoenix em “APIs e back-end”: ele usa um release e escuta na porta 80. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker** para bots e automações, ou **Site ou API** para quem recebe acessos por endereço — nesse caso deixe **Publicar na web** ligado e escolha o subdomínio (`seu-nome.rtsystems.app`). 4. Confira o **Arquivo principal** (`lib/main.ex`) e reserve pelo menos **512 MB** de memória. 5. Publique e acompanhe o log ao vivo. Num site, abra `https://seu-nome.rtsystems.app` quando aparecer “no ar”; num bot, mande um comando para conferir. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ## Site estático (HTML, CSS e JS) Fonte: https://docs.rtcloud.com.br/site-estatico Publicar um site só de HTML, CSS e JavaScript, sem servidor seu: a estrutura do .zip, a página 404 e o que fazer com sites compilados. Um site estático não precisa de linguagem de servidor: a RTCloud entrega os arquivos direto, com HTTPS, a partir do endereço `seu-nome.rtsystems.app`. O painel reconhece pelo `index.html` na raiz do pacote. ### Estrutura do .zip ```text meu-site.zip ├── index.html ← obrigatório, na raiz ├── 404.html ← opcional: página de “não encontrado” ├── sobre.html ├── css/ │ └── estilo.css └── img/ └── logo.png ``` > **Compacte o conteúdo, não a pasta** — Se o `index.html` ficar dentro de uma pasta no .zip (`meu-site/index.html`), selecione os arquivos de dentro da pasta e compacte de novo. Links nas páginas devem usar caminhos relativos (`css/estilo.css`), que funcionam em qualquer endereço. ### Sites gerados por ferramenta Vite, Astro, Angular e outros geram o site numa pasta (`dist`, `build`). Envie o **conteúdo** dessa pasta, com o `index.html` na raiz — a pasta `dist` em si sai do pacote na limpeza automática. Se o site tiver rotas no navegador (React Router, Vue Router), veja “Publicar um site compilado”: sem um servidor que devolva o `index.html`, abrir `/contato` direto dá 404. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`index.html`) e reserve pelo menos **512 MB** de memória. 5. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. Para atualizar, envie o .zip novo na aba **Commit** — ou só o arquivo alterado, escolhendo a pasta de destino. Se o navegador continuar mostrando a versão antiga, recarregue sem cache (Ctrl+F5). ## Publicar um site compilado (React, Vue, Vite…) Fonte: https://docs.rtcloud.com.br/site-compilado Os três jeitos de colocar no ar um site que passa por build: arquivos estáticos, o servidor serve e um servidor Express com rotas. React, Vue, Preact, Angular e companhia geram, no build, uma pasta com HTML, CSS e JavaScript prontos (`dist` ou `build`). Colocar o site no ar é entregar essa pasta. Há três jeitos, do mais simples ao mais flexível. ### 1. Como site estático (mais leve) 1. Rode `npm run build` na sua máquina. 2. Abra a pasta gerada (`dist` ou `build`), selecione **o que está dentro** dela e compacte num .zip — o `index.html` precisa ficar na raiz. 3. Publique como **Site ou API** com 512 MB. Não há processo Node rodando: a RTCloud entrega os arquivos. > **Rotas no navegador dão 404 neste modo** — Com React Router ou Vue Router em modo history, abrir `/contato` direto (ou recarregar a página) procura um arquivo `contato` que não existe. Se o site tem rotas assim, use o jeito 2 ou 3 — ou o roteamento por hash (`/#/contato`). ### 2. Com o servidor serve (recomendado para SPA) O pacote `serve` entrega a pasta e, com `-s`, devolve o `index.html` para qualquer rota — exatamente o que uma SPA precisa. Aqui o build roda na própria RTCloud, então você envia o código-fonte. ```bash npm install serve ``` ```json { "scripts": { "build": "vite build", "start": "serve -s dist -l 80" } } ``` > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas plugins e ferramentas como `@vitejs/plugin-react`, `@vitejs/plugin-vue`, `tailwindcss`, `postcss`, `autoprefixer` e `sass` você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB (1 GB se o build for grande)** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. ### 3. Com um servidor Express Quando o site precisa de algo além dos arquivos — uma rota de API, um redirecionamento, cabeçalhos próprios —, um servidor Express pequeno resolve. Ele entrega a pasta do build e devolve o `index.html` para o resto: ```javascript // server.js import express from "express"; import path from "node:path"; const app = express(); const pasta = path.join(import.meta.dirname, "dist"); app.use(express.static(pasta)); app.use((req, res) => res.sendFile(path.join(pasta, "index.html"))); const porta = process.env.PORT || 80; app.listen(porta, "0.0.0.0", () => console.log("No ar na porta " + porta)); ``` Com esse arquivo, o comando de start passa a ser `node server.js` (e o build continua `npm run build`). Troque `dist` pela pasta que o seu framework gera. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Next.js Fonte: https://docs.rtcloud.com.br/nextjs Publicar um projeto Next.js: scripts de build e start, o que tirar de devDependencies, variáveis NEXT_PUBLIC e memória. O Next.js roda como um servidor Node: o `next build` gera a pasta `.next` e o `next start` serve o site. Na RTCloud o build acontece aqui — você envia o código-fonte, sem a pasta `.next`. ### Preparando o package.json ```json { "scripts": { "dev": "next dev", "build": "next build", "start": "next start -H 0.0.0.0 -p 80" } } ``` Com esses scripts, o painel já preenche sozinho **Comando de build** `npm run build` e **Comando de start** `npm run start`. > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas `@types/react`, `@types/node`, `tailwindcss`, `@tailwindcss/postcss`, `postcss` e `autoprefixer` você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **1 GB (o build do Next é pesado)** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. ### Variáveis de ambiente Variáveis com prefixo `NEXT_PUBLIC_` são gravadas no JavaScript do navegador durante o build. Como o build roda a cada início, basta criá-las em **Variáveis de Ambiente** e reiniciar. As demais (chaves de API, `DATABASE_URL`) ficam só no servidor — nunca use o prefixo público para segredo. > **Endereço público pronto** — Todo site recebe a variável `RTCLOUD_URL` com o endereço completo (`https://seu-nome.rtsystems.app` ou o seu domínio). Use-a para montar links absolutos, sitemap e URLs de callback. ### Imagens O `next/image` otimiza imagens com o `sharp`, que funciona no ambiente sem configurar nada. Se o build reclamar dele, prefira a versão Estável do Node na aba **Geral**. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Nuxt Fonte: https://docs.rtcloud.com.br/nuxt Publicar um projeto Nuxt: o build que gera a pasta .output, o arquivo que sobe o servidor e a porta. O `nuxt build` gera a pasta `.output` com um servidor Node pronto em `.output/server/index.mjs`. O build roda aqui; envie o código-fonte, sem `.output` e sem `.nuxt`. ```bash npx nuxi@latest init meu-site cd meu-site npm install npm run dev # teste local ``` O servidor do Nuxt lê as variáveis `PORT` e `HOST`, que a RTCloud já define como 80 e 0.0.0.0 — não é preciso mudar nada no código. > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas o próprio `nuxt`, se estiver em `devDependencies`, e módulos como `@nuxtjs/tailwindcss` você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **1 GB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `node .output/server/index.mjs`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. Site 100% estático (`nuxt generate`)? Aí não precisa de servidor: gere na sua máquina e envie o conteúdo de `.output/public` como site estático. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Vite Fonte: https://docs.rtcloud.com.br/vite Publicar um projeto Vite (React, Vue, Svelte, Lit…): estático, com serve ou com o vite preview. O Vite compila o projeto para a pasta `dist`. Qualquer template — React, Vue, Svelte, Lit, Preact — segue o mesmo caminho na RTCloud. ```bash npm create vite@latest meu-site -- --template react cd meu-site npm install npm run build ``` ### Escolha como servir | Jeito | Quando usar | Como | | --- | --- | --- | | Site estático | Sem rotas no navegador, ou com rotas por hash. | Envie o conteúdo de `dist` — veja “Publicar um site compilado”. | | serve | SPA com React Router, Vue Router e afins. | `serve -s dist -l 80` como start, build aqui. | | vite preview | Quer o mesmo comportamento do teste local de produção. | Configure o `preview` como abaixo. | ### Usando o vite preview ```javascript // vite.config.js import { defineConfig } from "vite"; export default defineConfig({ preview: { host: "0.0.0.0", port: 80, strictPort: true, }, }); ``` Com isso, **Comando de build** `npm run build` e **Comando de start** `npx vite preview`. O `vite` precisa estar instalado em produção — o painel o move para `dependencies` sozinho; plugins como `@vitejs/plugin-react` você move. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npx vite preview`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## React Fonte: https://docs.rtcloud.com.br/react Criar um projeto React com Vite e publicá-lo na RTCloud, com as rotas do React Router funcionando ao recarregar a página. Projeto React novo começa pelo Vite (o Create React App foi descontinuado). O build sai em `dist`. ```bash npm create vite@latest meu-app -- --template react cd meu-app npm install serve ``` ```json { "scripts": { "dev": "vite", "build": "vite build", "start": "serve -s dist -l 80" } } ``` O `-s` faz o `serve` devolver o `index.html` para qualquer caminho — é o que mantém `/perfil` e `/pedidos/42` do React Router funcionando quando a pessoa recarrega a página. > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas `@vitejs/plugin-react` e, se usar, `tailwindcss` e `postcss` você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. Projeto antigo em Create React App? O build sai em `build`: troque `dist` por `build` no script `start`. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Vue Fonte: https://docs.rtcloud.com.br/vue Criar um projeto Vue e publicá-lo na RTCloud, com o Vue Router em modo history funcionando. O `create-vue` monta o projeto em cima do Vite, com o build em `dist`. A publicação segue o caminho de qualquer SPA. ```bash npm create vue@latest cd nome-do-projeto npm install npm install serve ``` ```json { "scripts": { "build": "vite build", "start": "serve -s dist -l 80" } } ``` > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas `@vitejs/plugin-vue` e, em projetos TypeScript, `vue-tsc` você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. Precisa de renderização no servidor (SEO, páginas dinâmicas)? Use o Nuxt — veja o guia dele. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Angular Fonte: https://docs.rtcloud.com.br/angular Publicar um projeto Angular: a pasta que o build gera, os pacotes de build que precisam ir para dependencies e o modo SSR. O `ng build` gera o site em `dist//browser` (nas versões mais antigas, direto em `dist/`). Confira o caminho na sua máquina antes de configurar o start. ```bash ng new meu-app cd meu-app npm install serve ng build --configuration production ``` ```json { "scripts": { "build": "ng build --configuration production", "start": "serve -s dist/meu-app/browser -l 80" } } ``` > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas `@angular/cli`, `@angular-devkit/build-angular` (ou `@angular/build`) e `@angular/compiler-cli` você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **1 GB (o build do Angular é pesado)** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. > **Prefere não compilar aqui?** — Rode o build na sua máquina e envie só o conteúdo de `dist/meu-app/browser` como site estático, com 512 MB. Fica mais leve — mas, sem o `serve -s`, recarregar uma rota interna dá 404. ### Angular com SSR Com `ng add @angular/ssr`, o build gera também um servidor em `dist/meu-app/server/server.mjs`, que lê a variável `PORT`. O comando de start passa a ser `node dist/meu-app/server/server.mjs`. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Astro Fonte: https://docs.rtcloud.com.br/astro Publicar um site Astro estático ou com renderização no servidor pelo adaptador Node. Por padrão o Astro gera páginas estáticas em `dist`. Com o adaptador Node, ele também renderiza no servidor. Os dois modos funcionam na RTCloud. ```bash npm create astro@latest cd meu-site npm run build ``` ### Site estático Cada página vira um arquivo HTML de verdade, então não há problema de rota. Envie o **conteúdo** de `dist` como site estático, ou deixe o build rodar aqui com o `serve` (sem o `-s`, que é para SPA): ```json { "scripts": { "build": "astro build", "start": "serve dist -l 80" } } ``` ### Renderização no servidor ```bash npx astro add node ``` Deixe o adaptador em `mode: "standalone"`. O servidor gerado lê `HOST` e `PORT`, que a RTCloud já define — o comando de start fica `node ./dist/server/entry.mjs`. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Remix e React Router Fonte: https://docs.rtcloud.com.br/remix Publicar um app Remix (ou React Router no modo framework): o build em build/server e o servidor de produção. O Remix evoluiu para o React Router 7 no modo framework; os dois publicam do mesmo jeito. O build gera `build/client` (arquivos do navegador) e `build/server/index.js` (o servidor). | Projeto | Comando de start | | --- | --- | | Remix 2 | `npx remix-serve ./build/server/index.js` | | React Router 7 | `npx react-router-serve ./build/server/index.js` | Os dois servidores leem `PORT` e `HOST`, que a RTCloud já define — nada a mudar no código. O pacote do servidor (`@remix-run/serve` ou `@react-router/serve`) precisa estar em `dependencies`. > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas `@remix-run/dev` ou `@react-router/dev` você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npx remix-serve ./build/server/index.js`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Gatsby Fonte: https://docs.rtcloud.com.br/gatsby Publicar um site Gatsby: enviar a pasta public pronta ou compilar e servir na RTCloud. O Gatsby gera o site em `public` no `gatsby build`. Como o build dele é demorado e pede bastante memória, o caminho mais leve é compilar na sua máquina. ### Jeito 1: enviar o site pronto 1. Rode `npm run build` na sua máquina. 2. Compacte o **conteúdo** da pasta `public` (o `index.html` na raiz do .zip). 3. Publique como site estático, com 512 MB. ### Jeito 2: compilar e servir aqui Necessário se você usa renderização no servidor (SSR ou DSG). O `gatsby` já fica em `dependencies` nos projetos novos. ```json { "scripts": { "build": "gatsby build", "start": "gatsby serve -H 0.0.0.0 -p 80" } } ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **1 GB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Preact Fonte: https://docs.rtcloud.com.br/preact Criar um projeto Preact com Vite e publicá-lo na RTCloud como SPA ou site estático. O `create-preact` monta o projeto sobre o Vite, com build em `dist`. A publicação é a de qualquer SPA. ```bash npm init preact cd meu-app npm install serve ``` ```json { "scripts": { "build": "vite build", "start": "serve -s dist -l 80" } } ``` > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas `@preact/preset-vite` você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. Projeto antigo feito com o `preact-cli`? O build sai em `build` — ajuste a pasta no script `start`. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Qwik Fonte: https://docs.rtcloud.com.br/qwik Publicar um app Qwik City com o adaptador Express (servidor Node) ou como site estático. O Qwik precisa de um adaptador para saber onde vai rodar. Na RTCloud, use o do Express (servidor Node) ou o estático. ```bash npm create qwik@latest cd meu-app npm run qwik add express ``` O adaptador cria o servidor em `server/entry.express` e o script `serve`. Ele lê a variável `PORT`, que a RTCloud já define como 80. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `node server/entry.express`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. ### Site estático Com `npm run qwik add static`, o build gera páginas estáticas em `dist`. Envie o conteúdo dessa pasta como site estático. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## SolidJS e SolidStart Fonte: https://docs.rtcloud.com.br/solidjs Publicar um app SolidStart (servidor Node) ou um projeto Solid com Vite (SPA). O `npm init solid` pergunta se o projeto usa o SolidStart (com servidor) ou só o Solid com Vite (SPA). Os dois rodam na RTCloud. ### SolidStart O build gera um servidor Node em `.output/server/index.mjs`, que lê `PORT` e `HOST` — já definidos pela RTCloud. ```json { "scripts": { "build": "vinxi build", "start": "vinxi start" } } ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. ### Solid com Vite (SPA) Sem SolidStart, o projeto é uma SPA com build em `dist`: siga “Publicar um site compilado” e use `serve -s dist -l 80` como start. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Express Fonte: https://docs.rtcloud.com.br/express Uma API Express pronta para produção na RTCloud: porta, endereço, proxy confiável e encerramento limpo. O Express é reconhecido pelo `package.json` e a aplicação já vira Site ou API no deploy. O que precisa estar certo é o `listen`. ```bash npm init -y npm install express ``` ```javascript // index.js const express = require("express"); const app = express(); // as visitas chegam por um proxy com HTTPS: assim req.protocol e req.ip ficam certos app.set("trust proxy", true); app.use(express.json()); app.get("/", (req, res) => res.json({ ok: true, mensagem: "Olá da RTCloud!" })); const porta = process.env.PORT || 80; const servidor = app.listen(porta, "0.0.0.0", () => { console.log("API no ar na porta " + porta); }); // reinício e novo deploy pedem para o processo terminar: feche as conexões antes process.on("SIGTERM", () => servidor.close(() => process.exit(0))); ``` > **Escute em 0.0.0.0, porta 80** — É nessa porta que a RTCloud procura o seu site. A variável `PORT` já chega com 80 e `HOST` com 0.0.0.0 — usar as duas no código é o jeito mais seguro. Escutar em `localhost` ou noutra porta faz a aplicação subir e não responder no endereço. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`index.js`) e reserve pelo menos **512 MB** de memória. 5. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Fastify Fonte: https://docs.rtcloud.com.br/fastify Publicar uma API Fastify — com o detalhe do host, que por padrão escuta só em localhost. > **O Fastify escuta em localhost por padrão** — Sem `host: "0.0.0.0"` no `listen`, a API sobe, o log diz que está tudo certo e o endereço nunca responde. É o erro mais comum com Fastify. ```bash npm install fastify ``` ```javascript // index.js import Fastify from "fastify"; const app = Fastify({ logger: true, trustProxy: true }); app.get("/", async () => ({ ok: true })); try { await app.listen({ host: "0.0.0.0", port: Number(process.env.PORT) || 80 }); } catch (erro) { app.log.error(erro); process.exit(1); } ``` O exemplo usa `import`: o `package.json` precisa de `"type": "module"`. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`index.js`) e reserve pelo menos **512 MB** de memória. 5. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## NestJS Fonte: https://docs.rtcloud.com.br/nestjs Publicar uma API NestJS: o main.ts no endereço certo, o build com o CLI do Nest e o start de produção. O NestJS é TypeScript compilado: o `nest build` gera `dist/main.js`, e é esse arquivo que roda em produção. O build acontece aqui — envie o código-fonte, sem `dist`. ```typescript // src/main.ts import { NestFactory } from "@nestjs/core"; import { AppModule } from "./app.module"; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableShutdownHooks(); await app.listen(process.env.PORT ?? 80, "0.0.0.0"); } bootstrap(); ``` > **O que o build usa precisa estar em dependencies** — A instalação na RTCloud é de produção: `devDependencies` não são instaladas. O painel já move sozinho `typescript`, `vite`, `esbuild`, `webpack`, `rollup` e `tsx` quando o projeto compila, mas `@nestjs/cli` (é ele que roda o `nest build`) você move para `dependencies`. Sem isso o build falha com “command not found” ou “Cannot find module”. > **Use o start de produção** — O script `start` do Nest (`nest start`) compila e roda pelo CLI, como em desenvolvimento. Em produção, o comando de start é `node dist/main.js`. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `npm run build` e **Comando de start** com `node dist/main.js`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Flask Fonte: https://docs.rtcloud.com.br/flask Publicar uma aplicação Flask com Gunicorn, o servidor de produção, no endereço e na porta da RTCloud. O `app.run()` do Flask é um servidor de desenvolvimento: atende uma requisição por vez e avisa no próprio log que não é para produção. Na RTCloud, quem serve a aplicação é o Gunicorn. ```python # app.py from flask import Flask app = Flask(__name__) @app.get("/") def inicio(): return {"ok": True, "mensagem": "Olá da RTCloud!"} ``` ```text # requirements.txt flask==3.0.3 gunicorn==23.0.0 ``` O `app:app` do comando abaixo quer dizer “a variável `app` do arquivo `app.py`”. Se o seu arquivo se chama `main.py`, use `main:app`. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`app.py`) e reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com `gunicorn --bind 0.0.0.0:80 --workers 2 app:app`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O painel sugere python app.py** — Ao reconhecer o Flask, o painel preenche o start com `python app.py`. Troque pelo Gunicorn antes de publicar — ou depois, na aba **Geral**, em **Comando de início**. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Django Fonte: https://docs.rtcloud.com.br/django Publicar um projeto Django: configurações de produção, arquivos estáticos, migrações e Gunicorn. O `runserver` é só para desenvolvimento. Em produção, o Django roda pelo Gunicorn, com algumas configurações que o projeto novo não traz prontas. ### settings.py de produção ```python import os SECRET_KEY = os.environ["DJANGO_SECRET_KEY"] DEBUG = os.environ.get("DJANGO_DEBUG") == "1" ALLOWED_HOSTS = [".rtsystems.app", "seudominio.com.br"] CSRF_TRUSTED_ORIGINS = ["https://*.rtsystems.app", "https://seudominio.com.br"] # o HTTPS termina no proxy da RTCloud: o Django precisa confiar nesse cabeçalho SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") STATIC_URL = "static/" STATIC_ROOT = BASE_DIR / "staticfiles" ``` ### Arquivos estáticos com WhiteNoise Sem `DEBUG`, o Django não entrega CSS e JavaScript. O WhiteNoise resolve sem servidor extra: instale e coloque o middleware logo depois do `SecurityMiddleware`. ```python MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", # ...o resto ] ``` ```text # requirements.txt django==5.1.2 gunicorn==23.0.0 whitenoise==6.7.0 ``` ### Variáveis de ambiente Crie `DJANGO_SECRET_KEY` em **Variáveis de Ambiente** com uma chave longa e aleatória (gere com `python -c "import secrets; print(secrets.token_urlsafe(50))"`). Nunca deixe a chave no código. ### Comando de início As migrações e o `collectstatic` rodam a cada início, antes do servidor — assim o banco e os estáticos estão sempre em dia com o código publicado. Troque `meuprojeto` pelo nome da pasta que tem o `wsgi.py`: ```bash python manage.py migrate --noinput && python manage.py collectstatic --noinput && gunicorn meuprojeto.wsgi --bind 0.0.0.0:80 --workers 2 ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`manage.py`) e reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com o comando mostrado acima. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **SQLite fica no disco da aplicação** — O arquivo `db.sqlite3` sobrevive a reinícios e novos deploys, mas some se a aplicação for excluída — e não pode ir dentro do .zip de atualização, senão sobrescreve os dados. Para produção, use um PostgreSQL gerenciado (a partir do Carbon) com `dj-database-url`. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## FastAPI Fonte: https://docs.rtcloud.com.br/fastapi Publicar uma API FastAPI com Uvicorn, cabeçalhos de proxy e workers, no endereço e na porta da RTCloud. ```python # main.py from fastapi import FastAPI app = FastAPI() @app.get("/") def inicio(): return {"ok": True, "mensagem": "Olá da RTCloud!"} ``` ```text # requirements.txt fastapi==0.115.2 uvicorn[standard]==0.32.0 ``` ### Comando de start ```bash python -m uvicorn main:app --host 0.0.0.0 --port 80 --proxy-headers --forwarded-allow-ips="*" ``` - `main:app` é a variável `app` do arquivo `main.py`. - `--proxy-headers` e `--forwarded-allow-ips` fazem a API enxergar o HTTPS e o IP real de quem acessa — sem isso, os links da documentação (`/docs`) e redirecionamentos saem com `http://`. - Para mais tráfego, acrescente `--workers 2` (cada worker é uma cópia da aplicação na memória). ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`main.py`) e reserve pelo menos **512 MB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com `python -m uvicorn main:app --host 0.0.0.0 --port 80 --proxy-headers --forwarded-allow-ips="*"`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. A documentação interativa fica em `https://seu-nome.rtsystems.app/docs`. Para validar dados de entrada e ler configurações das variáveis de ambiente, veja o guia de Pydantic. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Gunicorn Fonte: https://docs.rtcloud.com.br/gunicorn Servir Flask, Django e FastAPI em produção com Gunicorn: bind, quantos workers cabem na memória e arquivo de configuração. O Gunicorn é o servidor HTTP de produção mais usado no Python. Ele sobe vários processos (workers) com a sua aplicação e distribui as requisições entre eles. ```bash pip install gunicorn # arquivo app.py com a variável app python -m gunicorn --bind 0.0.0.0:80 app:app ``` Usar `python -m gunicorn` em vez de só `gunicorn` garante que é o Gunicorn instalado no ambiente da aplicação. ### Opções que mais importam | Opção | O que faz | | --- | --- | | `--bind 0.0.0.0:80` | Endereço e porta. Obrigatório na RTCloud. | | `--workers 2` | Quantos processos. Cada um é uma cópia da aplicação na memória. | | `--threads 4` | Threads por worker — mais conexões simultâneas sem multiplicar a memória. | | `--worker-class uvicorn.workers.UvicornWorker` | Para aplicações ASGI (FastAPI, Starlette). | | `--timeout 60` | Segundos até um worker travado ser reiniciado. | | `--name minha-api` | Nome dos processos, para reconhecer no log. | > **Workers pela memória, não pela CPU** — A fórmula clássica `2 × CPUs + 1` olha os processadores da máquina inteira, não os da sua aplicação — e multiplica a memória. Comece com 2 workers em 512 MB e 3 ou 4 em 1 GB, e acompanhe o uso na aba **Analytics**. ### Arquivo de configuração ```python # gunicorn.conf.py — lido sozinho quando está na raiz do projeto bind = "0.0.0.0:80" workers = 2 threads = 4 timeout = 60 accesslog = "-" # log de acesso no console ``` Com o arquivo na raiz, o comando de início fica só `python -m gunicorn app:app`. Para Django, `python -m gunicorn meuprojeto.wsgi`. ## Validar dados e configurações com Pydantic Fonte: https://docs.rtcloud.com.br/pydantic Validar o que chega na API com modelos Pydantic e ler as variáveis de ambiente da RTCloud com tipos e valores padrão. O Pydantic transforma dados soltos (JSON, formulário, variáveis de ambiente) em objetos Python com tipo garantido. Se algo não bate, ele explica o quê — antes de o dado ruim chegar no banco. ```text # requirements.txt pydantic==2.9.2 pydantic-settings==2.6.0 email-validator==2.2.0 ``` ### Validando a entrada ```python from pydantic import BaseModel, EmailStr, Field, ValidationError class Cadastro(BaseModel): nome: str = Field(min_length=2, max_length=60) email: EmailStr idade: int = Field(ge=13) try: c = Cadastro(nome="Ana", email="ana@exemplo.com", idade="20") print(c.idade + 1) # 21 — o texto "20" virou int except ValidationError as erro: print(erro.errors()) ``` No FastAPI, basta declarar o modelo como parâmetro da rota: a validação acontece sozinha e a API responde 422 com o motivo quando o dado vem errado. ### Lendo as variáveis de ambiente As variáveis que você cria na aba **Variáveis de Ambiente** chegam ao processo como texto. O `pydantic-settings` lê, converte e reclama logo no início se faltar alguma obrigatória — muito melhor que descobrir no meio de uma requisição. ```python from pydantic_settings import BaseSettings class Config(BaseSettings): database_url: str # obrigatória: DATABASE_URL port: int = 80 # a RTCloud define PORT debug: bool = False # DEBUG=1 vira True config = Config() ``` > **Falhou no início? Leia o log** — Se uma variável obrigatória faltar, a aplicação para logo ao subir e a aba **Logs** mostra exatamente qual campo está faltando. Crie a variável e reinicie. ## Laravel Fonte: https://docs.rtcloud.com.br/laravel Publicar um projeto Laravel: variáveis de produção, migrações, assets com Vite, proxy confiável e Octane com Swoole. O Laravel é reconhecido pelo `composer.json` e as dependências do Composer são instaladas sozinhas. Não envie as pastas `vendor` e `node_modules`. ### Variáveis de ambiente | Variável | Valor | | --- | --- | | `APP_KEY` | Gere com `php artisan key:generate --show` e cole o valor (com o `base64:`). | | `APP_ENV` | `production` | | `APP_DEBUG` | `false` — com `true`, qualquer erro mostra senhas e caminhos para quem visita. | | `APP_URL` | `https://seu-nome.rtsystems.app` (ou o seu domínio) | | `LOG_CHANNEL` | `stderr`, para os logs aparecerem na aba **Logs**. | ### Confiando no proxy As visitas chegam por um proxy com HTTPS. Sem confiar nele, o Laravel gera links e redirecionamentos com `http://`. No Laravel 11 ou mais novo, em `bootstrap/app.php`: ```php ->withMiddleware(function (Middleware $middleware) { $middleware->trustProxies(at: '*'); }) ``` ### Comando de início ```bash npm install && npm run build && php artisan migrate --force && php artisan config:cache && php artisan serve --host=0.0.0.0 --port=80 ``` Sem assets do Vite, tire o `npm install && npm run build`. O comando aceita até 256 caracteres — se precisar de mais passos (`storage:link`, `route:cache`), coloque tudo num `start.sh` e use `sh start.sh`. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`public/index.php`) e reserve pelo menos **512 MB (1 GB com build do Vite)** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com o comando mostrado acima. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Mais desempenho com Octane O `artisan serve` atende bem sites pequenos. Para tráfego maior, instale o Octane (`composer require laravel/octane` e `php artisan octane:install --server=swoole`) e troque o fim do comando por `php artisan octane:start --server=swoole --host=0.0.0.0 --port=80`. O Swoole já está disponível no ambiente. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Spring Boot Fonte: https://docs.rtcloud.com.br/spring-boot Publicar uma API Spring Boot: porta e endereço no application.properties, o jar executável e a memória da JVM. ```text # src/main/resources/application.properties server.port=${PORT:80} server.address=0.0.0.0 # o HTTPS termina no proxy da RTCloud server.forward-headers-strategy=framework ``` `${PORT:80}` lê a variável `PORT` que a RTCloud define, com 80 como reserva. ### Gerando o jar ```bash # Maven ./mvnw clean package -DskipTests # o jar sai em target/, algo como meu-app-0.0.1-SNAPSHOT.jar # Gradle ./gradlew bootJar # o jar sai em build/libs/ ``` O plugin do Spring Boot já empacota as dependências dentro do jar. Copie o arquivo para a raiz do .zip com um nome simples (`app.jar`) — as pastas `target` e `build` saem do pacote na limpeza automática. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`app.jar`) e reserve pelo menos **1 GB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com `java -XX:MaxRAMPercentage=75 -jar app.jar`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **Por que o MaxRAMPercentage** — Sem ele, a JVM usa só uma fração da memória reservada para o heap. Com 75%, ela aproveita o que você reservou e ainda deixa espaço para o resto do processo. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Ruby on Rails Fonte: https://docs.rtcloud.com.br/ruby-on-rails Publicar um app Rails em produção: variáveis, assets, banco e o servidor Puma no endereço certo. O Rails roda pelo Puma, que já vem no projeto. Em produção ele precisa de algumas variáveis e de um comando de início que prepare o banco e os assets antes de subir. ### Variáveis de ambiente | Variável | Valor | | --- | --- | | `RAILS_ENV` | `production` | | `SECRET_KEY_BASE` | Gere com `bin/rails secret`. | | `BUNDLE_WITHOUT` | `development:test` — não instala gems de teste. | | `RAILS_LOG_TO_STDOUT` | `1`, para o log aparecer na aba **Logs**. | | `DATABASE_URL` | A string de conexão do banco, se não usar SQLite. | ### Comando de início ```bash bundle exec rails db:prepare && bundle exec rails assets:precompile && bundle exec rails server -b 0.0.0.0 -p 80 ``` O `db:prepare` cria o banco na primeira vez e roda as migrações pendentes nas seguintes. Como arquivo principal, escolha um `.rb` do projeto, como `config/application.rb` — com o comando de início preenchido, é ele que identifica o projeto como Ruby. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`config/application.rb`) e reserve pelo menos **1 GB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com o comando mostrado acima. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **HTTPS atrás do proxy** — Com `config.force_ssl = true`, deixe também `config.assume_ssl = true` (Rails 7.1 ou mais novo): o HTTPS termina no proxy da RTCloud, e sem isso o Rails entra num laço de redirecionamentos. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Phoenix Fonte: https://docs.rtcloud.com.br/phoenix Publicar um app Phoenix (Elixir) como release: variáveis de produção, build dos assets e o comando que sobe o servidor. Em produção, o Phoenix roda como um release do Mix: um pacote com a aplicação compilada e o comando que a inicia. O build do release acontece aqui, no deploy. ```bash mix phx.new meu_app cd meu_app mix phx.gen.release # cria o rel/ e o módulo de migrações ``` ### Variáveis de ambiente | Variável | Valor | | --- | --- | | `MIX_ENV` | `prod` | | `PHX_SERVER` | `true` — sem ela, o release sobe sem o servidor web. | | `PHX_HOST` | `seu-nome.rtsystems.app` (ou o seu domínio) | | `SECRET_KEY_BASE` | Gere com `mix phx.gen.secret`. | | `DATABASE_URL` | A string de conexão do PostgreSQL. | O `config/runtime.exs` gerado já lê `PORT` (definida pela RTCloud como 80) e escuta em todas as interfaces. ### Build e start | Campo (Opções avançadas) | Valor | | --- | --- | | Comando de build | `mix deps.get --only prod && mix assets.deploy && mix release --overwrite` | | Comando de start | `_build/prod/rel/meu_app/bin/server` | O `bin/server` vem do `phx.gen.release` e já liga o servidor web. Para rodar as migrações antes de subir, use como start `_build/prod/rel/meu_app/bin/migrate && _build/prod/rel/meu_app/bin/server`. Não envie as pastas `_build` e `deps`. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`lib/meu_app.ex`) e reserve pelo menos **1 GB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de build** com `mix deps.get --only prod && mix assets.deploy && mix release --overwrite` e **Comando de start** com `_build/prod/rel/meu_app/bin/server`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **O build roda a cada início** — A RTCloud junta o comando de build e o de start num comando de início só (você o vê na aba **Geral**). Por isso cada reinício recompila o projeto: é normal o site levar um pouco mais para voltar do que um bot. Reserve memória com folga — o build costuma pedir mais que o site rodando. ### Se o endereço não abrir - **Demora para responder ou erro 502:** o código não está escutando em 0.0.0.0 na porta 80. Confira o `listen` e use `process.env.PORT` (ou o equivalente da sua linguagem). - **“Não foi possível encontrar o site”:** confira o subdomínio na aba **Network**. Logo depois do primeiro deploy, espere cerca de um minuto para o endereço começar a responder. - **A aplicação cai sozinha:** quase sempre é memória. Frameworks de site pedem pelo menos 1 GB; aumente na aba **Geral**. - **Erro logo ao iniciar:** a última linha da aba **Logs** diz o motivo. Veja também “A aplicação não inicia”. ## Bot de Discord Fonte: https://docs.rtcloud.com.br/bot-discord Do zero ao bot online: criar a aplicação no Discord, token, intents, código em discord.js ou discord.py, deploy e convite. ### 1. Criando o bot no Discord 1. Entre no Discord Developer Portal, clique em **New Application**, dê um nome e confirme. 2. Na aba **Bot**, clique em **Reset Token** e copie o token. Ele aparece uma vez só. 3. Ainda na aba **Bot**, em **Privileged Gateway Intents**, ligue **Message Content Intent** (e **Server Members Intent**, se o bot lê a lista de membros). > **O token fica em Variáveis de Ambiente** — Nunca escreva o token no código nem no repositório. Crie a variável na aba **Variáveis de Ambiente** da aplicação (ou mande um `.env` no .zip — ele é importado no primeiro deploy) e leia no código. Se o token vazou, gere outro na hora. ### 2. O código **Node.js com discord.js** — `npm install discord.js`: ```javascript // index.js const { Client, GatewayIntentBits, Events } = require("discord.js"); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, ], }); client.once(Events.ClientReady, (c) => console.log(c.user.tag + " está online!")); client.on(Events.MessageCreate, (mensagem) => { if (mensagem.content === "!ping") mensagem.reply("pong!"); }); // um erro passageiro não derruba o processo client.on("error", console.error); process.on("unhandledRejection", console.error); client.login(process.env.DISCORD_TOKEN); ``` **Python com discord.py** — `requirements.txt` com `discord.py`: ```python # main.py import os import discord from discord.ext import commands intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) @bot.event async def on_ready(): print(f"{bot.user} está online!", flush=True) @bot.command() async def ping(ctx): await ctx.reply("pong!") bot.run(os.environ["DISCORD_TOKEN"]) ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker**. Bot não precisa de endereço nem de porta. 4. Confira o **Arquivo principal** (`index.js` ou `main.py`) e reserve pelo menos **256 MB** de memória. 5. Em **Variáveis de Ambiente** (ou num `.env` dentro do .zip), crie `DISCORD_TOKEN` com o token do bot. 6. Publique e acompanhe o log ao vivo até aparecer a linha que o seu código imprime ao conectar. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### 3. Convidando e testando 1. No Developer Portal, abra **OAuth2 → URL Generator**. 2. Marque o escopo **bot** (e **applications.commands**, se usar comandos de barra) e as permissões que o bot precisa. 3. Abra o link gerado, escolha o servidor e autorize. 4. No servidor, mande `!ping`. A resposta confirma que está tudo certo. > **Bot de música** — O FFmpeg já vem instalado. Para tocar de muitas fontes com pouca memória no bot, use um servidor Lavalink — há um guia nesta seção. Bot com áudio pede 512 MB ou mais. ## Bot de Telegram Fonte: https://docs.rtcloud.com.br/bot-telegram Criar o bot no BotFather, escrever o código com grammY ou pyTelegramBotAPI e escolher entre polling e webhook. ### 1. Criando o bot 1. No Telegram, abra a conversa com o **@BotFather** e mande `/newbot`. 2. Escolha o nome e o usuário do bot (precisa terminar em `bot`). 3. Copie o token que o BotFather devolve. > **O token fica em Variáveis de Ambiente** — Nunca escreva o token no código nem no repositório. Crie a variável na aba **Variáveis de Ambiente** da aplicação (ou mande um `.env` no .zip — ele é importado no primeiro deploy) e leia no código. Se o token vazou, gere outro na hora. ### 2. O código **Node.js com grammY** — `npm install grammy`: ```javascript // index.js const { Bot } = require("grammy"); const bot = new Bot(process.env.TELEGRAM_TOKEN); bot.command("start", (ctx) => ctx.reply("Olá! Estou rodando na RTCloud.")); bot.on("message:text", (ctx) => ctx.reply("Você disse: " + ctx.message.text)); bot.catch((erro) => console.error(erro)); bot.start(); console.log("Bot iniciado"); ``` **Python com pyTelegramBotAPI** — `requirements.txt` com `pyTelegramBotAPI`: ```python # main.py import os import telebot bot = telebot.TeleBot(os.environ["TELEGRAM_TOKEN"]) @bot.message_handler(commands=["start"]) def inicio(mensagem): bot.reply_to(mensagem, "Olá! Estou rodando na RTCloud.") @bot.message_handler(func=lambda m: True) def eco(mensagem): bot.reply_to(mensagem, "Você disse: " + mensagem.text) print("Bot iniciado", flush=True) bot.infinity_polling() ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker**. Bot não precisa de endereço nem de porta. 4. Confira o **Arquivo principal** (`index.js` ou `main.py`) e reserve pelo menos **256 MB** de memória. 5. Em **Variáveis de Ambiente**, crie `TELEGRAM_TOKEN` com o token do BotFather. 6. Publique e acompanhe o log ao vivo até aparecer a linha que o seu código imprime ao conectar. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Polling ou webhook | Modo | Como funciona | Na RTCloud | | --- | --- | --- | | Polling | O bot pergunta ao Telegram se há mensagens novas. | Tipo **Bot / worker**, sem endereço. É o modo dos exemplos acima. | | Webhook | O Telegram chama o seu servidor a cada mensagem. | Ligue **Publicar na web**, escute na porta 80 e registre `https://seu-nome.rtsystems.app/webhook` no Telegram. | > **Um modo de cada vez** — Polling e webhook não funcionam juntos, e o mesmo token não pode rodar em dois lugares. Se o bot também estiver ligado no seu computador, o Telegram devolve “Conflict: terminated by other getUpdates request”. ## python-telegram-bot com aiohttp Fonte: https://docs.rtcloud.com.br/python-telegram-bot Trocar o cliente HTTP do python-telegram-bot de httpx para aiohttp quando o bot sofre com timeouts e conexões presas. O python-telegram-bot usa o `httpx` para falar com o Telegram. Em bots com muito movimento, ele pode esgotar o conjunto de conexões e passar a mostrar `httpx.PoolTimeout`, `TimedOut` ou simplesmente parar de responder. Trocar o cliente por `aiohttp` resolve na maioria dos casos — e não muda nada no resto do código. ### Dependências ```text # requirements.txt python-telegram-bot==21.6 aiohttp==3.10.10 git+https://github.com/python-telegram-bot/ptbcontrib.git@main ``` O `ptbcontrib` traz a classe `AiohttpRequest`, que substitui o `httpx` dentro da biblioteca. Ele é instalado direto do repositório oficial, e o `git` já vem no ambiente. ### Usando no Application ```python import os from telegram import Update from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes from ptbcontrib.aiohttp_request import AiohttpRequest async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("Olá! Rodando com aiohttp na RTCloud.") app = ( ApplicationBuilder() .token(os.environ["TELEGRAM_TOKEN"]) .request(AiohttpRequest(connection_pool_size=256)) .get_updates_request(AiohttpRequest()) .build() ) app.add_handler(CommandHandler("start", start)) app.run_polling() ``` Usando o `telegram.Bot` direto, sem o Application? Passe `request=AiohttpRequest()` e `get_updates_request=AiohttpRequest()` no construtor. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker**. Bot não precisa de endereço nem de porta. 4. Confira o **Arquivo principal** (`main.py`) e reserve pelo menos **256 MB** de memória. 5. Em **Variáveis de Ambiente**, crie `TELEGRAM_TOKEN` com o token do BotFather. 6. Publique e acompanhe o log ao vivo até aparecer a linha que o seu código imprime ao conectar. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ## Bot de WhatsApp Fonte: https://docs.rtcloud.com.br/bot-whatsapp whatsapp-web.js com o Chromium do ambiente ou Baileys sem navegador: QR Code, sessão que sobrevive ao reinício e memória. Há dois caminhos populares. O **whatsapp-web.js** abre o WhatsApp Web num navegador sem tela — é o mais fácil de programar, mas consome mais memória. O **Baileys** fala direto com o protocolo, sem navegador, e roda em 256 MB. > **São bibliotecas não oficiais** — O WhatsApp pode banir números que mandam mensagem em massa ou parecem automação. Para atendimento em escala, a API oficial do WhatsApp Business (Cloud API) é o caminho seguro — e roda na RTCloud como qualquer API com webhook. ### whatsapp-web.js ```bash npm install whatsapp-web.js qrcode-terminal ``` ```javascript // index.js const { Client, LocalAuth } = require("whatsapp-web.js"); const qrcode = require("qrcode-terminal"); const client = new Client({ authStrategy: new LocalAuth(), // guarda a sessão em .wwebjs_auth puppeteer: { executablePath: "/usr/bin/chromium", // o Chromium que já vem no ambiente args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"], }, }); client.on("qr", (qr) => qrcode.generate(qr, { small: true })); client.on("ready", () => console.log("WhatsApp conectado!")); client.on("message", (msg) => { if (msg.body === "!ping") msg.reply("pong"); }); client.initialize(); ``` - Crie a variável `PUPPETEER_SKIP_DOWNLOAD` com `true` em **Variáveis de Ambiente**: o Puppeteer deixa de baixar um Chromium próprio na instalação (são centenas de MB) e usa o do ambiente. - Sem `--no-sandbox` o navegador não abre dentro do container. - Reserve **512 MB a 1 GB**. Só o navegador sem tela consome perto de 300 MB. ### Escaneando o QR Code Depois de publicar, abra a aba **Logs**: o QR aparece desenhado no console. No celular, vá em **Aparelhos conectados → Conectar um aparelho** e escaneie. Se o desenho sair torto na sua tela, salve o QR como imagem (`qrcode.toFile("qrcode.png", qr)`, do pacote `qrcode`) e abra pelo **Explorador de arquivos**. > **A sessão sobrevive a reinícios** — A pasta `.wwebjs_auth` fica no disco da aplicação e não é apagada por reinício nem por commit. Só não a envie dentro de um .zip de atualização — ela sobrescreveria a sessão ativa. Ponha `.wwebjs_auth/` no `.rtcloudignore`. ### Baileys (sem navegador) ```bash npm install @whiskeysockets/baileys qrcode-terminal ``` ```javascript // index.js const { default: makeWASocket, useMultiFileAuthState, DisconnectReason } = require("@whiskeysockets/baileys"); const qrcode = require("qrcode-terminal"); async function iniciar() { const { state, saveCreds } = await useMultiFileAuthState("auth"); const sock = makeWASocket({ auth: state }); sock.ev.on("creds.update", saveCreds); sock.ev.on("connection.update", ({ connection, qr, lastDisconnect }) => { if (qr) qrcode.generate(qr, { small: true }); if (connection === "open") console.log("WhatsApp conectado!"); if (connection === "close") { const saiu = lastDisconnect?.error?.output?.statusCode === DisconnectReason.loggedOut; if (!saiu) iniciar(); // reconecta; se a sessão foi encerrada no celular, escaneie de novo } }); sock.ev.on("messages.upsert", async ({ messages }) => { const msg = messages[0]; if (!msg.message || msg.key.fromMe) return; if (msg.message.conversation === "!ping") { await sock.sendMessage(msg.key.remoteJid, { text: "pong" }); } }); } iniciar(); ``` A sessão do Baileys fica na pasta `auth` — mesma regra: ela persiste no disco, mas não deve ir no .zip de atualização. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker**. Bot não precisa de endereço nem de porta. 4. Confira o **Arquivo principal** (`index.js`) e reserve pelo menos **512 MB com whatsapp-web.js ou 256 MB com Baileys** de memória. 5. Publique e acompanhe o log ao vivo até aparecer a linha que o seu código imprime ao conectar. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. O whatsapp-web.js travou em “carregando” depois de uma atualização do WhatsApp Web? Atualize a biblioteca para a versão mais nova; se ainda assim não conectar, use a opção `webVersionCache` do tipo `remote` para fixar uma versão do WhatsApp Web que sabidamente funciona. ## Bot de Slack Fonte: https://docs.rtcloud.com.br/bot-slack Um app de Slack com Bolt em Node.js ou Python, no Socket Mode (sem endereço) ou recebendo eventos por HTTP. ### 1. Criando o app no Slack 1. Em api.slack.com/apps, clique em **Create New App → From scratch**, dê um nome e escolha o workspace. 2. Em **OAuth & Permissions**, adicione os escopos de bot `app_mentions:read`, `chat:write` e `commands`. Instale no workspace e copie o **Bot User OAuth Token** (`xoxb-…`). 3. Em **Basic Information**, copie o **Signing Secret**. 4. Para o Socket Mode: em **Socket Mode**, ligue a opção e gere um **App-Level Token** (`xapp-…`) com o escopo `connections:write`. > **Tokens e Signing Secret fica em Variáveis de Ambiente** — Nunca escreva o token no código nem no repositório. Crie a variável na aba **Variáveis de Ambiente** da aplicação (ou mande um `.env` no .zip — ele é importado no primeiro deploy) e leia no código. Se o token vazou, gere outro na hora. ### 2. O código (Socket Mode) No Socket Mode o próprio bot abre a conexão com o Slack — não precisa de endereço público nem de porta. É o jeito mais simples de hospedar. `npm install @slack/bolt`: ```javascript // index.js const { App } = require("@slack/bolt"); const app = new App({ token: process.env.SLACK_BOT_TOKEN, appToken: process.env.SLACK_APP_TOKEN, socketMode: true, }); app.event("app_mention", async ({ event, say }) => { await say(" obrigado por me chamar!"); }); app.command("/ola", async ({ ack, respond }) => { await ack(); await respond("Olá da RTCloud!"); }); (async () => { await app.start(); console.log("App do Slack rodando"); })(); ``` Em Python, com `slack_bolt` no `requirements.txt`: ```python # main.py import os from slack_bolt import App from slack_bolt.adapter.socket_mode import SocketModeHandler app = App(token=os.environ["SLACK_BOT_TOKEN"]) @app.event("app_mention") def mencao(event, say): say(f" obrigado por me chamar!") @app.command("/ola") def ola(ack, respond): ack() respond("Olá da RTCloud!") SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start() ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker**. Bot não precisa de endereço nem de porta. 4. Confira o **Arquivo principal** (`index.js` ou `main.py`) e reserve pelo menos **256 MB** de memória. 5. Em **Variáveis de Ambiente**, crie `SLACK_BOT_TOKEN` e `SLACK_APP_TOKEN`. 6. Publique e acompanhe o log ao vivo até aparecer a linha que o seu código imprime ao conectar. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Recebendo eventos por HTTP Sem Socket Mode, o Slack chama o seu servidor. Publique como **Site ou API**, inicie o Bolt com `signingSecret: process.env.SLACK_SIGNING_SECRET` e `await app.start(process.env.PORT || 80)`, e cadastre `https://seu-nome.rtsystems.app/slack/events` como **Request URL** em **Event Subscriptions** e nos comandos de barra. ## Bot do X (Twitter) Fonte: https://docs.rtcloud.com.br/bot-x-twitter Credenciais no portal de desenvolvedor do X, permissão de escrita, um bot que publica em Node.js ou Python e os limites da API. ### 1. Credenciais 1. No portal de desenvolvedor do X, crie um projeto e, dentro dele, um app. 2. Em **User authentication settings**, defina a permissão como **Read and write**. Faça isso **antes** de gerar os tokens de acesso — tokens gerados antes da mudança continuam só de leitura. 3. Em **Keys and tokens**, copie a **API Key** e a **API Key Secret** e gere o **Access Token** e o **Access Token Secret**. > **As quatro chaves fica em Variáveis de Ambiente** — Nunca escreva o token no código nem no repositório. Crie a variável na aba **Variáveis de Ambiente** da aplicação (ou mande um `.env` no .zip — ele é importado no primeiro deploy) e leia no código. Se o token vazou, gere outro na hora. > **O nível gratuito da API é limitado** — No acesso gratuito, a API do X permite basicamente publicar, com uma cota mensal pequena. Ler menções, buscar posts e acompanhar hashtags exige um plano pago da API. Confira o seu nível no portal antes de programar a leitura. ### 2. Um bot que publica (Node.js) ```bash npm install twitter-api-v2 ``` ```javascript // index.js const { TwitterApi } = require("twitter-api-v2"); const cliente = new TwitterApi({ appKey: process.env.X_API_KEY, appSecret: process.env.X_API_SECRET, accessToken: process.env.X_ACCESS_TOKEN, accessSecret: process.env.X_ACCESS_SECRET, }).readWrite; async function publicar() { try { const { data } = await cliente.v2.tweet("Bom dia! Post automático da RTCloud ☁️"); console.log("Publicado:", data.id); } catch (erro) { // 429 = limite da API: espere em vez de insistir console.error("Falha ao publicar:", erro.code, erro.data?.detail); } } publicar(); setInterval(publicar, 24 * 60 * 60 * 1000); // uma vez por dia ``` ### Em Python ```python # main.py — requirements.txt com tweepy import os, time import tweepy cliente = tweepy.Client( consumer_key=os.environ["X_API_KEY"], consumer_secret=os.environ["X_API_SECRET"], access_token=os.environ["X_ACCESS_TOKEN"], access_token_secret=os.environ["X_ACCESS_SECRET"], ) while True: try: r = cliente.create_tweet(text="Bom dia! Post automático da RTCloud ☁️") print("Publicado:", r.data["id"], flush=True) except tweepy.TooManyRequests: print("Limite da API — tentando de novo amanhã", flush=True) time.sleep(24 * 60 * 60) ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker**. Bot não precisa de endereço nem de porta. 4. Confira o **Arquivo principal** (`index.js` ou `main.py`) e reserve pelo menos **256 MB** de memória. 5. Em **Variáveis de Ambiente**, crie `X_API_KEY`, `X_API_SECRET`, `X_ACCESS_TOKEN` e `X_ACCESS_SECRET`. 6. Publique e acompanhe o log ao vivo até aparecer a linha que o seu código imprime ao conectar. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Boas práticas - Respeite os limites: diante de um erro 429, espere o tempo indicado em `x-rate-limit-reset` antes de tentar de novo. - Não publique o mesmo texto repetido — a API recusa posts duplicados. - Agendamento com `setInterval` se perde num reinício. Para horários exatos, guarde a próxima execução num banco ou num arquivo. ## Webhook de votos do Top.gg Fonte: https://docs.rtcloud.com.br/webhook-topgg Receber os votos do seu bot no Top.gg com uma rota HTTP na RTCloud, em Node.js ou Python, com a autorização conferida. Quando alguém vota no seu bot, o Top.gg faz um POST num endereço seu. Esse endereço pode ser o próprio bot — basta ligar **Publicar na web** na aplicação (bots com rotas HTTP também podem ter endereço) — ou uma aplicação separada. ### Node.js ```bash npm install express @top-gg/sdk ``` ```javascript // webhook.js const express = require("express"); const Topgg = require("@top-gg/sdk"); const app = express(); const webhook = new Topgg.Webhook(process.env.TOPGG_WEBHOOK_AUTH); app.post("/topgg", webhook.listener((voto) => { console.log("Voto recebido do usuário " + voto.user); // aqui entra a recompensa: moedas, cargo, mensagem... })); app.listen(process.env.PORT || 80, "0.0.0.0"); ``` ### Python ```python # main.py — requirements.txt com flask e waitress import os from flask import Flask, request, abort from waitress import serve app = Flask(__name__) SEGREDO = os.environ["TOPGG_WEBHOOK_AUTH"] @app.post("/topgg") def voto(): if request.headers.get("Authorization") != SEGREDO: abort(401) dados = request.get_json() print("Voto recebido do usuário", dados["user"], flush=True) return "", 204 serve(app, host="0.0.0.0", port=int(os.environ.get("PORT", 80))) ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`webhook.js` ou `main.py`) e reserve pelo menos **512 MB** de memória. 5. Em **Variáveis de Ambiente**, crie `TOPGG_WEBHOOK_AUTH` com uma senha longa e aleatória. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Ligando no Top.gg 1. Na página do bot no Top.gg, abra **Edit → Webhooks**. 2. Em **Webhook URL**, coloque `https://seu-nome.rtsystems.app/topgg`. 3. Em **Authorization**, a mesma senha de `TOPGG_WEBHOOK_AUTH`. 4. Salve e clique em **Send Test**. O voto de teste aparece na aba **Logs**. > **Recebeu 401?** — A senha do Top.gg e a da variável não são iguais — confira espaços e aspas. Depois de mudar a variável, reinicie a aplicação. ## Servidor Lavalink Fonte: https://docs.rtcloud.com.br/lavalink Hospedar o Lavalink para os bots de música: application.yml, senha, plugins e como o bot se conecta pela porta 443. O Lavalink é um servidor em Java que busca e transmite o áudio para os bots de música. Rodá-lo numa aplicação separada tira esse peso do bot e permite usar o mesmo servidor em vários bots. ### Arquivos do pacote - `Lavalink.jar` — baixe a versão mais recente na página de releases do projeto oficial do Lavalink. - `application.yml` — a configuração, ao lado do jar. ```yaml # application.yml (o essencial) server: port: 80 address: 0.0.0.0 lavalink: server: password: "${LAVALINK_SERVER_PASSWORD}" sources: youtube: false # o YouTube vem pelo plugin abaixo soundcloud: true bandcamp: true http: true plugins: # troque pela versão mais recente do plugin - dependency: "dev.lavalink.youtube:youtube-plugin:1.11.2" plugins: youtube: enabled: true ``` > **Senha forte, fora do arquivo** — Qualquer um que souber o endereço e a senha usa o seu Lavalink. Crie a variável `LAVALINK_SERVER_PASSWORD` com pelo menos 32 caracteres aleatórios — o `application.yml` acima já lê dela. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`Lavalink.jar`) e reserve pelo menos **1 GB** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com `java -XX:MaxRAMPercentage=75 -jar Lavalink.jar`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Conectando o bot | Campo do cliente | Valor | | --- | --- | | Host | `seu-nome.rtsystems.app` | | Porta | `443` | | Seguro (SSL/TLS) | `true` | | Senha | o valor de `LAVALINK_SERVER_PASSWORD` | O Lavalink escuta na porta 80 dentro da aplicação, mas o bot chega até ele pelo endereço público com HTTPS — por isso a porta 443 e `secure: true`. > **Erro 1006 ao conectar** — Quase sempre é versão trocada: cliente feito para o Lavalink 3 falando com um servidor 4, ou o contrário. Use a mesma versão principal nos dois lados. ## n8n Fonte: https://docs.rtcloud.com.br/n8n Hospedar o n8n para automações: package.json, variáveis de endereço e webhook, chave de criptografia, versão do Node e memória. O n8n é distribuído como pacote npm, então o projeto é só um `package.json` que o instala e o inicia. ```json { "name": "meu-n8n", "version": "1.0.0", "private": true, "scripts": { "start": "n8n start" }, "dependencies": { "n8n": "1.64.0" } } ``` Fixe a versão do `n8n` (em vez de `latest`) para atualizar quando você quiser, não quando sair uma versão nova. ### Variáveis de ambiente | Variável | Valor | Para quê | | --- | --- | --- | | `N8N_PORT` | `80` | A porta em que a RTCloud procura o site. | | `N8N_LISTEN_ADDRESS` | `0.0.0.0` | Escutar em todas as interfaces. | | `N8N_HOST` | `seu-nome.rtsystems.app` | O endereço público, usado nos links. | | `N8N_PROTOCOL` | `https` | O endereço público tem HTTPS. | | `WEBHOOK_URL` | `https://seu-nome.rtsystems.app/` | Sem ela, os webhooks aparecem com `localhost` no editor. | | `N8N_ENCRYPTION_KEY` | texto longo e aleatório | Cifra as credenciais salvas. Guarde: sem ela, as credenciais não abrem mais. | | `GENERIC_TIMEZONE` | `America/Sao_Paulo` | Horário dos gatilhos agendados. | > **Use a versão Estável** — O n8n declara as versões de Node que suporta, e a mais nova costuma chegar antes do suporte dele. Em **Opções avançadas** (ou depois, na aba **Geral**), escolha **Estável (Node 24)**. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **2 GB (o n8n é pesado; com muitos fluxos, mais)** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com `npm run start`. 6. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Onde ficam os dados Por padrão o n8n guarda fluxos, execuções e credenciais num SQLite dentro da própria aplicação. Ele sobrevive a reinícios e atualizações, mas não à exclusão da aplicação — faça snapshots. Para produção, aponte o n8n para um PostgreSQL gerenciado (variáveis `DB_TYPE=postgresdb` e `DB_POSTGRESDB_*`). ## Evolution API Fonte: https://docs.rtcloud.com.br/evolution-api Hospedar a Evolution API (WhatsApp) com PostgreSQL gerenciado, Redis opcional, chave de acesso e o build na primeira subida. A Evolution API gerencia várias instâncias de WhatsApp por uma API HTTP e se integra a n8n, Chatwoot e outras ferramentas. Baixe o código da versão desejada no repositório oficial do projeto e trabalhe a partir do `.env.example` dele. > **Precisa de banco de dados** — A Evolution API guarda instâncias e mensagens num PostgreSQL. Bancos gerenciados estão disponíveis a partir do plano Carbon — crie o banco antes de começar. ### Servidor e acesso ```text SERVER_TYPE=http SERVER_PORT=80 SERVER_URL=https://seu-nome.rtsystems.app LANGUAGE=pt-BR # a chave que protege a API inteira — longa e aleatória AUTHENTICATION_API_KEY=troque-por-uma-chave-forte ``` ### Banco de dados O banco gerenciado só aceita conexão com certificado. A Evolution API usa o Prisma, que pede o certificado no formato `.p12`: converta o `.pem` baixado na tela do banco e envie o `.p12` junto com o projeto. ```bash openssl pkcs12 -export -in certificado.pem -out cliente.p12 -passout pass:SENHA_DO_P12 ``` ```text DATABASE_PROVIDER=postgresql DATABASE_CONNECTION_URI=postgresql://USUARIO:SENHA@ENDERECO:PORTA/BANCO?sslmode=require&sslidentity=cliente.p12&sslpassword=SENHA_DO_P12 DATABASE_CONNECTION_CLIENT_NAME=evolution DATABASE_SAVE_DATA_INSTANCE=true DATABASE_SAVE_DATA_NEW_MESSAGE=true DATABASE_SAVE_DATA_CONTACTS=true DATABASE_SAVE_DATA_CHATS=true ``` Senha com `@`, `:` ou `/` precisa ser codificada na URL (`@` vira `%40`). ### Primeira subida: build e migrações Na primeira vez, a aplicação precisa gerar o cliente do Prisma, aplicar as migrações no banco e compilar. Use este comando de início e reserve **3 GB** — a compilação é a parte mais pesada: ```bash npx prisma generate --schema prisma/postgresql-schema.prisma && npm run db:deploy && npm run build && npm run start:prod ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Reserve pelo menos **3 GB na primeira subida** de memória. 5. Abra **Opções avançadas** e preencha **Comando de start** com o comando mostrado acima. 6. Leve as variáveis do `.env` para a aba **Variáveis de Ambiente** (ou envie o `.env` no .zip — ele é importado no primeiro deploy). 7. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **Depois da primeira vez, mais leve** — Com a aplicação no ar, troque o comando de início (aba **Geral**) para só `npm run start:prod` e baixe a memória para 1,5 a 2 GB. O build já fica no disco da aplicação. Ao atualizar a versão da Evolution API, volte ao comando completo uma vez. ### Cache com Redis (opcional) ```text CACHE_REDIS_ENABLED=true CACHE_REDIS_URI=rediss://default:SENHA@ENDERECO:PORTA CACHE_REDIS_PREFIX_KEY=evolution CACHE_REDIS_SAVE_INSTANCES=false ``` Repare no `rediss://`, com dois “s”: o Redis gerenciado só aceita conexão cifrada. ## Uptime Kuma Fonte: https://docs.rtcloud.com.br/uptime-kuma Hospedar o Uptime Kuma para monitorar sites, APIs e bots: o código da versão, o download da interface e onde ficam os dados. O Uptime Kuma monitora endereços, portas e palavras-chave e avisa quando algo cai — por Discord, Telegram, e-mail e dezenas de outros canais. Ele roda como aplicação Node.js comum. ### Preparando 1. No repositório oficial do Uptime Kuma, abra a página de releases e baixe o código-fonte (.zip) da versão estável mais recente. 2. Envie esse .zip como está no **Novo deploy**, escolhendo **Site ou API**. 3. Em **Opções avançadas**, preencha **Comando de build** com `npm run download-dist` (baixa a interface já compilada da mesma versão) e **Comando de start** com `node server/server.js`. 4. Escolha **Estável (Node 24)** na versão da linguagem e reserve **512 MB** — use a versão 2.x do Uptime Kuma, que roda no Node 24. O Uptime Kuma lê as variáveis `PORT` e `HOST`, que a RTCloud já define — ele sobe na porta 80 sem configurar nada. Na primeira visita a `https://seu-nome.rtsystems.app`, ele pede para criar o usuário administrador. > **Os dados ficam na pasta data** — Monitores, histórico e configurações ficam em `data/`, no disco da aplicação: sobrevivem a reinícios e atualizações. Faça snapshots de vez em quando — e não envie uma pasta `data` vazia num .zip de atualização. Para monitorar outras aplicações da RTCloud, use o endereço público delas (`https://outra-app.rtsystems.app`). Monitorar a própria aplicação do Uptime Kuma não faz sentido: se ela cair, não há quem avise. ## pgAdmin Fonte: https://docs.rtcloud.com.br/pgadmin Hospedar o pgAdmin para administrar o seu PostgreSQL de qualquer lugar: dependências, configuração, usuário inicial e conexão com certificado. O pgAdmin é distribuído como pacote Python e roda pelo Gunicorn. O projeto tem três arquivos pequenos. ### requirements.txt ```text pgadmin4 gunicorn ``` ### config_local.py Diz ao pgAdmin para rodar em modo servidor (com login) e guardar os dados numa pasta do projeto, que persiste no disco da aplicação: ```python import os PASTA = os.path.join(os.path.dirname(os.path.abspath(__file__)), "pgadmin-dados") SERVER_MODE = True MAX_LOGIN_ATTEMPTS = 3 DATA_DIR = PASTA LOG_FILE = os.path.join(PASTA, "pgadmin4.log") SQLITE_PATH = os.path.join(PASTA, "pgadmin4.db") SESSION_DB_PATH = os.path.join(PASTA, "sessoes") STORAGE_DIR = os.path.join(PASTA, "arquivos") ``` ### main.py Encontra onde o pip instalou o pgAdmin e sobe o Gunicorn apontando para lá, com o `config_local.py` do projeto no caminho: ```python import importlib.util import os import sys PROJETO = os.path.dirname(os.path.abspath(__file__)) PGADMIN = list(importlib.util.find_spec("pgadmin4").submodule_search_locations)[0] PORTA = os.environ.get("PORT", "80") os.execvp(sys.executable, [ sys.executable, "-m", "gunicorn", "--bind", "0.0.0.0:" + PORTA, "--workers", "1", "--threads", "25", "--chdir", PGADMIN, "--pythonpath", PROJETO, "pgAdmin4:app", ]) ``` ### Usuário inicial Na primeira subida, o pgAdmin cria o administrador a partir de duas variáveis. Crie-as em **Variáveis de Ambiente** antes de publicar: ```text PGADMIN_SETUP_EMAIL=voce@exemplo.com PGADMIN_SETUP_PASSWORD=uma-senha-longa-e-forte ``` ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Site ou API**, deixe **Publicar na web** ligado e escolha o subdomínio — o endereço fica `seu-nome.rtsystems.app`, já com HTTPS. 4. Confira o **Arquivo principal** (`main.py`) e reserve pelo menos **1 GB** de memória. 5. Publique e acompanhe o log ao vivo. Quando aparecer “no ar”, abra `https://seu-nome.rtsystems.app`. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. ### Conectando ao banco gerenciado No pgAdmin, em **Register → Server**, use o endereço, a porta, o usuário e a senha da tela do banco. Na aba **Parameters**, defina **SSL mode** como `require` e aponte **Client certificate**, **Client certificate key** e **Root certificate** para o `.pem` baixado no painel — envie-o antes pelo gerenciador de arquivos do próprio pgAdmin. ## Selenium e automação de navegador Fonte: https://docs.rtcloud.com.br/selenium Rodar Selenium com o Chromium e o ChromeDriver que já vêm no ambiente: opções obrigatórias, caminho do driver e memória. O ambiente da RTCloud já traz o Chromium e o ChromeDriver instalados. Você só instala a biblioteca do Selenium — nada de baixar navegador ou driver. ```text # requirements.txt selenium==4.25.0 ``` ```python # main.py import time from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service opcoes = Options() opcoes.add_argument("--headless=new") # sem janela opcoes.add_argument("--no-sandbox") # obrigatório dentro de container opcoes.add_argument("--disable-dev-shm-usage") # evita travar em páginas grandes opcoes.add_argument("--window-size=1920,1080") # o ChromeDriver do ambiente; ele já sabe onde está o Chromium driver = webdriver.Chrome(service=Service("/usr/bin/chromedriver"), options=opcoes) try: while True: driver.get("https://www.exemplo.com") driver.save_screenshot("pagina.png") print("Captura salva:", driver.title, flush=True) time.sleep(60) finally: driver.quit() ``` - **`/usr/bin/chromedriver`** — informe sempre o caminho. Sem ele, o Selenium tenta baixar um driver e pode pegar uma versão que não casa com o Chromium. - **`--no-sandbox`** — sem ele, o navegador não abre dentro do container. - **`driver.quit()`** — cada navegador esquecido aberto consome memória até a aplicação cair. - A captura `pagina.png` aparece no **Explorador de arquivos** da aplicação. ### Publicando na RTCloud 1. Compacte o projeto num **.zip** com o arquivo de dependências na raiz — ou deixe o código num repositório do GitHub. Pastas como `node_modules`, `.venv` e `.git` podem ficar de fora: o painel tira e o ambiente reinstala. 2. No painel, abra **Novo deploy** e escolha **Enviar ZIP** ou **GitHub**. 3. Em **Tipo**, escolha **Bot / worker**. Bot não precisa de endereço nem de porta. 4. Confira o **Arquivo principal** (`main.py`) e reserve pelo menos **512 MB (1 GB para páginas pesadas)** de memória. 5. Publique e acompanhe o log ao vivo até aparecer a linha que o seu código imprime ao conectar. Para publicar uma versão nova, use a aba **Commit** da aplicação (envie o .zip de novo ou só o arquivo que mudou). Com o GitHub conectado, cada push na branch escolhida publica sozinho. Memória, versão da linguagem, comando de início e reinício automático ficam na aba **Geral**. > **Puppeteer e Playwright também funcionam** — Use o mesmo Chromium: `executablePath: "/usr/bin/chromium"` e `args: ["--no-sandbox"]`. Crie `PUPPETEER_SKIP_DOWNLOAD=true` em **Variáveis de Ambiente** para a instalação não baixar outro navegador. ## Migrar do Heroku Fonte: https://docs.rtcloud.com.br/migrar-do-heroku Procfile, Config Vars, Heroku Postgres e domínio: o equivalente de cada coisa na RTCloud e o passo a passo da mudança. No Heroku, cada dyno, add-on e hora de processamento entra na conta separadamente. Na RTCloud o plano tem preço fixo em reais, com memória reservada para as suas aplicações e renovação por Pix — e as aplicações não dormem. ### O que vira o quê | Heroku | RTCloud | | --- | --- | | `Procfile` com `web:` | Uma aplicação do tipo **Site ou API**; o comando vira o **Comando de start** (aba **Geral**). | | `Procfile` com `worker:` | Outra aplicação, do tipo **Bot / worker**. Cada tipo de processo é uma aplicação. | | Buildpacks | Detecção automática da linguagem pelo pacote. Não há buildpack para escolher. | | Release phase | Os passos entram no começo do comando de início (`python manage.py migrate && …`). | | Config Vars | **Variáveis de Ambiente** da aplicação — ou um `.env` no .zip. | | Heroku Postgres / Redis | Banco gerenciado (PostgreSQL, MySQL, MongoDB ou Redis), a partir do plano Carbon. | | Heroku Scheduler | Um agendador no próprio código (`node-cron`, `APScheduler`) rodando numa aplicação. | | Domínio próprio | Menu **Domínios**, com SSL automático, a partir do plano Carbon. | | `git push heroku main` | Deploy pelo GitHub (cada push publica) ou .zip no **Novo deploy** e na aba **Commit**. | ### Passo a passo 1. **Comando de início.** Copie o que vem depois de `web:` no `Procfile` (por exemplo `gunicorn app:app`) e acrescente o endereço e a porta: `gunicorn app:app --bind 0.0.0.0:80`. Quem já lê `process.env.PORT` ou `$PORT` não precisa mudar nada — a variável continua existindo, agora com 80. 2. **Variáveis.** Rode `heroku config -s > .env` na sua máquina. Envie esse `.env` dentro do .zip do primeiro deploy (ele é importado automaticamente) ou cole os valores em **Variáveis de Ambiente**. Tire do arquivo as variáveis que o próprio Heroku criava, como `DATABASE_URL` do Heroku Postgres. 3. **Deploy.** Em **Novo deploy**, conecte o repositório do GitHub ou envie o .zip. Escolha **Site ou API** para o `web` e repita com **Bot / worker** para cada `worker`. 4. **Banco de dados.** Crie o banco gerenciado, exporte os dados do Heroku com `pg_dump` e restaure no banco novo (veja abaixo). Atualize `DATABASE_URL` com a string de conexão nova. 5. **Teste pelo endereço `seu-nome.rtsystems.app`.** Só depois de tudo funcionando, aponte o domínio em **Domínios**. ### Levando o PostgreSQL ```bash # 1. exporta do Heroku pg_dump --no-owner --no-acl "URL_DO_HEROKU" > backup.sql # 2. restaura no banco gerenciado da RTCloud (conexão com o certificado baixado no painel) psql "postgresql://USUARIO:SENHA@ENDERECO:PORTA/BANCO?sslmode=require&sslcert=certificado.pem&sslkey=certificado.pem" < backup.sql ``` > **Planeje uma janela de manutenção** — Entre o `pg_dump` e a troca do `DATABASE_URL`, o que for gravado no banco antigo não vem junto. Pare as escritas (modo manutenção) durante a cópia em aplicações com movimento. ### Diferenças que pegam de surpresa - **O disco não é apagado a cada reinício.** No Heroku, arquivos gravados somem quando o dyno reinicia; aqui eles ficam — o que é bom, mas pode mascarar código que depende de começar do zero. - **Sem dyno gratuito.** Existe um teste grátis de 24 horas para um bot, sem cartão. Para manter no ar, é preciso um plano. - **Cada worker é uma aplicação**, com a sua memória reservada do plano. Some as memórias para escolher o plano certo. ## Migrar do Railway Fonte: https://docs.rtcloud.com.br/migrar-do-railway Serviços, variáveis, plugins de banco e volumes do Railway e o equivalente de cada um na RTCloud, com o passo a passo. O Railway cobra pelo uso medido — CPU, memória e rede por segundo —, e a fatura acompanha o tráfego. Na RTCloud o preço do plano é fixo, em reais, e o tráfego não é cobrado à parte: você dimensiona pela memória que as aplicações precisam. ### O que vira o quê | Railway | RTCloud | | --- | --- | | Serviço | Uma aplicação: **Site ou API** se tem domínio, **Bot / worker** se não tem. | | Nixpacks / `railway.json` | Detecção automática da linguagem + **Comando de build** e **Comando de start** no deploy. | | Variables | **Variáveis de Ambiente** da aplicação — ou um `.env` no .zip. | | Plugins de Postgres, MySQL, Redis, MongoDB | Bancos gerenciados, a partir do plano Carbon. | | Volumes | O disco da própria aplicação, que persiste entre reinícios e deploys. | | `railway up` / deploy por push | Deploy pelo GitHub (cada push publica) ou .zip no **Novo deploy** e na aba **Commit**. | | Domínio `*.up.railway.app` | Subdomínio `seu-nome.rtsystems.app` com HTTPS. | | Cron jobs | Um agendador no próprio código, rodando numa aplicação. | ### Passo a passo 1. **Variáveis.** Na aba **Variables** de cada serviço, use o editor em modo texto (Raw) e copie tudo para um `.env`. Remova as referências do Railway (`${{Postgres.DATABASE_URL}}` e afins) — elas serão trocadas pelos valores novos. 2. **Comandos.** Se o serviço tinha comandos de build e start personalizados, leve-os para **Opções avançadas** no Novo deploy. O código precisa escutar em `0.0.0.0` na porta da variável `PORT` (aqui, 80). 3. **Deploy.** Em **Novo deploy**, conecte o mesmo repositório do GitHub ou envie um .zip. Uma aplicação por serviço. 4. **Bancos.** Crie os bancos gerenciados equivalentes, copie os dados (`pg_dump`/`psql`, `mysqldump`, `mongodump`/`mongorestore`) e atualize as strings de conexão. 5. **Domínio.** Com tudo funcionando no endereço da RTCloud, aponte o domínio em **Domínios**. > **Serviços que conversavam pela rede privada** — No Railway, serviços do mesmo projeto se falam por endereços internos (`*.railway.internal`). Na RTCloud, use o endereço público com HTTPS da outra aplicação e proteja a rota com uma chave em variável de ambiente. > **Copie os dados com as escritas paradas** — O que for gravado no banco antigo depois da exportação não vem junto. Em aplicações com movimento, ative um modo de manutenção durante a cópia. ## Migrar do Render Fonte: https://docs.rtcloud.com.br/migrar-do-render Web services, background workers, cron jobs, PostgreSQL, Key Value e discos do Render e o equivalente de cada um na RTCloud, com o passo a passo. No plano gratuito do Render, o serviço web hiberna depois de um tempo sem acesso e demora para acordar na próxima visita — ruim para bot e para API. Na RTCloud a aplicação fica no ar 24 horas nos planos pagos, com preço fixo em reais e pagamento por Pix Automático. ### O que vira o quê | Render | RTCloud | | --- | --- | | Web Service | Uma aplicação do tipo **Site ou API**, com endereço `seu-nome.rtsystems.app` e HTTPS. | | Background Worker | Uma aplicação do tipo **Bot / worker** (sem endereço público). | | Cron Job | Um agendador no próprio código, rodando numa aplicação. | | Static Site | Um **site estático** — ou o site compilado (React, Vue, Vite) publicado como site. | | Environment / Environment Groups | **Variáveis de Ambiente** de cada aplicação — ou um `.env` no .zip. | | `render.yaml` (Blueprint) | Detecção automática da linguagem + **Comando de build** e **Comando de start** no deploy. | | PostgreSQL e Key Value | Bancos gerenciados (PostgreSQL e Redis), a partir do plano Carbon. | | Persistent Disk | O disco da própria aplicação, que persiste entre reinícios e deploys. | | Deploy a cada push | Deploy automático pelo GitHub: cada push na branch publica a versão nova. | | Domínio `*.onrender.com` | Subdomínio `seu-nome.rtsystems.app` com HTTPS, e domínio próprio a partir do Carbon. | ### Passo a passo 1. **Variáveis.** No Render, abra **Environment** de cada serviço (e os Environment Groups, se usar) e copie as variáveis para um `.env`. Deixe de fora as que apontam para recursos do Render, como a URL interna do banco — elas serão trocadas pelos valores novos. 2. **Porta.** Mantenha o código lendo a variável `PORT` e escutando em `0.0.0.0` — na RTCloud a porta é 80. 3. **Comandos.** Leve o **Build Command** e o **Start Command** de cada serviço para **Opções avançadas** no Novo deploy. 4. **Deploy.** Em **Novo deploy**, conecte o mesmo repositório do GitHub ou envie um .zip. Uma aplicação por serviço: web service vira **Site ou API**; background worker vira **Bot / worker**. 5. **Bancos.** Crie os bancos gerenciados equivalentes, copie os dados (`pg_dump`/`psql` no PostgreSQL) e atualize as strings de conexão. 6. **Domínio.** Com tudo funcionando no endereço da RTCloud, aponte o domínio em **Domínios** — e só então desligue o serviço no Render. > **Serviços que conversavam pela rede privada** — No Render, serviços da mesma conta se falam por endereços internos. Na RTCloud, use o endereço público com HTTPS da outra aplicação e proteja a rota com uma chave em variável de ambiente. > **Copie os dados com as escritas paradas** — O que for gravado no banco antigo depois da exportação não vem junto. Em aplicações com movimento, ative um modo de manutenção durante a cópia. ## Migrar de uma VPS ou de outra hospedagem Fonte: https://docs.rtcloud.com.br/migrar-de-vps O checklist para trazer um projeto que roda em VPS, painel de bot ou outra RTCloud: código, processos, variáveis, arquivos, banco e DNS. Numa VPS você cuidava de tudo: Node ou Python instalado, PM2 ou systemd para manter o processo vivo, Nginx na frente, Certbot para o SSL. Na RTCloud essas peças já existem — a migração é, em boa parte, deixar de fazer coisas. ### O que você não precisa mais | Na VPS | Na RTCloud | | --- | --- | | PM2, systemd, `screen` | A plataforma mantém o processo no ar e tem **reinício automático** (aba **Geral**). | | Nginx como proxy | O endereço público já chega na sua aplicação, na porta 80. | | Certbot / Let's Encrypt | SSL automático no subdomínio e no seu domínio. | | `apt install ffmpeg chromium` | Já vêm instalados no ambiente. | | `crontab` | Um agendador no próprio código (`node-cron`, `APScheduler`). | | SSH e terminal | Explorador de arquivos, console ao vivo e variáveis — tudo no painel. | ### Checklist da mudança 1. **Código.** Gere um .zip só com o projeto — sem `node_modules`, `venv`, logs e backups. Confira se o arquivo de dependências está completo: o que foi instalado à mão na VPS e não está no `package.json`/`requirements.txt` não vem junto. 2. **Um processo, uma aplicação.** Cada entrada do PM2 (ou serviço do systemd) vira uma aplicação. O que estava no `ecosystem.config.js` (script, argumentos, variáveis) vai para o arquivo principal, o comando de início e as variáveis. 3. **Porta.** Se o Nginx encaminhava para a porta 3000, o código agora deve escutar em `0.0.0.0`, na porta da variável `PORT` (80). O painel já reescreve as portas mais comuns no deploy, mas o certo é ler a variável. 4. **Variáveis.** Leve o `.env` no .zip do primeiro deploy (ele é importado) ou cadastre em **Variáveis de Ambiente**. 5. **Arquivos gravados.** Uploads, bancos SQLite e sessões (como a pasta de autenticação de um bot de WhatsApp) podem ir no primeiro .zip. Depois disso, deixe-os fora dos pacotes de atualização com o `.rtcloudignore`, para não sobrescrever os dados novos. 6. **Banco.** Exporte e importe no banco gerenciado (`pg_dump`, `mysqldump`, `mongodump`) e troque a string de conexão. 7. **DNS.** Um dia antes, baixe o TTL do registro para alguns minutos. Com tudo testado em `seu-nome.rtsystems.app`, ligue o domínio em **Domínios** e crie o registro que o painel mostrar. > **Desligue o antigo só depois** — Mantenha a hospedagem antiga no ar até o DNS propagar e a RTCloud estar respondendo. Bots são exceção: o mesmo token rodando em dois lugares responde em dobro — desligue o antigo assim que o novo conectar. ## A aplicação não inicia Fonte: https://docs.rtcloud.com.br/aplicacao-nao-inicia EADDRINUSE, Cannot find module, arquivo principal inválido, falta de memória, binários nativos e aplicação suspensa: a causa e a correção de cada um. Quase sempre o próprio log diz o motivo. Abra a aba **Logs** e leia as últimas linhas antes da parada — o erro está ali. Se a aplicação caiu por um erro conhecido, a **Visão geral** já mostra o cartão “Encontramos o motivo da queda” com a correção pronta. ### O código de saída | Código | O que quer dizer | | --- | --- | | 0 | O programa terminou sozinho. Num bot, normalmente o processo não ficou esperando eventos, ou o login falhou sem lançar erro. | | 1 | Erro não tratado no código. A mensagem está logo acima, no log. | | 127 | Comando não encontrado: comando de início errado ou dependência que não instalou. | | 137 | Parada forçada. Se não foi você quem desligou, é falta de memória. | | 139 | Falha num módulo nativo. Tente a versão Estável da linguagem e reinstale as dependências. | | 143 | Desligamento pedido — botão Parar, reinício ou novo commit. É normal. | ### EADDRINUSE: porta já em uso O código tentou abrir a mesma porta duas vezes: dois servidores no mesmo processo, ou um `listen` dentro de algo que roda mais de uma vez (um evento, uma reconexão). Deixe **um** servidor, **uma** chamada de `listen`, no nível de cima do arquivo de início: ```javascript // certo: um listen só, quando o arquivo carrega app.listen(process.env.PORT || 80, "0.0.0.0", () => console.log("No ar")); ``` ### Cannot find module / ModuleNotFoundError Uma biblioteca usada no código não está no arquivo de dependências, então nunca foi instalada aqui — mesmo funcionando na sua máquina. Acrescente-a ao `package.json`, `requirements.txt` ou `pyproject.toml` e publique de novo. Se o módulo que falta é um arquivo do próprio projeto (`./utils`), confira se ele foi no .zip e se o nome bate, inclusive maiúsculas: o Linux diferencia `Utils.js` de `utils.js`. ### Arquivo principal inválido ou não encontrado O arquivo escolhido como principal não existe nesse caminho. Se ele está numa pasta, informe o caminho completo (`src/index.js`). Confira na aba **Geral** e no **Explorador de arquivos** — um .zip que levou a pasta de fora junto (`meu-projeto/src/index.js`) é a causa mais comum. ### Dependência inválida O deploy falha quando o arquivo de dependências pede um pacote que não existe ou uma versão que nunca foi publicada — quase sempre um erro de digitação. Corrija o nome ou a versão e publique de novo. ### Falta de memória O processo passou da memória reservada e foi encerrado (código 137, ou “JavaScript heap out of memory”). Três caminhos: - Procure o vazamento: um `Map`, lista ou cache que só cresce; arquivo grande lido inteiro; navegador sem tela aberto e nunca fechado. - Leve o cache para um Redis gerenciado em vez de guardar tudo no processo. - Aumente a memória da aplicação na aba **Geral**, se o plano tiver folga. ### Erro de binário nativo (better-sqlite3, bcrypt, sharp) Mensagens como `Could not locate the bindings file`, `invalid ELF header` ou `NODE_MODULE_VERSION` dizem que o módulo nativo foi compilado para outro sistema ou outra versão do Node. Atualize a biblioteca (o `better-sqlite3` precisa ser 12.5.0 ou mais novo; o `quick.db`, 9.1.7 ou mais novo), apague a pasta `node_modules` pelo **Explorador de arquivos** e reinicie — as dependências são reinstaladas e recompiladas aqui. Fixar a versão Estável do Node evita que isso volte. ### Aplicação temporariamente suspensa A plataforma suspende uma aplicação que ameaça a estabilidade do servidor: consumo de memória ou CPU fora do normal por muito tempo, ou um volume de requisições anormal — quase sempre um laço infinito, chamadas sem cache a uma API (Discord, Telegram) ou um site sendo atacado. Confira o e-mail da conta, que explica o motivo, corrija a causa e fale com o suporte para liberar. ### Sem espaço em disco Logs gravados em arquivo, cache e backups antigos lotaram o disco da aplicação. Apague o que for descartável pelo **Explorador de arquivos** e mande o log para o console em vez de arquivo. ## Erros de bot do Discord Fonte: https://docs.rtcloud.com.br/erros-bot-discord Token inválido, intents não permitidas, bot online que não responde, resposta em dobro, Lavalink 1006 e bot que cai depois de funcionar no computador. ### “An invalid token was provided” / LoginFailure O Discord recusou o token. As causas: o token foi trocado no Developer Portal (gerar um novo invalida o antigo na hora), sobrou espaço ou aspas ao colar, ou o código lê a variável com outro nome. 1. No Developer Portal, abra a aplicação → **Bot** → **Reset Token** e copie o novo. 2. Na RTCloud, atualize a variável (`DISCORD_TOKEN`) em **Variáveis de Ambiente** — sem aspas e sem espaços. 3. Confira se o nome da variável no código é exatamente o mesmo. 4. Reinicie a aplicação. ### “Used disallowed intents” O código pede uma intent privilegiada (Message Content, Server Members, Presence) que não está ligada no portal. Ligue-a em **Bot → Privileged Gateway Intents** e reinicie. Bots em mais de 100 servidores precisam de aprovação do Discord para essas intents. ### O bot fica online mas não responde Quase sempre é a **Message Content Intent**: sem ela, o bot recebe as mensagens com o conteúdo vazio e nenhum comando de prefixo funciona. Ela precisa estar ligada nos dois lugares — no portal e no código: ```javascript // discord.js intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] # discord.py intents = discord.Intents.default() intents.message_content = True ``` Se a intent está certa, confira as permissões do bot no canal (ver canal, enviar mensagens) e se os comandos de barra foram registrados. ### O bot responde duas vezes Há duas cópias do bot conectadas com o mesmo token — normalmente a do seu computador e a da RTCloud, ou duas aplicações publicadas com o mesmo código. Desligue a que sobra. ### Lavalink: conexão fechada com código 1006 É versão trocada: um cliente feito para o Lavalink 3 falando com um servidor 4, ou o contrário. Use a mesma versão principal nos dois lados e reinicie as duas aplicações. Com o Lavalink na RTCloud, o bot conecta pela porta 443 com `secure: true` — veja o guia do Lavalink. ### Funciona no computador e cai na RTCloud - **Leia o log primeiro.** A última linha antes da queda diz o motivo. - **Erro passageiro derrubando o processo:** trate os erros para uma falha de rede não matar o bot — `client.on("error", …)` e `process.on("unhandledRejection", …)` no discord.js. - **Versões diferentes:** o que você testou não é o que está no arquivo de dependências. Fixe as versões. - **Limite da API (erro 429):** o bot faz requisições demais — editar mensagem em laço, criar canais em sequência. Guarde em cache o que dá, espere o tempo que o Discord indica e use webhooks para envios em massa. Abuso repetido pode suspender a aplicação. ## Erros de conexão com o banco Fonte: https://docs.rtcloud.com.br/erros-conexao-banco “Host is not allowed to connect”, erros de SSL, MongoDB Atlas que recusa a conexão, timeout, ECONNREFUSED e senha com caracteres especiais. Quase toda falha de conexão com banco cai em três causas: o certificado não foi carregado, uma lista de IPs liberados no banco externo, ou credencial errada. ### “Host '…' is not allowed to connect to this MySQL server” Apesar da mensagem, não é bloqueio de endereço: os bancos gerenciados da RTCloud **exigem conexão com certificado**, e o MySQL responde assim quando ela vem sem. Baixe o `.pem` na tela do banco (**Baixar certificado**) e carregue no seu cliente — o guia “Conectar ao banco de dados” mostra como em cada linguagem. Em programas como DBeaver, MySQL Workbench e HeidiSQL, aponte os campos da aba SSL para o mesmo arquivo. ### Erros de SSL/TLS - **Redis:** o endereço começa com `rediss://` — com dois “s”. Com `redis://` a conexão é recusada. - **Prisma:** ele não lê `.pem`; converta para `.p12` com `openssl pkcs12 -export -in certificado.pem -out cliente.p12` e use `sslidentity` e `sslpassword` na URL. - **Java (JDBC):** a chave precisa estar no formato PKCS#8 (`.pk8`). - **“private key file has group or world access”** (Python e `psql`): o arquivo da chave precisa de permissão restrita. Rode `os.chmod("certificado.pem", 0o600)` no início do código. - **Certificado renovado:** depois de **Renovar certificado** na tela do banco, o arquivo antigo para de valer. Baixe o novo e envie para as aplicações. ### MongoDB Atlas recusa a conexão (MongoNetworkError) O Atlas só aceita os IPs da sua lista de acesso, e o endereço de saída de uma aplicação muda quando ela reinicia. A lista com um IP fixo funciona até o próximo reinício e depois quebra sem aviso. Duas saídas: - **Liberar qualquer IP** em **Network Access** (`0.0.0.0/0`) e compensar com credenciais fortes: usuário exclusivo da aplicação, senha longa e aleatória, string de conexão só em variável de ambiente. - **Trazer o banco para a RTCloud** (MongoDB gerenciado, a partir do Carbon): sem lista de IPs, e com o banco perto da aplicação. ### Timeout ou ECONNREFUSED | Sintoma | Causa provável | | --- | --- | | A conexão fica parada até dar timeout | Um firewall ou lista de IPs no banco de destino está descartando a conexão. Comum em bancos externos que bloqueiam IPs de datacenter. | | ECONNREFUSED na hora | O endereço responde, mas a porta está errada ou o serviço não está escutando. | | “authentication failed” | Usuário, senha ou nome do banco errado — ou a senha foi trocada em **Gerar nova senha** e a variável ficou com a antiga. | ### Senha com caracteres especiais Dentro de uma URL de conexão, `@`, `:`, `/`, `#` e `%` na senha quebram a leitura do endereço. Codifique esses caracteres (`@` vira `%40`, `:` vira `%3A`, `/` vira `%2F`) ou gere uma senha só com letras e números. ## Conectar ao banco de dados (em cada linguagem) Fonte: https://docs.rtcloud.com.br/conectar-banco PostgreSQL, MySQL, MongoDB e Redis gerenciados: a conexão com certificado em Node.js, Python, Prisma e Java, com código pronto. Os bancos gerenciados da RTCloud só aceitam conexão cifrada, com o certificado da sua aplicação. A receita é sempre a mesma: a string de conexão numa variável de ambiente e o `.pem` baixado na tela do banco junto com o projeto. 1. No menu **Banco de dados**, crie o banco (motor, nome e memória) e copie a string de conexão — a senha aparece uma única vez. 2. Clique em **Baixar certificado (.pem)**. Neste guia o arquivo aparece como `certificado.pem`; renomeie o seu ou ajuste o nome no código. 3. Na aplicação, crie a variável `DATABASE_URL` em **Variáveis de Ambiente** com a string de conexão. 4. Envie o `certificado.pem` junto com o projeto (no .zip, ou como arquivo solto pela aba **Commit**) e reinicie. > **O certificado é uma credencial** — Ele carrega a chave que identifica a sua aplicação no banco. Pode ir no .zip de deploy, mas nunca num repositório público — com o deploy pelo GitHub, use um repositório privado. ### PostgreSQL ```javascript // Node.js — npm install pg const fs = require("fs"); const { Client } = require("pg"); const pem = fs.readFileSync("certificado.pem", "utf8"); const client = new Client({ connectionString: process.env.DATABASE_URL, // confere o certificado do banco; o nome do servidor não é comparado ssl: { ca: pem, cert: pem, key: pem, checkServerIdentity: () => undefined }, }); async function main() { await client.connect(); console.log((await client.query("SELECT 1 AS ok")).rows[0]); } main(); ``` ```python # Python — requirements.txt com psycopg2-binary import os import psycopg2 os.chmod("certificado.pem", 0o600) # o libpq exige a chave com permissão restrita conn = psycopg2.connect( os.environ["DATABASE_URL"], sslmode="verify-ca", sslrootcert="certificado.pem", sslcert="certificado.pem", sslkey="certificado.pem", ) with conn.cursor() as cur: cur.execute("SELECT 1") print(cur.fetchone(), flush=True) ``` Com **Drizzle**, use o mesmo `Pool` do `pg` com o objeto `ssl` acima, também no `drizzle.config.ts`. Por que o nome do servidor não é comparado: o endereço do banco é da RTCloud, e o certificado foi emitido para o servidor interno. A conexão continua cifrada e o certificado do banco continua sendo conferido (o mesmo que `sslmode=verify-ca`). Com a comparação de nome ligada, o driver recusa com “Hostname/IP does not match certificate's altnames”. ### MySQL ```javascript // Node.js — npm install mysql2 const fs = require("fs"); const mysql = require("mysql2/promise"); const pem = fs.readFileSync("certificado.pem", "utf8"); const pool = mysql.createPool({ uri: process.env.DATABASE_URL, ssl: { ca: pem, cert: pem, key: pem }, }); pool.query("SELECT 1").then(([linhas]) => console.log(linhas)); ``` ```python # Python — requirements.txt com PyMySQL import os import pymysql conn = pymysql.connect( host=os.environ["DB_HOST"], port=int(os.environ["DB_PORT"]), user=os.environ["DB_USER"], password=os.environ["DB_PASSWORD"], database=os.environ["DB_NAME"], ssl={"ca": "certificado.pem", "cert": "certificado.pem", "key": "certificado.pem", "check_hostname": False}, ) ``` ### MongoDB ```javascript // Node.js — npm install mongodb (no Mongoose, as mesmas opções no connect) const { MongoClient } = require("mongodb"); const client = new MongoClient(process.env.DATABASE_URL, { tls: true, tlsCAFile: "certificado.pem", tlsCertificateKeyFile: "certificado.pem", tlsAllowInvalidHostnames: true, }); client.connect().then(() => console.log("MongoDB conectado")); ``` ```python # Python — requirements.txt com pymongo import os from pymongo import MongoClient client = MongoClient( os.environ["DATABASE_URL"], tls=True, tlsCAFile="certificado.pem", tlsCertificateKeyFile="certificado.pem", tlsAllowInvalidHostnames=True, ) ``` ### Redis O endereço do Redis começa com `rediss://` (dois “s”), no formato `rediss://default:SENHA@ENDERECO:PORTA`. ```javascript // Node.js — npm install redis const fs = require("fs"); const { createClient } = require("redis"); const pem = fs.readFileSync("certificado.pem", "utf8"); const redis = createClient({ url: process.env.REDIS_URL, socket: { tls: true, ca: pem, cert: pem, key: pem, checkServerIdentity: () => undefined }, }); redis.on("error", console.error); redis.connect().then(() => console.log("Redis conectado")); ``` ```python # Python — requirements.txt com redis import os import redis r = redis.from_url( os.environ["REDIS_URL"], ssl_ca_certs="certificado.pem", ssl_certfile="certificado.pem", ssl_keyfile="certificado.pem", ssl_check_hostname=False, ) print(r.ping(), flush=True) ``` ### Prisma O Prisma não lê o `.pem`: converta para `.p12` na sua máquina e envie o `cliente.p12` com o projeto. ```bash openssl pkcs12 -export -in certificado.pem -out cliente.p12 -passout pass:SENHA_DO_P12 # DATABASE_URL (PostgreSQL) postgresql://USUARIO:SENHA@ENDERECO:PORTA/BANCO?sslmode=require&sslidentity=cliente.p12&sslpassword=SENHA_DO_P12 # DATABASE_URL (MySQL) mysql://USUARIO:SENHA@ENDERECO:PORTA/BANCO?sslidentity=cliente.p12&sslpassword=SENHA_DO_P12 ``` O caminho do `sslidentity` é relativo à pasta do `schema.prisma`. Se o schema fica em `prisma/`, coloque o `.p12` lá dentro. ### Java (JDBC) O driver JDBC do PostgreSQL pede a chave no formato PKCS#8. Converta e passe os arquivos na URL: ```bash openssl pkcs8 -topk8 -inform PEM -outform DER -in certificado.pem -out cliente.pk8 -nocrypt jdbc:postgresql://ENDERECO:PORTA/BANCO?sslmode=verify-ca&sslrootcert=certificado.pem&sslcert=certificado.pem&sslkey=cliente.pk8 ``` > **Não conectou?** — O guia “Erros de conexão com o banco” traz as mensagens mais comuns — “Host is not allowed”, SSL, timeout — e a correção de cada uma. ## Novidades ### 5.2 — Analytics de verdade, Network completa e balanceamento pelo painel (2026-11-06) Agora você vê quem acessa o seu site, de onde e o que deu erro, com filtro em tudo. A Network mostra o estado real do DNS, o balanceamento liga com um toque e os gráficos da Visão geral nunca mais abrem parados. - Analytics novo: requisições, visitas, banda, países no mapa, rotas, navegadores, códigos de status, bots e IPs, com filtro por qualquer linha e comparação com o período anterior. - Balanceamento pelo painel: adicione ou tire aplicações do domínio com um toque, veja quem está recebendo tráfego e acompanhe uma simulação de como tudo funciona. - Network refeita: endereços, domínio próprio, registros de DNS com o estado de cada um, o motivo do que está pendente e delegação do certificado. - Visão geral da aplicação redesenhada: estado, consumo ao vivo, ações e atalhos num lugar só. - Assistentes de IA agora se chama Ferramentas MCP. A ReactorAI ganhou o selo de Assistente: é o suporte do painel com inteligência artificial. - Os gráficos da Visão geral não abrem mais caídos: as medições agora rodam o tempo todo, com ou sem o painel aberto. - Limpar cache agora limpa o cache de verdade, na hora e sem reiniciar a aplicação. ### 5.1.1 — Ferramentas MCP: aba própria e tutorial para cada uma (2026-11-04) Agora as ferramentas de IA têm lugar próprio em Recursos Avançados, com um passo a passo ilustrado para cada conexão. - Nova aba Ferramentas MCP em Recursos Avançados, com as conexões e as chaves num lugar só. - Tutorial com imagens para Claude Code, Grok, Codex, Claude, ChatGPT, VS Code, Cursor, Google Antigravity, Devin Desktop e outros. - Cada passo mostra onde fazer, o comando pronto para copiar e a tela que vai aparecer. - Mais segurança ao autorizar: só as permissões de leitura vêm marcadas, e liberar alterações é escolha sua. - A mesma ferramenta agora pode ficar conectada em dois computadores ao mesmo tempo. - Claude Code, VS Code e outros programas do computador agora conectam sem o erro de endereço de retorno. ### 5.1 — Conecte a sua ferramenta de IA à RTCloud (2026-11-04) Agora Claude, Grok, ChatGPT, Cursor e outras ferramentas cuidam da sua hospedagem: leem logs, corrigem arquivos e reiniciam a aplicação, só com o que você autorizar. - Servidor MCP: conecte Claude Code, Grok, Codex, Claude, ChatGPT, VS Code e Cursor à sua conta e peça em linguagem normal. - Claude, ChatGPT e Claude Code conectam com um clique. Você escolhe o que cada ferramenta pode fazer. - Chaves MCP com permissões por tipo de ação, e que podem valer só para as aplicações que você marcar. - Nova página Ferramentas, com o passo a passo de cada ferramenta e um AGENTS.md para o seu projeto. - Nova página de Suporte, com todos os canais de atendimento num lugar só. - Modo privacidade em Meu perfil: esconda nomes e e-mails do painel para gravar ou compartilhar a tela. - A Atividade agora mostra o que foi feito por ferramentas de IA e qual chave fez cada ação. - Domínios: quando um registro DNS não vale, o painel diz o motivo em português. - As conversas com a ReactorAI agora ficam guardadas com criptografia. - Variável de ambiente removida agora sai de verdade da aplicação, e valores com espaço não aparecem mais entre aspas. ### 5.0 — A RTCloud agora é aplicativo (2026-11-02) Chegou o app da RTCloud para Android, iPhone, iPad e computador: o painel em tela cheia, sem barra de endereço, com a página de status e a documentação dentro do app. - App para Android: baixe o app assinado pela RTCloud e instale em segundos. - iPhone e iPad: no Safari, toque em Compartilhar → Adicionar à Tela de Início. A RTCloud abre em tela cheia, com ícone e tela de abertura próprios. - App para Windows com instalador próprio, que não pede administrador. No Mac e no Linux, instale pelo Chrome, pelo Edge ou pelo Safari. - Dentro do app, a página de status e a documentação abrem no próprio app — sem ir para o navegador. - Sem internet? O app mostra uma tela própria e volta sozinho quando a conexão voltar. - No app de Windows, o login com Google é feito no seu navegador e volta sozinho para o app. - O app se atualiza sozinho: cada novidade do painel chega nele sem baixar nada de novo. ### 4.9.15 — Backups, snapshots e bancos de dados: correções (2026-11-01) Corrigimos o download de backups e snapshots, a restauração e a conexão dos bancos de dados gerenciados — e cada banco ganhou exemplos prontos de conexão. - Baixar backup e snapshots: o download começa na hora, com o tamanho e o progresso certos — inclusive em aplicações grandes. - Quando o backup novo ainda está sendo gerado, o painel avisa e entrega o mais recente pronto, com a data. - Restaurar snapshots de aplicações e backups de bancos de dados voltou a funcionar direto, sem erro de “snapshot inválido”. - Escolher uma versão do backup do banco e baixar depois não dá mais “backup indisponível”. - Bancos de dados: o endereço de conexão sai no padrão da RTCloud, e o painel mostra quando ele já está ativo. - Redis: a URL de conexão agora vem com TLS (rediss://). - Nova seção “Como conectar” em cada banco, com exemplos prontos para Node.js, Python e terminal. - Mensagens de erro do backup mais claras, dizendo o que aconteceu. ### 4.9.14 — Gráficos da Visão geral mais bonitos e fiéis (2026-10-29) Os gráficos da Visão geral ganharam curvas suaves, escala com números redondos e horários cheios no eixo — e pararam de mostrar o zigue-zague que aparecia em recursos medidos a cada 10 minutos. Os números continuam os mesmos, medidos de verdade. - Memória sem o zigue-zague falso: recursos medidos a cada 10 minutos aparecem contínuos no gráfico. - A CPU de recursos medidos a cada 10 minutos volta a aparecer no gráfico. - A rede mostra a taxa real — antes alguns intervalos apareciam com o dobro do valor e o seguinte vazio. - Curvas suaves que passam exatamente por cada leitura, sem inventar pico nem vale. - Escala com números redondos (0, 1, 2 GB…) e horários cheios no eixo, com o dia na virada da meia-noite. - Grade mais limpa e degradê nas áreas de rede e tráfego. ### 4.9.13 — Visão geral inteira desde a entrada, sem piscar (2026-10-29) A Visão geral agora abre inteira de uma vez: nome, botões, mapa, avisos e gráficos já no lugar, sem nada aparecendo depois nem piscando ao rolar — no computador, no Android e no iPhone. Os efeitos continuam ligados. - Gráficos, números, avisos e o sino da Visão geral já chegam com a página — nada entra depois empurrando a tela. - No celular, os cards não somem nem piscam mais ao rolar: o mapa da rede ficou bem mais leve de desenhar. - A saudação (Bom dia, Boa tarde, Boa noite) não troca mais sozinha ao abrir o painel. - No modo claro, o nome na saudação fica sempre legível enquanto o brilho passa. - Na entrada, os botões respondem na hora: o mapa e os gráficos terminam de ligar em segundo plano. - Os gráficos já abrem na largura certa da tela, sem se redesenhar. - Ao abrir o painel, a tela aparece já no lugar — o deslizar fica para quando você troca de tela. - Os horários dos gráficos seguem o horário de Brasília, como o resto do painel. ### 4.9.12 — Visão geral no celular: nome e mapa sempre firmes (2026-10-28) Ajustamos a primeira entrada no painel pelo celular: o nome não pisca mais e o mapa da rede roda desde o primeiro segundo, sem esperar um toque. Todos os efeitos ficam ligados o tempo todo, lisos. - O nome na saudação não pisca mais nem aparece esticado ao abrir o painel no celular. - O mapa da rede roda sempre, desde a entrada — não fica mais parado até tocar na tela ou rolar. - O convite das redes espera o “Bem-vindo de volta” terminar antes de aparecer. ### 4.9.11 — RT Cloud no Instagram e no TikTok, e uma Visão geral bem mais leve (2026-10-28) Agora dá para acompanhar a RT Cloud no Instagram e no TikTok, os dois em @rtcloud.br. E a Visão geral ficou bem mais leve: o mapa e o brilho continuam iguais, mas não pesam mais — rolagem lisa e menu abrindo na hora, até no celular. - Instagram e TikTok oficiais da RT Cloud, os dois em @rtcloud.br: dicas de deploy, novidades do painel e promoções saem primeiro por lá. - Os botões das redes ficam no menu do painel, em “Siga a RT Cloud”, e no rodapé do site. - Visão geral muito mais leve: o mapa da rede e o brilho do seu nome agora andam pela placa de vídeo — o mesmo visual, sem travar a rolagem nem o menu ☰. - Os gráficos só se redesenham quando os números mudam. - A Visão geral não fica mais lenta na primeira entrada — antes, só atualizando a página voltava ao normal. ### 4.9.8 — Visão geral com gráficos em tempo real e deploy que mostra o erro (2026-10-26) A Visão geral ganhou gráficos de memória, CPU e rede de todas as suas aplicações e bancos. O deploy acompanha a aplicação até ela ficar no ar e, se falhar, diz o motivo. E o teste grátis agora avisa por e-mail quando termina. - Gráficos da conta inteira na Visão geral: memória, CPU e rede de cada aplicação e banco, em 1 h, 6 h, 12 h ou 24 h, com as marcações de deploy, reinício e queda. - Tabela de recursos com busca, filtro e ordenação: RAM agora, CPU, pico de memória, rede e reinícios de cada um. - Tráfego HTTP dos seus sites na Visão geral: requisições, visitas, dados transferidos e erros 5xx (a partir do plano Carbon). - O card da Rede global subiu para o topo da Visão geral, logo abaixo da saudação. - O deploy acompanha a aplicação até ela ficar no ar. Se falhar, o log termina com o motivo em português: variável de ambiente faltando, pacote ou versão que não existe, token vazio, banco apontando para localhost e outros. - Teste grátis: quando as 24 horas acabam, a aplicação pausa e você recebe um e-mail com o prazo. Assinando um plano até lá, ela volta a ligar sozinha, sem novo deploy; sem plano, é removida 24 horas depois. - Nome de aplicação com acento ou emoji não trava mais o deploy. ### 4.9.7 — Dependências instaladas certinho e métricas de 7 dias (2026-10-26) O deploy agora corrige sozinho os problemas mais comuns do requirements.txt e do package.json, a escolha da versão da linguagem ficou mais simples e as métricas guardam até 7 dias. - Import de arquivo do próprio projeto (como “import config” ou “from cogs import”) não vira mais biblioteca no requirements.txt ou no package.json — era o motivo mais comum de a instalação parar. - Arquivo de dependências salvo em UTF-16 ou com BOM, com nome errado (Requirements.txt, requirements.txt.txt) ou fora da raiz é corrigido no deploy. - Versões antigas fixadas por um pip freeze de outro Python sobem para a mais nova da mesma série, com aviso no log. Bot com py-cord não recebe mais o discord.py junto. - Versão da linguagem: Automático (o padrão), Estável ou Mais recente. Aplicações com uma versão antiga guardada passam para a Estável sozinhas. - Métricas de 7 dias (média e pico de cada hora) para aplicações de 512 MB ou mais e para bancos de dados. Toda aplicação tem o histórico das últimas 24 horas. - Página de status verificada também de fora, a cada minuto. ### 4.9.6 — Página de status mais precisa (2026-10-22) Quando publicamos uma atualização do site, você vê uma tela de aviso que volta sozinha — e a atualização não conta mais como queda no status. - Durante uma atualização, o site mostra “Publicando uma atualização” e recarrega sozinho em alguns segundos. - Atualizações do site não entram mais como queda no status. Queda de verdade continua sendo registrada e avisada, como sempre. - “Tudo operacional há” conta desde o último incidente e não zera mais a cada atualização. - Cartão do topo do status mais compacto: a situação em uma linha e disponibilidade, tempo de resposta e tempo operacional lado a lado. - Atualizações de 19 a 22/10 que apareciam como quedas curtas saíram do histórico. ### 4.9.4 — Aviso de novo login e ajustes no celular (2026-10-21) Toda vez que alguém entra na sua conta, você recebe um e-mail com quando, de qual aparelho e de qual IP. E o site ficou mais confortável no celular e no modo claro. - E-mail “Novo login na sua conta” com data, aparelho e IP, e um botão para revisar as sessões abertas. O mesmo aparelho avisa no máximo uma vez a cada 12 horas. - No celular, os menus de tema e idioma abrem sempre inteiros na tela, e o “Criar conta” não quebra mais a linha. - Explorador de arquivos e logs legíveis no modo claro, com as cores do código no estilo do VS Code. ### 4.9.3 — Modo claro no site e no painel (2026-10-21) Agora dá para escolher o tema: Escuro (o padrão), Claro ou Sistema, que segue o tema do seu aparelho. O botão fica ao lado do sino, sempre à mão. - Modo claro em todas as páginas: site, documentação, status, login e o painel inteiro. - Botão de tema (sol e lua) ao lado do sino, com Sistema, Claro e Escuro. - No modo Sistema, o site muda sozinho junto com o tema do aparelho. - Visão geral do Meu perfil mais limpa: sem informações repetidas, e as abas ficam só no submenu. ### 4.9.2 — Meu perfil completo: segurança, conexões, atividade e uso (2026-10-21) O Meu perfil ganhou abas novas: veja onde a sua conta está aberta, encerre sessões, gerencie as conexões, filtre a atividade por origem e acompanhe o uso do plano. - Segurança: chaves de API, sessões abertas com aparelho e IP, e um botão para desconectar todas as sessões. - Conexões: conecte ou desconecte Google, GitHub e Discord numa tela só. - Atividade: filtre o que foi feito por você, pelas chaves de API, pelo bot do Discord ou pela ReactorAI. - Uso: a memória do plano dividida entre aplicações e bancos de dados, o Blob e os tokens da ReactorAI dos últimos 7 dias. - Meu perfil abre um submenu no menu da conta, com todas as abas à mão. - Guia novo na documentação: como migrar do Render para a RTCloud. ### 4.9.1 — Teste grátis de 24 horas (2026-10-20) O teste grátis agora dura 24 horas: um bot com até 512 MB no ar por um dia inteiro, sem cartão e sem Pix, uma vez por conta. - Teste grátis de 24 horas: um bot com até 512 MB, sem cartão e sem Pix — tempo de sobra para testar com calma, de dia e de noite. - As 24 horas contam a partir do primeiro deploy grátis: se você apagar o bot de teste para subir o arquivo certo, o prazo continua o mesmo. - O tempo que falta do teste aparece em horas no painel e no Discord. - No teste grátis, a memória do bot vai até 512 MB também nas configurações da aplicação, igual ao deploy. ### 4.9 — Status com endereço próprio, página de planos e o selo Hospedado na RTCloud (2026-10-20) A página de status ganhou o endereço status.rtcloud.com.br e continua no ar mesmo se o site parar. Planos, recursos e hardware viraram páginas próprias, e chegou o selo para o rodapé do seu site. - Página de status em status.rtcloud.com.br: se o site principal parar de responder, ela continua no ar mostrando a última situação registrada. - Planos e preços com página própria: a tabela, os períodos com desconto e as regras de cobrança num lugar só. - Selo Hospedado na RTCloud para o rodapé do site e o README do projeto, em versão escura, clara e compacta — também na aba Monitor de cada aplicação. - Recursos e hardware também ganharam páginas próprias, com links para os guias da documentação. - Bancos de dados novos nascem sempre na versão mais recente de cada motor: MongoDB 8, PostgreSQL 17, MySQL 9 e Redis 8. ### 4.8 — Planos de 3 meses, 6 meses e 1 ano com desconto (2026-10-20) Agora dá para pagar por período no Pix Automático: 5% de desconto em 3 meses, 10% em 6 meses e 2 meses grátis no anual — com a renovação sozinha no mesmo período. - Escolha o período ao assinar: mensal, 3 meses (-5%), 6 meses (-10%) ou 1 ano (2 meses grátis). O valor total, quanto sai por mês e quanto você economiza aparecem antes do Pix. - Tela de pagamento nova, em etapas: configurar o plano, pagar pelo Pix Automático e pronto. Os dados de cobrança podem ser salvos para pagar depois — e editados sem redigitar o CPF. - Trocar de período no mesmo plano (por exemplo, do mensal para o anual) soma os meses no fim do que já está pago e encerra a renovação antiga — sem cobrança em dobro. - Recibos de troca de plano mostram o crédito do plano anterior como dias a mais (é o que acontece de verdade), e não mais como desconto em reais. ### 4.7.3 — Página de status com mapa da plataforma e serviços de terceiros (2026-10-20) A página de status ganhou um mapa ao vivo da RTCloud, acompanha Cloudflare, GitHub, Discord e Google, e não acusa mais a hospedagem por problema de empresa de fora. - Mapa da plataforma: a RTCloud no centro, cada serviço em volta e os terceiros por fora, com a cor da situação de cada um — e a lista do que está fora do normal agora. - Serviços de terceiros: Cloudflare, GitHub, Discord e Google lidos direto das páginas oficiais, contando só a parte que a RTCloud usa e mostrando o que cada problema muda por aqui. - Armazenamento de arquivos e ReactorAI ganharam a própria linha na página de status, com o histórico de 90 dias. - A hospedagem não aparece mais com "desempenho reduzido" por causa de empresa de fora: em 20/10 um incidente da Cloudflare em produtos que a RTCloud não usa acendeu esse aviso com tudo no ar. O registro daquele dia foi corrigido. - Atualização do próprio site da RTCloud não conta mais como queda na página de status. ### 4.7.2 — Menu ⋯ nos cartões e tempo no ar de verdade (2026-10-20) Cada aplicação ganhou um menu com tudo à mão, e o cartão mostra há quanto tempo ela está ligada — não quando foi criada. - Menu ⋯ no cartão de cada aplicação: ligar, reiniciar e parar, favoritar, atalhos para console, arquivos, monitor e configurações, abrir o site, copiar o ID e excluir. - Favoritas: marque com a estrela e elas aparecem primeiro na lista. Na equipe, cada pessoa tem as suas. - O cartão mostrava "há 13 dias" — a data de criação — e parecia tempo ligado. Agora mostra "no ar há" com o tempo real que a aplicação está ligada; a data de criação aparece ao passar o mouse. - Subir de plano: os dias que sobram do plano atual viram dias a mais arredondados para o dia mais próximo (antes, sempre para baixo). ### 4.7.1 — Monitor com o tempo real e troca de plano mais clara (2026-10-19) O "no ar há" volta a contar o tempo que a aplicação está ligada, e a troca de plano mostra o vizinho certo e o valor exato do Pix. - "No ar há" do monitor: conta o tempo que a aplicação está ligada, o mesmo do topo da tela. Só uma queda confirmada recomeça a conta — uma falha isolada não zera mais. - As falhas registradas por engano em 19/10, entre 16h e 16h25, foram apagadas do monitor e da página de status: a % no ar volta ao que era. - "Mudar para um plano menor" e "Evoluir" mostram o vizinho de verdade entre os 9 planos da tabela — abaixo do Apex é o Titan. - Subir de plano mostra o valor exato do Pix: a mensalidade do plano novo, com os dias que sobravam do atual virando dias a mais. ### 4.7 — Monitor de bots, Obsidian por Pix e mudar de plano na hora (2026-10-19) Saiba na hora quando o seu bot travar, monte o Obsidian deslizando a memória e suba ou desça de plano quando quiser. - Monitor de bots: o seu bot manda um sinal de vida para a RTCloud e, se ele travar, desconectar do Discord ou cair, você é avisado no Discord, no sino e por e-mail — com código pronto para discord.js e discord.py. - Obsidian de 48 GB a 768 GB: escolha a memória deslizando e assine por Pix, como qualquer plano. - Mudar de plano na hora: suba ou desça quando quiser. Ao descer, o vencimento é mantido e, se as aplicações não couberem, você escolhe quais continuam ligadas. - Faturamento novo: seu plano, a renovação automática e as faturas com recibo em PDF, tudo numa tela. - Assistente no site: tire dúvidas sobre planos, preços e Pix na hora, com a recomendação do plano certo para o seu projeto. - Página de status com as dependências da RTCloud: o que continua no ar quando uma parte falha. - Avisos de "fora do ar" enviados por engano em 19/10 corrigidos: a falha foi na verificação da RTCloud, não nos seus sites. Agora o monitor confere a própria rede e repete o teste antes de avisar. - Restaurar um snapshot religa a aplicação uma vez só, sem reinício em dobro. ### 4.6 — Monitor de sites, página de status do seu site e API completa (2026-10-16) A RTCloud abre o seu site como um visitante e avisa no Discord quando ele cair — com página de status para mandar aos seus clientes. - Monitor de sites: a RTCloud testa o seu site de fora, de 1 a 5 minutos conforme o plano, e avisa no Discord, no sino e por e-mail quando ele cair ou voltar — mesmo quando o processo continua ligado. - Página pública de status do seu site, com % no ar, barras de 90 dias, tempo de resposta e selo para o README. - Alerta de erros depois de publicar: se a versão nova fizer os erros 5xx dispararem, você recebe a rota que mais errou e o atalho para voltar um snapshot. - Bancos de dados com a aba Uso: memória e CPU das últimas 24 horas, com o limite desenhado no gráfico. - API da RTCloud: monitor, publicações, snapshots, relatórios do site, limpar cache e controle dos bancos de dados. - Discord: comando /monitor e avisos de site fora do ar no privado. - A página de status ganhou o fundo quadriculado da RTCloud. ### 4.5.1 — Backup com progresso, modais novos e limites justos (2026-10-16) Acompanhe o backup etapa por etapa, com tempo restante e cancelar — e um painel ainda mais caprichado. - Backup completo com acompanhamento: empacotando, preparando e baixando, com tamanho, velocidade, tempo restante e botão para cancelar. - Todos os modais do painel com o novo visual de vidro preto, o mesmo da barra de navegação. - A página de status mostra há quanto tempo está tudo operacional, contando ao vivo. - Setas e atalhos do painel viraram ícones. - Limites justos por conta nas ações pesadas (reiniciar, backup, snapshot, deploy), para a plataforma seguir rápida para todo mundo. - Discord: a vitrine e o /renovar mostram os mesmos 9 planos do site, com os benefícios certos. ### 4.5 — Página de status em tempo real e Pix Automático no Discord (2026-10-16) Acompanhe a RTCloud ao vivo em /status — e assine ou renove pelo Discord com o mesmo valor do site. - Página de status em tempo real: a situação de cada parte da plataforma, disponibilidade de 90 dias, tempo de resposta e histórico de incidentes — atualizada sozinha. - Incidentes e manutenções programadas avisados na página de status, no canal de status do Discord e por feed RSS. - API de status aberta em JSON e selo ao vivo para o README do seu projeto. - Discord: /renovar e a vitrine de planos agora usam o Pix Automático, com o mesmo valor e as mesmas regras do site. - A tela de planos mostra o valor exato do Pix e quantos dias o que sobrou do plano atual vira no plano novo. - O Pix gerado pelo Discord voltou a funcionar e bate com o valor do site. - A vitrine de planos do Discord mostra só os planos à venda, com o preço sempre atualizado. ### 4.4.1 — Snapshots no Discord, níveis e status por incidente (2026-10-15) Volte no tempo sem abrir o site, ganhe cargo conversando e saiba na hora quando algo oscilar. - /snapshots no Discord: veja as versões guardadas da sua aplicação, baixe no privado ou restaure com um clique (sempre com confirmação). - Níveis na comunidade: conversar no servidor rende XP e os níveis 5, 10, 20, 35 e 50 dão cargo. Veja o seu com /nivel e o top com /ranking. - Status por incidente: se algo oscilar, o canal de status avisa na hora e mostra quanto tempo levou para resolver. - O aviso de vencimento do plano no Discord agora traz o botão Renovar agora com Pix: o código chega ali mesmo e o plano ativa sozinho. - O resumo semanal do Discord agora destaca os membros mais ativos da semana. ### 4.4 — Avisos no Discord e bot da RTCloud turbinado (2026-10-15) Sua aplicação com plantão no seu privado — e um Discord bem mais vivo. - Avisos no seu Discord: memória passando de 90%, aplicação que caiu e que voltou ao ar chegam no privado, com botões para reiniciar e ver os logs. - Comando /avisos no bot da RTCloud: escolha o que você recebe e teste a entrega na hora. - /app no Discord mostra CPU e memória em uso agora, além da memória reservada. - Painel sempre sincronizado: aplicação que deixa de existir não fica mais aparecendo como parada. - /backup pelo Discord voltou a funcionar, com link seguro da RTCloud que vence em 15 minutos. - Deploy pelo GitHub direto do Discord e a recompensa por impulsionar o servidor voltaram a funcionar. ### 4.3 — Explorador novo, painel mais rápido e preto de verdade (2026-10-15) Editor de arquivos no estilo dos editores profissionais e um painel bem mais leve. - Explorador de arquivos repaginado: caminho no topo, Novo, Enviar arquivos e atalhos; editor com tela cheia e botão para perguntar à ReactorAI sobre o arquivo aberto. - Fonte do código menor e ajustável (A− / A+) no computador e no celular — no telefone dá para ver quase a linha inteira. - Painel mais rápido e com preto de verdade: menos efeitos pesados, rolagem mais lisa e o globo ajusta a qualidade sozinho em aparelhos mais simples. - Snapshot automático diário ligado por padrão em todas as aplicações (planos a partir do Onyx). Não quer em alguma? Desligue só nela, na aba Snapshots. - Console de logs com as cores que o seu programa imprime e as linhas da saída de erro destacadas, além de CPU e memória ao vivo. - Barra de atalhos do celular mais fina, em vidro escuro. - E-mails da RTCloud com visual novo, em preto e vermelho. - Aviso de boas-vindas ao entrar e Visão geral mais completa no computador. - Criar conta com Google, GitHub ou Discord de uma conta que já existe agora leva para o login, sem criar nada. ### 4.2 — Login novo, recuperar senha e snapshots para baixar (2026-10-15) Entrar ficou mais fácil e seus backups ficaram à mão. - Esqueci minha senha: receba um código por e-mail e crie uma senha nova. - Snapshots com download: a versão mais recente em destaque e o histórico para baixar em .zip. - Telas de entrar e criar conta redesenhadas, com mostrar e esconder senha. - Cartão do seu plano com ativação, vencimento, forma de pagamento e renovação automática. - Página pública de novidades e documentação com atalhos para a API. ### 4.1 — API pública, deploy automático pelo GitHub e menu da conta (2026-10-14) Agora dá para controlar tudo por script e publicar só com git push. - API pública da RTCloud: liste aplicações, veja status e logs, ligue, desligue, reinicie, publique commit e troque variáveis de ambiente por HTTP. - Chaves de API com permissão de acesso total ou somente leitura, revogáveis a qualquer momento. - Deploy automático: ligue na aba Commit da aplicação e cada git push na branch escolhida vira versão nova no ar. - Menu da conta no rodapé da barra lateral: perfil, plano, memória, chaves, documentação e novidades num lugar só. - Bancos de dados mostram quantos você usa do seu plano, e a memória do plano é dividida entre aplicações e bancos. - A ReactorAI ficou mais precisa sobre como publicar: sempre pelo painel, pelo GitHub ou pela API. ### 4.0.2 — ReactorAI nova, explorador de arquivos e backups limpos (2026-09-30) Painel mais estável nos horários de pico e uma assistente repaginada. - ReactorAI com mascote novo, respostas com títulos, listas e blocos de código com botão Copiar, e sugestões em cartões. - Explorador de arquivos com árvore, abas, filtro por nome e ícones das linguagens; no celular, itens em cartões. - Durante instabilidades, as telas mostram as últimas leituras de logs, memória e CPU em vez de ficarem vazias. - No celular, o campo de digitar do chat não some mais atrás do teclado. ### 4.0 — Reforma do painel (2026-09-30) Notificações novas, bancos com endereço próprio e backups pelo painel. - Notificações temporárias para deploy, commit, reinício, backup, snapshot, variáveis e configurações. - Backup de banco de dados baixado direto pelo painel. - Ajuste de memória dos bancos de dados passou a valer na hora.