# Plano Free Source: https://docs.cubehosting.com.br/account/free-plan 100 MB e 1 bot de graça. Em breve, a vaga do Free passa a ser pelo comando /free no Discord da Cube. ## O que o Free inclui | Recurso | Free | | -------------------------------------- | ------------------------------------------- | | Memória | 100 MB | | Processador | 0,25 vCPU | | Projetos | 1 bot | | Tamanho do .zip | Até 5 MB | | Variáveis de ambiente, logs e métricas | Sim | | Cube AI | 8 mensagens por dia, só para ver e explicar | | Sites e APIs | Não | | Reinício automático | Não | | Explorador de arquivos | Não | Hoje, toda conta nova começa no Free. Para sites, reinício automático e o explorador de arquivos, veja os [planos pagos](/account/plans). No Free, se o bot cair, ele fica **Com erro** até você iniciar de novo. Confira os logs para ver o motivo. ## A vaga pelo Discord Em breve Em breve, a vaga do Free vai ser resgatada no [Discord da Cube](https://discord.gg/pv6D9tUsDV), com o comando `/free`. Como vai funcionar (os detalhes podem mudar até o lançamento): Ligue a sua conta do Discord à conta da Cube. No servidor da Cube, use `/free`. Se houver vaga, o Free é liberado na hora. As vagas são limitadas. Para manter a vaga, bata a meta semanal de mensagens num canal do servidor. Quem não bater perde a vaga: o bot para e os arquivos ficam guardados por 30 dias. * Uma vaga por conta do Discord e por conta da Cube. * A conta do Discord precisa ter mais de 30 dias. * O bot da Cube conta só quantas mensagens você mandou por dia. Ele não guarda o texto das mensagens. # Pagamento por Pix Source: https://docs.cubehosting.com.br/account/pix-billing Mês a mês no Pix, sem cartão e sem fidelidade: assinatura, renovação, troca de plano e o que acontece se atrasar. A assinatura dos planos pagos pelo painel abre **em breve**. Enquanto isso, os planos pagos são liberados pelo **beta por convite**: quem recebeu um código resgata em **Minha conta** › **Perfil** › **Resgatar código**. ## Como funciona Em [Plano e cobrança](https://app.cubehosting.com.br/billing), escolha o plano e aceite os Termos de Uso, a Política de Uso Aceitável e a Política de Privacidade. O painel mostra o QR Code e o Pix copia e cola. O Pix vale até o **fim do dia** (horário de Brasília). Assim que o pagamento é confirmado, a conta passa para o plano novo. Ele vale **1 mês** a partir do pagamento. Sem cartão de crédito, sem taxa por cima do preço e sem fidelidade: todo mês chega uma cobrança nova, e você paga se quiser continuar. ## Renovação * A cobrança do mês seguinte sai **3 dias antes do vencimento**, com um e-mail que traz o Pix copia e cola. * O vencimento é o mesmo dia e hora da contratação, todo mês. Pagar a renovação não muda essa data. ## Se o pagamento atrasar Os projetos continuam rodando. O painel mostra um aviso em todas as páginas e você recebe um e-mail no dia 1 e no dia 5, com o Pix. Os projetos param e nada sobe nem instala até pagar. Os arquivos ficam guardados. Parar projetos e ver os arquivos continua liberado. Em **Plano e cobrança**, use **Pagar e reativar**. Pago o Pix, a suspensão sai, o que estava no ar sobe sozinho em até 1 minuto, e a data do ciclo continua a mesma. Projetos parados há 30 dias por falta de pagamento podem ser apagados, e a conta volta ao Free. Antes disso, você recebe um e-mail avisando, **3 dias antes**. Pagou o Pix da renovação depois de os projetos serem apagados? O valor vira **crédito** na conta e paga o próximo plano que ele cobrir, sem Pix. ## Trocar de plano Suba para um plano maior pagando por Pix só a **diferença proporcional** aos dias que faltam no ciclo. O plano novo liga quando o Pix é confirmado, e o vencimento não muda. Desça para um plano menor sem pagar nada agora. A troca fica agendada para o vencimento, e a próxima cobrança já vem com o preço novo. * **Upgrade:** se a diferença der menos de R\$ 1,00 (fim de ciclo), a troca espera o ciclo seguinte. * **Downgrade:** só é aceito se os seus projetos já couberem no plano menor (memória somada, número de projetos e de sites). Se não couberem, o painel mostra quanto sobra, sem apagar nada. Com a renovação atrasada, pague primeiro. * Na virada do ciclo, se o que estiver ligado passar do plano menor, os projetos ligados param. Nada é apagado. ## Beta por convite Um código de convite (`CUBE-XXXX-XXXX-XXXX`) libera um plano pago por um tempo, sem cobrança. Resgate no cadastro ou em **Minha conta** › **Perfil** › **Resgatar código**. * Vale para contas no Free, um beta por vez e um uso por código em cada conta. * O painel mostra o plano como **Beta**, com a data e a hora do fim. Você recebe um e-mail 3 dias antes. * No fim, a conta volta ao Free: os projetos param e os arquivos ficam guardados. Ligue de novo o que couber no Free, ou assine um plano pago para continuar com tudo. # Planos e memória Source: https://docs.cubehosting.com.br/account/plans O único limite é a memória do plano, dividida como você quiser entre bots e sites. ## Os planos | Plano | Memória | Processador | Bots **ou** sites | Preço por mês | | ------------ | ---------- | ----------- | ------------------- | ------------- | | **Free** | 100 MB | 0,25 vCPU | 1 bot | R\$ 0 | | **Block** | 1 GB | 1 vCPU | 10 bots ou 2 sites | R\$ 5,99 | | **Stack** | 2 GB | 2 vCPU | 20 bots ou 4 sites | R\$ 10,99 | | **Tower** | 4 GB | 3 vCPU | 40 bots ou 8 sites | R\$ 23,99 | | **Fortress** | 8 GB | 4 vCPU | 81 bots ou 16 sites | R\$ 47,99 | | **Empresas** | Sob medida | Sob medida | Centenas de bots | Sob consulta | A coluna "Bots ou sites" é o máximo de um tipo só. Você pode misturar os dois, como explicado abaixo. Para o plano **Empresas**, fale com a gente no [Discord](https://discord.gg/pv6D9tUsDV). ## Como a memória funciona O **único limite é a memória** do plano (1 GB = 1024 MB). Você divide como quiser entre os projetos, e cada projeto tem um mínimo: | Tipo | Mínimo | | ----------- | ------ | | Bot | 100 MB | | Site ou API | 512 MB | Exemplo no **Block** (1 GB): 1 site de 512 MB e 5 bots de 100 MB, ou 1 site de 512 MB e 2 bots de 256 MB. A memória de um projeto é **reservada** mesmo quando ele está parado. A soma da memória de todos os projetos não passa a do plano. Para liberar espaço, diminua a memória de um projeto em **Configurações** › **Geral** ou exclua o que não usa mais. A memória de cada projeto também é o **teto** dele: se o processo passar disso, ele é encerrado, e os outros projetos seguem no ar. ## O que cada plano inclui Envio por `.zip` e pela API, instalação das dependências, logs ao vivo, métricas, [variáveis de ambiente](/hosting/environment-variables) cifradas, [envio de código novo](/hosting/files#atualizar-o-código-com-um-novo-zip) e [Cube AI](/cube-ai). Tudo do Free, mais [sites e APIs](/hosting/sites-and-apis) com HTTPS, **reinício automático** quando o projeto cai e o [explorador de arquivos](/hosting/files) com editor. ## Em breve | Recurso | Planos | | -------------------------------------------------------- | ---------------------------------------------------- | | **Blob** (armazenamento de arquivos) | Block 5 GB, Stack 10 GB, Tower 25 GB, Fortress 50 GB | | **Bancos de dados** (PostgreSQL, MySQL, MongoDB e Redis) | Stack 1, Tower 3, Fortress 6 | | **Domínio próprio** | A partir do Tower | Quando chegarem, bancos também usam a memória do plano (Redis a partir de 256 MB; PostgreSQL, MySQL e MongoDB a partir de 512 MB). ## Trocar de plano O upgrade vale na hora, pagando só a diferença dos dias que faltam. O downgrade fica agendado para o próximo ciclo. Veja [Pagamento por Pix](/account/pix-billing#trocar-de-plano). # Segurança da conta Source: https://docs.cubehosting.com.br/account/security Verificação em duas etapas, sessões ativas, histórico de segurança e o que fazer se algo estranho acontecer. Tudo isto fica em [Minha conta](https://app.cubehosting.com.br/account). ## Verificação em duas etapas Com as duas etapas ligadas, o login pede a senha e um código de 6 dígitos do seu app autenticador (Google Authenticator, Authy, 1Password e parecidos). Em **Minha conta** › **Segurança**, clique para ligar e confirme a sua senha. Abra o app autenticador, leia o QR Code e digite o código que ele mostra. O painel mostra **10 códigos de recuperação**, uma vez só. Cada um entra uma vez, se você ficar sem o celular. Guarde num lugar seguro. Sem o celular e sem os códigos? No login, peça o código **por e-mail**. Ele vale 10 minutos. Para desligar ou gerar códigos novos, a Cube pede a senha e um código (do app, de recuperação ou por e-mail). ## Sessões ativas Cada aparelho em que você entrou é uma sessão. Em **Minha conta** › **Sessões** você vê o aparelho, o IP (parcialmente escondido) e a última atividade, e pode encerrar uma sessão ou **todas as outras** de uma vez. Uma sessão encerrada também perde os logs ao vivo que estavam abertos nela. ## Histórico de segurança Em **Minha conta** › **Histórico** ficam os logins, as tentativas que falharam e as trocas de senha, e-mail e duas etapas, com o aparelho e o IP parcialmente escondido. ## Senha e e-mail * **Trocar a senha** pede a senha atual e encerra as outras sessões. A sessão deste aparelho continua. * **Trocar o e-mail** pede a senha e manda um link de confirmação ao endereço novo. A troca só vale quando você abre o link. * O endereço **antigo** recebe um aviso com o link **Não fui eu**, que vale 7 dias. Ele devolve a conta para o e-mail de antes, com senha nova. ## Chaves de API As [chaves de API](/api-reference/introduction#autenticação) dão acesso aos seus projetos por código. * Criar uma chave pede a sua senha, e você recebe um e-mail avisando. * A chave aparece **uma vez só**. A Cube guarda só uma impressão dela, não a chave. * Revogar vale no pedido seguinte. ## Se algo estranho acontecer Recebeu um aviso de segurança que não foi você? Use **Esqueci a senha** para redefinir, ou o link **Não fui eu** do e-mail. Os dois encerram **todas as sessões** e revogam **todas as chaves de API** da conta. Depois, ligue as duas etapas, confira o **Histórico** e a [Atividade](https://app.cubehosting.com.br/activity), e crie chaves de API novas, se precisar. Se precisar de ajuda, fale com a gente no [Discord](https://discord.gg/pv6D9tUsDV). # Referência da API Source: https://docs.cubehosting.com.br/api-reference/introduction A mesma API do painel, para scripts e CI: envie o .zip, inicie, pare, reinicie, leia logs e métricas e cuide das variáveis. A API da Cube segue o estilo REST: rotas previsíveis, respostas em JSON e os códigos HTTP de sempre. É a mesma API que o painel usa, com uma chave no lugar do login. ## URL base ```text theme={null} https://app.cubehosting.com.br/api ``` Todo pedido vai por HTTPS. ## Autenticação Mande a sua chave de API no cabeçalho `Authorization`: ```bash theme={null} Authorization: Bearer cube_… ``` No painel, abra [Chaves de API](https://app.cubehosting.com.br/api-keys) e clique para criar. Dê um nome (como "CI do GitHub"), escolha a permissão e confirme com a sua senha. A chave começa com `cube_` e aparece **uma vez só**. Guarde num gerenciador de segredos ou numa variável de ambiente, como `CUBE_API_KEY`. Mande `Authorization: Bearer $CUBE_API_KEY` em todo pedido. Sem cookie e sem nada mais. | Permissão | O que libera | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Leitura** | Listar e ver projetos, ler logs e métricas | | **Leitura e escrita** | Tudo da leitura, mais enviar e reenviar o `.zip`, iniciar, parar, reiniciar e as variáveis de ambiente (inclusive listar, porque são segredo) | * Até **10 chaves** por conta. A lista mostra o começo de cada chave e quando ela foi usada pela última vez. * **Revogar** vale no pedido seguinte. Logs abertos com a chave revogada fecham em até 20 segundos. * Redefinir a senha ou usar o **Não fui eu** revoga **todas** as chaves da conta. * Tudo o que a chave faz entra na [Atividade](https://app.cubehosting.com.br/activity) com o nome dela. A chave dá acesso aos seus projetos. Nunca coloque no código, num repositório ou num app que roda no navegador. Vazou? Revogue no painel e crie outra. ## O que a chave pode fazer | Ação | Rota | Permissão | | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ | ----------------- | | [Listar projetos](/api-reference/projects/list) | `GET /projects` | Leitura | | [Ver um projeto](/api-reference/projects/get) | `GET /projects/{id}` | Leitura | | [Logs ao vivo](/api-reference/projects/logs) | `GET /projects/{id}/logs` | Leitura | | [Métricas](/api-reference/projects/metrics) | `GET /projects/{id}/metrics` | Leitura | | [Criar um projeto](/api-reference/projects/create) | `POST /projects` | Leitura e escrita | | [Enviar novo código](/api-reference/projects/upload-code) | `POST /projects/{id}/code` | Leitura e escrita | | [Iniciar](/api-reference/projects/start), [parar](/api-reference/projects/stop) e [reiniciar](/api-reference/projects/restart) | `POST /projects/{id}/start` · `stop` · `restart` | Leitura e escrita | | [Listar](/api-reference/projects/list-variables) e [definir variáveis](/api-reference/projects/set-variables) | `GET` e `PUT /projects/{id}/variables` | Leitura e escrita | Excluir um projeto, mudar as configurações, mexer nos arquivos, ver o uso da conta e cuidar de chaves e cobrança são **só pelo painel**. Com uma chave, essas rotas respondem `403 api_key_not_allowed` ou `401 not_authenticated`. Uma chave nunca cria nem revoga outra chave. ## Limites Os pedidos com chave contam por conta (todas as chaves somadas), por minuto e por dia: | Plano | Por minuto | Por dia | | ------------ | ---------- | ------- | | **Free** | 10 | 5.000 | | **Block** | 30 | 43.200 | | **Stack** | 60 | 86.400 | | **Tower** | 120 | 172.800 | | **Fortress** | 180 | 259.200 | | **Empresas** | 240 | 345.600 | Toda resposta a um pedido com chave válida traz os cabeçalhos do limite: | Cabeçalho | O que diz | | --------------------- | ------------------------------------------------------ | | `RateLimit-Limit` | O limite da janela mais apertada agora | | `RateLimit-Remaining` | Quantos pedidos ainda cabem nela | | `RateLimit-Reset` | Em quantos segundos ela zera | | `RateLimit-Policy` | As duas janelas do plano, como `10;w=60, 5000;w=86400` | Passou do limite: `429 rate_limit_exceeded` com `Retry-After`. Além disso, as ações pesadas têm limite próprio: **um envio de `.zip` a cada 3 segundos** por conta e **uma abertura de logs a cada 5 segundos** por projeto, com até 5 abertas ao mesmo tempo (`429 too_many_requests`). ## Formato * **Pedidos** com corpo usam JSON (`Content-Type: application/json`), menos o envio do `.zip`, que é `multipart/form-data`. * **Respostas** são JSON com o recurso pelo nome: `{ "project": { … } }` ou `{ "projects": [ … ] }`. Os logs chegam por streaming (`text/event-stream`). * **IDs** de projeto têm 26 caracteres, como `01J8Z3W6N0Q4Y7V2K5T9D1H3XA`. * **Datas** em ISO 8601, em UTC: `2026-09-26T18:00:00.000Z`. * **Memória** sempre em MB (`memoryMb`). 1 GB = 1024 MB. * **Erros** no formato `{ "status": "error", "code", "message" }`. Veja todos em [Códigos de erro](/errors). ## O ciclo de vida de um projeto | `status` | No painel | Quando | | ------------ | --------------- | --------------------------------------------------------------- | | `creating` | Enviando | O `.zip` chegou e está sendo extraído | | `installing` | Instalando | Instalando as dependências e rodando o build | | `running` | No ar | O processo está de pé | | `stopped` | Parado | Parado por você, terminou com código 0 ou instalado sem iniciar | | `restarting` | Reiniciando | Caiu e vai voltar sozinho, ou está reiniciando a seu pedido | | `crash_loop` | Em loop de erro | Caiu 5 vezes seguidas e parou de tentar | | `error` | Com erro | A instalação ou a subida falhou, ou caiu no Free | Em `creating` e `installing`, iniciar, parar e reiniciar respondem `409 project_busy`. Nada sobe sem você pedir: um projeto novo só inicia com `start=true` no envio. ## Primeiro pedido ```bash curl theme={null} curl https://app.cubehosting.com.br/api/projects \ -H "Authorization: Bearer $CUBE_API_KEY" ``` ```js Node.js theme={null} const API = 'https://app.cubehosting.com.br/api'; const headers = { Authorization: `Bearer ${process.env.CUBE_API_KEY}` }; const res = await fetch(`${API}/projects`, { headers }); if (!res.ok) throw new Error((await res.json()).message); const { projects } = await res.json(); for (const p of projects) console.log(p.id, p.name, p.status); ``` ```python Python theme={null} import os import requests API = "https://app.cubehosting.com.br/api" headers = {"Authorization": f"Bearer {os.environ['CUBE_API_KEY']}"} r = requests.get(f"{API}/projects", headers=headers, timeout=30) r.raise_for_status() for p in r.json()["projects"]: print(p["id"], p["name"], p["status"]) ``` Os exemplos de Node.js usam `fetch` nativo e `await` fora de função: rode no Node.js 20 ou mais novo, com o arquivo salvo como `.mjs` (ou com `"type": "module"` no `package.json`). Os de Python usam [requests](https://requests.readthedocs.io). ## Deploy pelo CI Com uma chave de leitura e escrita guardada como segredo do CI, um passo basta para atualizar o projeto a cada push: ```bash theme={null} zip -r projeto.zip . -x "node_modules/*" ".git/*" ".env" curl --fail-with-body https://app.cubehosting.com.br/api/projects/$CUBE_PROJECT_ID/code \ -H "Authorization: Bearer $CUBE_API_KEY" \ -F "file=@projeto.zip" ``` O projeto volta ao ar com o código novo sozinho, se estava ligado. Veja [Enviar novo código](/api-reference/projects/upload-code). # Criar um projeto Source: https://docs.cubehosting.com.br/api-reference/projects/create POST /projects Envie um .zip e crie um projeto. A Cube instala as dependências e, com start=true, inicia o projeto sozinha. Envie o `.zip` como `multipart/form-data` no campo `file`. A configuração vem do [`cube.json`](/cube-json) na raiz do `.zip`, ou dos campos do formulário. A Cube confere o tamanho, extrai o `.zip` e valida a configuração. Se algo estiver errado, nada é criado e a resposta diz o motivo. O projeto nasce em `installing`. As dependências são instaladas e o build roda, se houver. Acompanhe pelos [logs](/api-reference/projects/logs) com `source=build`. Com `start=true`, o projeto sobe sozinho (`running`). Sem ele, fica `stopped` até você [iniciar](/api-reference/projects/start). Guarde tokens em [variáveis de ambiente](/api-reference/projects/set-variables), não no `.zip`. Para um bot que precisa do token para entrar, crie o projeto sem `start`, defina as variáveis e depois inicie. # Ver um projeto Source: https://docs.cubehosting.com.br/api-reference/projects/get GET /projects/{id} Um projeto da sua conta, com o status e o uso de agora. Um projeto da sua conta, com o status e o uso de agora. Útil para acompanhar a instalação depois de [criar](/api-reference/projects/create) ou [enviar código novo](/api-reference/projects/upload-code): consulte até o `status` sair de `installing`. Quando o `status` é `error` ou `crash_loop`, o campo `error` diz o motivo. Veja [Estados de erro do projeto](/errors#estados-de-erro-do-projeto). # Listar projetos Source: https://docs.cubehosting.com.br/api-reference/projects/list GET /projects Todos os projetos da sua conta, do mais novo para o mais antigo. Devolve todos os projetos da sua conta, do mais novo para o mais antigo. Use o `id` de cada um nas outras rotas. O `usage` (memória, processador e rede de agora) vem só nos projetos com `status` `running`. Para o histórico, use as [métricas](/api-reference/projects/metrics). # Listar variáveis Source: https://docs.cubehosting.com.br/api-reference/projects/list-variables GET /projects/{id}/variables Os nomes das variáveis de ambiente do projeto. Os valores nunca voltam. Devolve só os **nomes** das variáveis de ambiente. Os valores ficam cifrados e nunca voltam, nem pelo painel. Mesmo sendo uma leitura, esta rota pede uma chave de **leitura e escrita**: saber quais segredos um projeto usa já é informação sensível. # Logs do projeto Source: https://docs.cubehosting.com.br/api-reference/projects/logs GET /projects/{id}/logs Receba os logs do projeto ao vivo, por Server-Sent Events. Os logs chegam por **Server-Sent Events**: uma conexão HTTP que fica aberta e recebe eventos de texto. Primeiro vêm as últimas linhas, depois as novas, ao vivo. ## Eventos Uma linha do log. Quando a linha foi escrita (ISO 8601, UTC). De onde veio a linha. `build` só com `source=build`. O texto da linha, até 4.096 caracteres. O projeto mudou de estado. O [status](/api-reference/introduction#o-ciclo-de-vida-de-um-projeto) novo. Quedas seguidas até agora. O motivo, `{ code, message }`, quando o status novo é `error` ou `crash_loop`. Veja [Estados de erro do projeto](/errors#estados-de-erro-do-projeto). Linhas que começam com `:` são comentários (`: open` na abertura e `: ping` a cada 20 segundos): ignore. O log é texto do seu app. Mostre sempre como texto, nunca como HTML. `stdout` e `stderr` podem chegar fora de ordem entre si: ordene por `time` se precisar. ## Limites * Uma abertura a cada 5 segundos por projeto e origem (`app` ou `build`). * Até 5 streams abertos ao mesmo tempo por conta. * Se a chave for revogada, o stream fecha em até 20 segundos. Se a conexão cair, espere o `Retry-After` (quando houver) e abra de novo. As últimas linhas vêm de novo na reabertura, então limpe a tela ou descarte as repetidas. ```text 200 theme={null} : open event: line data: {"time":"2026-09-26T18:01:09.870Z","stream":"stdout","text":"Iniciando o bot..."} event: line data: {"time":"2026-09-26T18:01:10.123Z","stream":"stdout","text":"Logado como MeuBot#1234"} event: status data: {"status":"restarting","consecutiveCrashes":1,"error":null} : ping ``` # Métricas do projeto Source: https://docs.cubehosting.com.br/api-reference/projects/metrics GET /projects/{id}/metrics Memória, processador e rede do projeto em 15 minutos, 1 hora ou 24 horas. Memória, processador e rede do projeto ao longo do tempo, as mesmas dos gráficos do painel. | `window` | Intervalo entre pontos | O que é | | -------- | ---------------------- | ---------------------- | | `15m` | 15 segundos | Ao vivo | | `1h` | 60 segundos | Uma amostra por minuto | | `24h` | 300 segundos | Médias de 5 minutos | `cpuPercent` 100 é um núcleo inteiro. A rede vem em bytes por segundo. Minutos em que o projeto estava parado não têm ponto. # Reiniciar um projeto Source: https://docs.cubehosting.com.br/api-reference/projects/restart POST /projects/{id}/restart Pare e ligue o projeto de novo, zerando a contagem de quedas. Para e liga o projeto de novo, zerando a contagem de quedas. Num projeto parado, com erro ou em loop, funciona como [iniciar](/api-reference/projects/start). Mudou as [variáveis de ambiente](/api-reference/projects/set-variables)? Reinicie para o processo receber os valores novos. # Definir variáveis Source: https://docs.cubehosting.com.br/api-reference/projects/set-variables PUT /projects/{id}/variables Troque a lista inteira de variáveis de ambiente numa chamada só. Troca a lista inteira de variáveis do projeto numa chamada só. **A lista que você manda substitui a que está guardada.** Variável que ficar de fora é apagada, e valor apagado não volta. Para mudar uma só, mande todas: a que muda com `value` e as outras só com `name`, para manter o valor. Veja os nomes atuais em [Listar variáveis](/api-reference/projects/list-variables). ```json Novo TOKEN, mantendo o PREFIX theme={null} { "variables": [ { "name": "TOKEN", "value": "token-novo" }, { "name": "PREFIX" } ] } ``` ```json Apagar todas theme={null} { "variables": [] } ``` No primeiro exemplo, `TOKEN` recebe um valor novo, `PREFIX` mantém o valor que já tinha e qualquer outra variável é apagada. Se `isRestartRequired` vier `true`, [reinicie](/api-reference/projects/restart) o projeto para ele receber os valores novos. Veja as regras de nomes e tamanhos em [Variáveis de ambiente](/hosting/environment-variables#regras). # Iniciar um projeto Source: https://docs.cubehosting.com.br/api-reference/projects/start POST /projects/{id}/start Ligue um projeto. A resposta chega quando ele está de pé. Liga o projeto e responde quando ele está de pé. Se ele já estava no ar, nada muda. * Só sobe o que cabe no plano: a memória deste projeto mais a dos que já estão ligados não pode passar a do plano (`plan_limit_reached`). * Se a última instalação falhou, envie o código de novo antes (`install_pending`). * Se a versão da linguagem mudou em **Configurações**, o projeto passa pela instalação antes de subir e a resposta é `202`. # Parar um projeto Source: https://docs.cubehosting.com.br/api-reference/projects/stop POST /projects/{id}/stop Pare um projeto e desligue o reinício automático até o próximo início. Para o projeto e desliga o reinício automático até o próximo início. O processo recebe o aviso para encerrar e tem 10 segundos para terminar o que está fazendo. Parar funciona inclusive com a conta suspensa. Só não dá durante o envio e a instalação (`409 project_busy`). A memória do projeto continua reservada: para liberar, diminua a memória ou exclua o projeto pelo painel. # Enviar novo código Source: https://docs.cubehosting.com.br/api-reference/projects/upload-code POST /projects/{id}/code Troque o código de um projeto por um .zip novo, sem mudar a configuração. Atualiza o código de um projeto que já existe, como faria um deploy no CI. A configuração do projeto não muda. O `.zip` novo substitui a pasta inteira do projeto (só as dependências instaladas ficam). Arquivos que o seu app criou, como um banco SQLite, somem se não estiverem no `.zip`. ## Deploy a cada push (GitHub Actions) Guarde uma chave de leitura e escrita como segredo `CUBE_API_KEY` e o ID do projeto como variável `CUBE_PROJECT_ID`: ```yaml .github/workflows/deploy.yml theme={null} name: Deploy na Cube on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Compactar run: zip -r projeto.zip . -x "node_modules/*" ".git/*" ".github/*" - name: Enviar run: | curl --fail-with-body \ https://app.cubehosting.com.br/api/projects/${{ vars.CUBE_PROJECT_ID }}/code \ -H "Authorization: Bearer ${{ secrets.CUBE_API_KEY }}" \ -F "file=@projeto.zip" ``` # Cube AI Source: https://docs.cubehosting.com.br/cube-ai Suporte técnico que explica fácil, dentro do painel: lê os seus projetos e logs, diz por que o bot caiu e, com a sua confirmação, liga, desliga e reinicia. Cube AI fica no canto inferior direito do [painel](https://app.cubehosting.com.br), no cubo. Conversa em português, vai direto ao ponto e explica sem jargão. ## O que Cube AI faz Como subir um bot, o que vai no `cube.json`, qual plano cabe no seu caso, o que significa um erro. Status, memória, processador, quedas, histórico de envios, uso da conta e os logs da aplicação e da instalação. Num projeto **Com erro** ou **Em loop de erro**, o botão **Por que caiu?** abre a conversa com um diagnóstico a partir dos logs. Nos planos pagos, liga, desliga, reinicia e muda nome, descrição, comando, versão e memória, sempre com um cartão de confirmação. Dá também para mandar um **print** (por exemplo, de um erro no seu computador), marcar um projeto com **@** e usar **Analisar a fundo** para uma análise mais longa, do plano Tower para cima. ## Pode agir Por padrão, Cube AI só **vê e explica**. Para ligar, desligar, reiniciar ou mudar a configuração pela conversa, ligue o **Pode agir** no topo da conversa. * Vale **só naquela conversa** e só neste aparelho. Toda conversa nova começa com ele desligado. * Mesmo ligado, **cada ação pede o seu clique** num cartão de confirmação, que diz exatamente o que vai acontecer. * Cada cartão vale **um clique** e **5 minutos**. Desligar o Pode agir cancela os cartões abertos. * É dos planos pagos. No Free, Cube AI vê e explica, e as ações ficam na página do projeto. ## O que Cube AI nunca faz Cube AI **nunca apaga nada**: projeto, arquivo ou conta. Nem com o Pode agir ligado, nem com confirmação. Se você pedir, recebe a explicação e o botão da tela onde **você** faz. Senha, duas etapas, chaves de API e pagamento também ficam de fora: para esses, Cube AI manda o botão da tela certa. ## Privacidade * Antes de qualquer leitura, tokens, chaves, senhas, e-mails e IPs são **escondidos** automaticamente, nas suas mensagens, nos logs e nos resultados. * Das variáveis de ambiente, Cube AI vê só os **nomes**, nunca os valores. * Os prints não ficam guardados: no histórico da conversa, aparece só "\[print enviado]". * Cube AI enxerga só a sua conta, com as mesmas permissões que você tem no painel. ## Cota do dia A cota é de **mensagens por dia** e zera às **00:00, horário de Brasília**. A janela da conversa mostra quanto você já usou. | Plano | Mensagens por dia | Prints por dia | Analisar a fundo | | ------------ | ----------------- | -------------- | ---------------- | | **Free** | 8 | 1 | — | | **Block** | 25 | 3 | — | | **Stack** | 40 | 5 | — | | **Tower** | 60 | 10 | 3 por dia | | **Fortress** | 100 | 15 | 3 por dia | Cada **Analisar a fundo** conta como 5 mensagens, e uma mensagem com logs muito longos pode contar como mais de uma. Os números podem mudar: o que vale é o que a janela da conversa mostra. # O arquivo cube.json Source: https://docs.cubehosting.com.br/cube-json A configuração do projeto num arquivo só: linguagem, versão, comando de início, memória, porta, subdomínio e build. O `cube.json` fica na **raiz do .zip** e diz à Cube como rodar o seu projeto. Ele é opcional no painel (que detecta sozinho e mostra para você conferir), mas deixa o envio pela API automático. ```json cube.json theme={null} { "name": "Bot da loja", "language": "node", "version": "22", "command": "node index.js", "memoryMb": 100 } ``` ## Chaves A linguagem do projeto. O comando que inicia o projeto, como `node index.js`, `npm start` ou `python main.py`. De 1 a 500 caracteres, numa linha só. Ele roda dentro da pasta do projeto. O nome que aparece no painel, de 1 a 40 caracteres. Sem ele, vale o nome do arquivo `.zip`. `bot` é um processo sem endereço na internet (bots de Discord, workers, tarefas). `site` é um site ou API que recebe visitas por HTTPS. Veja [Sites e APIs](/hosting/sites-and-apis). A versão da linguagem. Node.js: `"20"`, `"22"` ou `"24"`. Python: `"3.11"` ou `"3.12"`. Sem ela, vale a mais nova. A memória do projeto, em MB. O mínimo é **100** para bot e **512** para site, e esse também é o valor padrão. A soma da memória de todos os seus projetos não pode passar a do plano. No Free, a conta tem **100 MB** no total: um bot que pede mais é recusado com `insufficient_memory`. Só para `site`: a porta em que o seu app escuta, de 1024 a 65535. O app recebe o mesmo número na variável `PORT`. Só para `site`: o nome em `nome.cubehost.dev`. De 3 a 32 caracteres, com letras minúsculas, números e hífen. Sem ele, a Cube gera um a partir do nome do projeto. Veja [Endereço e domínios](/hosting/domains). Um comando que roda depois de instalar as dependências, como `npm run build`. Sem a chave, o build é automático: se o `package.json` tem um script `build`, ele roda. Use `""` para não rodar nenhum build. Chave desconhecida é recusada com o erro `invalid_config`, dizendo qual chave. Assim um erro de digitação não passa calado. `port` e `subdomain` num `bot` também são recusados. ## Exemplos ```json cube.json theme={null} { "name": "Bot da loja", "language": "node", "version": "22", "command": "node index.js", "memoryMb": 100 } ``` ```json cube.json theme={null} { "name": "Bot TS", "language": "node", "command": "node dist/index.js", "build": "npm run build", "memoryMb": 100 } ``` ```json cube.json theme={null} { "name": "Bot de música", "language": "python", "version": "3.12", "command": "python main.py", "memoryMb": 100 } ``` ```json cube.json theme={null} { "name": "Loja", "type": "site", "language": "node", "command": "node dist/server.js", "port": 3000, "subdomain": "minha-loja" } ``` ```json cube.json theme={null} { "type": "site", "language": "python", "command": "gunicorn -w 2 -b 0.0.0.0:$PORT app:app", "memoryMb": 512 } ``` ## Onde o cube.json vale * **No painel:** ele preenche a tela **Configure o projeto**. O que você confirma na tela é o que fica valendo. * **Na API:** se o formulário do [envio](/api-reference/projects/create) trouxer `language` e `command`, o formulário vale e o `cube.json` é ignorado. Sem eles, vale o `cube.json`. Sem nenhum dos dois, o envio é recusado com `missing_config`. * **Pasta dentro do .zip:** se o `.zip` tiver uma única pasta no topo e nenhum `cube.json` na raiz, essa pasta vira a raiz. Isso cobre o "Compactar" do Windows e do macOS. A configuração fica guardada no projeto depois do primeiro envio. Um `cube.json` diferente num **novo .zip** do mesmo projeto é ignorado. Para mudar nome, comando, versão, memória ou subdomínio, use **Configurações** no projeto. Tipo, linguagem e porta não mudam: para isso, crie um projeto novo. # Códigos de erro Source: https://docs.cubehosting.com.br/errors Todo erro da API tem um código fixo em inglês e uma mensagem em português que diz o que houve e o que fazer. ## Formato Todo erro volta com o status HTTP certo e o mesmo formato: ```json theme={null} { "status": "error", "code": "insufficient_memory", "message": "Este bot pede 512 MB, mas o plano Block só tem 256 MB livres. Diminua a memória no cube.json, exclua ou reduza outro projeto, ou mude de plano.", "freeMemoryMb": 256, "requestedMemoryMb": 512 } ``` | Campo | O que é | | ------------- | ----------------------------------------------------------------------------------- | | `code` | Identificador fixo, em inglês. **Use este campo no seu código**: ele não muda. | | `message` | Texto em português para mostrar a uma pessoa. Pode mudar a qualquer momento. | | Campos extras | Alguns erros trazem dados a mais, como `limitMb` ou `field`. Estão listados abaixo. | Todo erro `429` traz o cabeçalho `Retry-After`, com os segundos que faltam. Espere esse tempo antes de tentar de novo. ## Autenticação e limites A chave não existe, foi revogada ou está fora do formato. **O que fazer:** Confira o cabeçalho `Authorization: Bearer cube_…` ou crie outra chave no painel. A chave é só de leitura e a rota muda algo. **O que fazer:** Crie uma chave de **leitura e escrita**. Esta ação não aceita chave de API. **O que fazer:** Faça pelo painel. Veja [o que a API faz](/api-reference/introduction#o-que-a-chave-pode-fazer). A rota é só do painel e o pedido veio sem sessão. **O que fazer:** Use uma rota da API pública ou faça pelo painel. A conta passou dos pedidos por minuto ou por dia do plano. **O que fazer:** Espere o `Retry-After`. Veja os [limites](/api-reference/introduction#limites). Ações pesadas seguidas: envio de `.zip` (1 a cada 3 s) ou abertura de logs (1 a cada 5 s por projeto, até 5 abertos). **O que fazer:** Espere o `Retry-After` e tente de novo. 10 chaves erradas do mesmo IP em 10 minutos. Chaves erradas desse IP ficam bloqueadas por 15 minutos. **O que fazer:** Corrija a chave. Uma chave certa continua passando. ## Pedidos Um parâmetro ou o corpo está fora do formato (por exemplo, `lines` acima de 1000 ou uma variável com nome inválido). **O que fazer:** Leia a `message`: ela diz qual campo. O corpo não veio como JSON. Acontece, por exemplo, no `curl -d` sem o cabeçalho `Content-Type`, que manda o corpo como formulário. **O que fazer:** Mande `Content-Type: application/json` junto do corpo. O corpo JSON do pedido é grande demais. **O que fazer:** Mande só o que a rota pede. As variáveis, somadas, vão até 32 KB. Para o `.zip`, o limite é outro: veja `invalid_zip`. O projeto não existe ou não é da sua conta. **O que fazer:** Confira o ID. A resposta é a mesma nos dois casos, de propósito. Algo falhou do nosso lado. **O que fazer:** Tente de novo em instantes. Se continuar, fale com a gente. ## Envio do .zip e configuração **413:** o `.zip` passou do limite do plano. Traz `limitMb`. **422:** não é um `.zip`, está corrompido, vazio ou tem senha. **O que fazer:** Tire `node_modules`, `venv` e o que o projeto não usa (veja [Limites do .zip](/hosting/zip-limits)), ou compacte de novo, sem senha. Tem atalhos, caminhos para fora da pasta, arquivos especiais ou cresce demais ao descompactar. Traz `reason`: `path`, `link`, `special_file`, `size`, `file_count` ou `compression_ratio`. **O que fazer:** Compacte só os arquivos do projeto. Sem `cube.json` no `.zip` e sem `language` e `command` no formulário. **O que fazer:** Mande um [`cube.json`](/cube-json) ou os campos no formulário. O `cube.json` ou o formulário tem um campo errado ou desconhecido, ou `port`/`subdomain` num bot. Traz `field`, quando dá para saber. **O que fazer:** Corrija o campo indicado. Linguagem ou versão fora da lista. Traz `supported`. **O que fazer:** Use Node.js `20`, `22` ou `24`, ou Python `3.11` ou `3.12`. A memória pedida passa do que sobra no plano. Traz `freeMemoryMb` e `requestedMemoryMb`. **O que fazer:** Diminua a memória deste ou de outro projeto, exclua um que não usa ou mude de plano. O plano já tem o máximo de projetos. Traz `limit`. **O que fazer:** Exclua um projeto ou mude de plano. Site ou API num plano sem sites (Free). **O que fazer:** Envie como `bot` ou veja os [planos pagos](/account/plans). O plano já tem o máximo de sites. Traz `limit`. **O que fazer:** Exclua um site ou mude de plano. Subdomínio fora do formato. Traz `field`. **O que fazer:** De 3 a 32 caracteres: letras minúsculas, números e hífen, sem hífen nas pontas. Nome reservado, ou que lembra banco, marca ou órgão público. Traz `field`. **O que fazer:** Escolha outro. Outro site já usa esse subdomínio. Traz `field`. **O que fazer:** Escolha outro. Os servidores estão cheios agora. **O que fazer:** Tente de novo mais tarde. Nada foi cobrado nem apagado. ## Iniciar, parar e reiniciar O projeto está instalando ou já tem outra ação em curso. **O que fazer:** Espere alguns segundos e tente de novo. A última instalação falhou, então não há o que iniciar. **O que fazer:** Confira os logs da instalação, corrija e envie o código de novo. Ligar este projeto passa da memória do plano com os que já estão ligados. Traz `freeMemoryMb` e `requestedMemoryMb`. **O que fazer:** Pare outro projeto ou diminua a memória deste. A conta está suspensa por falta de pagamento. Parar continua liberado. **O que fazer:** Pague em **Plano e cobrança**. Veja [Pagamento por Pix](/account/pix-billing). O beta acabou de terminar e a conta está voltando ao Free. **O que fazer:** Espere alguns minutos. Nada foi apagado. O servidor dos projetos não respondeu a tempo. **O que fazer:** Tente de novo em instantes. Nada foi alterado. Não deu para abrir as variáveis do projeto agora. Aparece também ao iniciar, reiniciar ou enviar código novo, porque o projeto não sobe sem as variáveis. **O que fazer:** Tente de novo em instantes. Nada foi gravado. ## Estados de erro do projeto Quando um projeto fica **Com erro** ou **Em loop de erro**, o campo `error` do [projeto](/api-reference/projects/get) traz um destes códigos. Eles não são erros HTTP: são o motivo de o projeto não estar no ar. A instalação das dependências ou o build terminou com erro. **O que fazer:** Corrija o pacote ou a versão e envie de novo. A instalação passou de 5 minutos. **O que fazer:** Diminua as dependências. A instalação passou de 1 GB de memória. **O que fazer:** Tire dependências que só servem para desenvolvimento. Um problema do nosso lado interrompeu a instalação. **O que fazer:** Envie o código de novo. O comando de início não subiu. **O que fazer:** Confira o comando e o arquivo principal. O processo caiu no plano Free, que não reinicia sozinho. **O que fazer:** Corrija e inicie de novo. O projeto caiu 5 vezes seguidas e parou de reiniciar. **O que fazer:** Corrija o erro e inicie de novo. No painel, o botão **Por que caiu?** pede um diagnóstico para [Cube AI](/cube-ai) a partir dos logs. ## Páginas que o visitante do seu site vê Para as páginas de site parado, sem resposta ou endereço inexistente, veja [Sites e APIs](/hosting/sites-and-apis#páginas-que-o-visitante-pode-ver). # Bots de Discord Source: https://docs.cubehosting.com.br/hosting/discord-bots Hospede bots em Node.js (discord.js), TypeScript com build automático e Python (discord.py). Um bot é um projeto do tipo `bot`: um processo que fica ligado e conversa com o Discord por conta própria. Ele não precisa de porta nem de endereço na internet. Envie o código com o `package.json`. A Cube roda `npm ci` quando existe `package-lock.json` e `npm install` quando não existe. ```js index.js theme={null} const { Client, Events, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.once(Events.ClientReady, (c) => console.log(`Logado como ${c.user.tag}`)); client.login(process.env.TOKEN); ``` ```json package.json theme={null} { "name": "meu-bot", "main": "index.js", "dependencies": { "discord.js": "^14.16.0" } } ``` ```json cube.json theme={null} { "name": "Meu bot", "language": "node", "version": "24", "command": "node index.js", "memoryMb": 100 } ``` Envie o `package-lock.json` junto. Com ele, a instalação usa exatamente as versões que você testou. Não precisa compilar antes de enviar. Se o `package.json` tem um script `build`, a Cube roda o build depois de instalar as dependências. O comando de início aponta para o arquivo compilado. ```ts src/index.ts theme={null} import { Client, Events, GatewayIntentBits } from 'discord.js'; const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.once(Events.ClientReady, (c) => console.log(`Logado como ${c.user.tag}`)); client.login(process.env.TOKEN); ``` ```json package.json theme={null} { "name": "meu-bot-ts", "scripts": { "build": "tsc" }, "dependencies": { "discord.js": "^14.16.0" }, "devDependencies": { "typescript": "^5.6.0", "@types/node": "^22.0.0" } } ``` ```json tsconfig.json theme={null} { "compilerOptions": { "target": "ES2022", "module": "commonjs", "rootDir": "src", "outDir": "dist", "strict": true, "esModuleInterop": true } } ``` ```json cube.json theme={null} { "name": "Meu bot TS", "language": "node", "command": "node dist/index.js", "memoryMb": 100 } ``` * As `devDependencies` também são instaladas, então o `typescript` do projeto está disponível no build. * Sem script `build`, o painel sugere `npx -p typescript tsc` no campo **Comando de build** (em **Avançado**). Você pode trocar à vontade. * Não envie a pasta `dist`: ela é gerada aqui. * A saída do build aparece em **Logs** › **Instalação**. Build com erro deixa o projeto em **Com erro** e mostra o motivo ali. Envie o código com o `requirements.txt`. A Cube cria o ambiente e roda `pip install -r requirements.txt`. ```python main.py theme={null} import os import discord intents = discord.Intents.default() client = discord.Client(intents=intents) @client.event async def on_ready(): print(f"Logado como {client.user}") client.run(os.environ["TOKEN"]) ``` ```text requirements.txt theme={null} discord.py==2.4.0 ``` ```json cube.json theme={null} { "name": "Meu bot", "language": "python", "version": "3.12", "command": "python main.py", "memoryMb": 100 } ``` * O `print` aparece nos logs na hora (a variável `PYTHONUNBUFFERED` já vem ligada). * Só o `requirements.txt` é instalado. Um projeto só com `pyproject.toml` precisa de um `requirements.txt` também. * Não envie o `venv`: ele é criado aqui. ## O token do bot Guarde o token numa [variável de ambiente](/hosting/environment-variables), nunca no código. No painel: **Configurações** › **Variáveis**. Pela API: [Definir variáveis](/api-reference/projects/set-variables). Se o token foi parar num `.zip`, num repositório ou num print, gere outro no Portal de Desenvolvedores do Discord. Um token vazado dá acesso total ao bot. ## Intents privilegiados Se o bot lê o conteúdo das mensagens ou a lista de membros, ligue os intents **Message Content** e **Server Members** no [Portal de Desenvolvedores do Discord](https://discord.com/developers/applications), em **Bot**. Sem isso, o bot cai ao entrar com um erro de intents nos logs. ## Quando o bot cai O bot volta sozinho. Se cair de novo, a espera entre as tentativas cresce (1, 2, 4 e 8 segundos). Depois de **5 quedas seguidas**, ele para e fica **Em loop de erro**, em vez de insistir sem fim. Rodar 60 segundos sem cair zera a contagem. Sem reinício automático: se o processo cair, o projeto fica **Com erro** até você iniciar de novo. Um bot que termina com código `0` (saída normal) fica **Parado**, sem reinício. Para sair do **Em loop de erro**, corrija o problema e clique em **Iniciar** ou **Reiniciar**. No projeto com erro ou em loop, o botão **Por que caiu?** pede um diagnóstico para [Cube AI](/cube-ai) a partir dos seus logs. ## Memória O mínimo de um bot é **100 MB**. Comece pequeno e acompanhe o uso real no gráfico de **Memória** do projeto. A memória reservada é o teto: se o bot passar dela, o processo é encerrado (e, nos planos pagos, volta sozinho). Se o gráfico encosta no limite antes das quedas, aumente em **Configurações** › **Geral**, desde que caiba no seu [plano](/account/plans). ## O console é só leitura Os logs mostram tudo o que o bot escreve, ao vivo. O processo não recebe comandos digitados: bots que esperam `input()` ou leem do teclado ficam parados esperando. Use comandos do próprio Discord ou variáveis de ambiente para configurar o bot. # Endereço e domínios Source: https://docs.cubehosting.com.br/hosting/domains Todo site ganha nome.cubehost.dev com HTTPS. Veja como escolher e trocar o subdomínio. ## Subdomínio padrão Todo projeto do tipo `site` ganha um endereço `https://nome.cubehost.dev`, com HTTPS automático e sem configurar nada. Bots não têm endereço: eles se conectam ao Discord por conta própria. ### Como escolher Defina o `subdomain` no [`cube.json`](/cube-json), no campo do painel ao enviar, ou deixe em branco para a Cube gerar um a partir do nome do projeto (por exemplo, `loja-do-ze-k3x9qa`). | Regra | Detalhe | | ---------- | ------------------------------------------------------ | | Tamanho | De 3 a 32 caracteres | | Caracteres | Letras minúsculas sem acento, números e hífen | | Pontas | Começa e termina com letra ou número, sem `--` | | Único | Um subdomínio pertence a um site só, de qualquer conta | Alguns nomes são **reservados** (como `www`, `api`, `app`, `admin`, `docs`) e nomes que lembram bancos, marcas e órgãos públicos são **bloqueados** para evitar golpes. Nos dois casos, o erro é `reserved_subdomain`: escolha outro. ### Como trocar Em **Configurações** › **Rede**, escreva o novo subdomínio e salve. A troca vale **na hora**: o endereço novo passa a funcionar e o antigo deixa de responder (mostra **Este endereço não existe**). Atualize os links, webhooks e integrações que apontam para o endereço antigo antes de trocar. ## Domínio próprio Em breve Em breve você vai poder usar um domínio seu, como `loja.com.br`, num site. Você cria os registros no DNS do domínio, a Cube confere a posse e o HTTPS sai sozinho. Vai chegar a partir do plano **Tower**. Até lá, use o subdomínio em `cubehost.dev`. # Variáveis de ambiente Source: https://docs.cubehosting.com.br/hosting/environment-variables Guarde tokens, senhas e configurações fora do código. Os valores ficam cifrados e chegam ao processo quando ele inicia. Variáveis de ambiente são pares de nome e valor que o seu projeto lê quando inicia, como o `TOKEN` do bot ou a URL de um banco. Elas valem em **todos os planos**, inclusive no Free. ```js Node.js theme={null} const token = process.env.TOKEN; ``` ```python Python theme={null} import os token = os.environ["TOKEN"] ``` ## Pelo painel Abra o projeto e vá em **Configurações** › **Variáveis**. * **Adicionar:** escreva o nome e o valor e salve. * **Importar .env:** cole o conteúdo de um arquivo `.env`. Linhas com `#` são comentários e ficam de fora. Escolha entre **Mesclar** com as que já existem ou **Substituir todas**. * **Trocar um valor:** digite o novo valor na variável e salve. O valor antigo nunca aparece. Depois de salvar, o painel avisa que o projeto recebe as variáveis **no próximo início** e oferece **Reiniciar agora**. ## Pela API Use [Listar variáveis](/api-reference/projects/list-variables) e [Definir variáveis](/api-reference/projects/set-variables) com uma chave de leitura e escrita. ## Regras | Regra | Limite | | ---------- | ---------------------------------------------------------------------------------------------- | | Quantidade | Até 50 variáveis por projeto | | Nome | Letras, números e `_`, começando com letra ou `_`, até 64 caracteres (`TOKEN`, `DATABASE_URL`) | | Valor | Até 4.096 caracteres, **numa linha só** | | Total | Nomes e valores somados até 32 KB | | Reservados | `HOME`, `PATH` e qualquer nome que comece com `CUBE_`. Em sites, `PORT` também | Precisa de um valor com várias linhas, como uma chave privada? Guarde em base64 e decodifique no código. ## O que já vem definido | Variável | Valor | Pode trocar? | | ------------------ | ------------------------------------------------ | ------------ | | `NODE_ENV` | `production` (Node.js) | Sim | | `PYTHONUNBUFFERED` | `1` (Python: o `print` aparece nos logs na hora) | Sim | | `PORT` | A porta do site (só em sites) | Não | | `HOME` | `/tmp` | Não | ## Segurança Os valores ficam guardados cifrados. Depois de salvos, nunca voltam: nem no painel, nem na API, nem para Cube AI. As variáveis chegam só ao seu app, quando ele inicia. A instalação das dependências e o build não enxergam os valores, então um pacote malicioso não lê o seu token. Por não chegarem ao build, variáveis que o framework embute durante o build (como as `NEXT_PUBLIC_…` do Next.js) ficam vazias. Veja a dica em [Sites e APIs](/hosting/sites-and-apis). A lista de [Atividade](https://app.cubehosting.com.br/activity) registra quem mudou as variáveis e quando, só com os **nomes**, nunca com os valores. # Arquivos e editor Source: https://docs.cubehosting.com.br/hosting/files Veja, edite, envie e baixe os arquivos do projeto pelo painel, e atualize o código com um novo .zip. ## Explorador de arquivos A aba **Arquivos** do projeto mostra a pasta do seu código, como no computador. É dos planos pagos, a partir do **Block**. Abra e edite arquivos de texto de até **1 MB**, com realce de sintaxe e formatação. Envie arquivos de até **50 MB** cada. O download sai por um link que vale 5 minutos e só para a sua conta. Crie arquivos e pastas, renomeie e mova arrastando para outra pasta, ou pelo **Mover para…** no menu do item. Apague arquivos e pastas que o projeto não usa mais. ### O que fica protegido * `node_modules` e `__pycache__` aparecem **só para leitura**: eles são criados pela instalação. Para mudar uma dependência, edite o `package.json` ou o `requirements.txt` e use **Aplicar mudanças**. * O ambiente do Python (`venv`) não aparece. * Atalhos (links simbólicos) aparecem na lista, mas não são abertos nem seguidos. * Arquivos que não são texto (imagens, `.zip`) não abrem no editor: baixe para abrir no computador. ## Aplicar mudanças Editar um arquivo não reinicia nada sozinho. Quando terminar, clique em **Aplicar mudanças**: 1. Se o `package.json`, o `package-lock.json` ou o `requirements.txt` mudou, as dependências são instaladas de novo. Se não mudou, a instalação é pulada. 2. O build roda de novo, se o projeto tiver um. 3. Se o projeto estava no ar, ele volta com o código novo. Mudou só um `.js` ou `.py`? **Reiniciar** também serve: o processo novo já lê os arquivos editados. ## Atualizar o código com um novo .zip Em **Configurações** › **Deploy**, use **Enviar .zip** para trocar o código inteiro do projeto. Vale em **todos os planos**, inclusive no Free. Pela API, é o [Enviar novo código](/api-reference/projects/upload-code). * A configuração do projeto (tipo, linguagem, comando e memória) **continua a mesma**. Um `cube.json` diferente no `.zip` novo é ignorado. * As dependências só são instaladas de novo se o manifesto mudou. * Se o `.zip` for recusado, os arquivos de antes ficam como estavam. O `.zip` novo **substitui a pasta inteira** do projeto (só as dependências instaladas ficam). Arquivos que o seu app criou, como um banco SQLite ou uploads, somem se não estiverem no `.zip`. Baixe esses arquivos pelo explorador antes de enviar, ou use **Aplicar mudanças** para trocar só o que editou. O **Histórico de envios**, na mesma seção, mostra os 20 últimos envios, edições aplicadas e trocas de versão, com o resultado de cada instalação. ## Onde o seu app pode gravar O seu código pode criar e gravar arquivos **dentro da pasta do projeto** (um banco SQLite, um JSON de configuração, uploads). Eles ficam guardados entre reinícios, mas um [novo .zip](#atualizar-o-código-com-um-novo-zip) substitui a pasta. Fora dela, só `/tmp`, que é pequeno e apagado quando o projeto reinicia. Cada projeto tem um espaço em disco próprio. Veja quanto está usando em [Uso](https://app.cubehosting.com.br/usage). Se o espaço acabar, novas gravações falham: apague o que o projeto não usa. ## Excluir o projeto Em **Configurações** › **Zona de perigo**. O projeto para, os arquivos são apagados e o endereço do site deixa de funcionar. Não dá para desfazer. # Logs e métricas Source: https://docs.cubehosting.com.br/hosting/logs-and-metrics Acompanhe a saída do seu app e da instalação ao vivo, e o uso de memória, processador e rede de cada projeto. ## Logs ao vivo A aba **Logs** do projeto mostra tudo o que o seu código escreve, em tempo real. A saída do seu app: `console.log`, `print`, erros e avisos. Mostra as últimas linhas e segue ao vivo. A saída da última instalação das dependências e do build. Fica guardada até a próxima. * **Buscar nos logs** filtra as linhas pelo texto. * **Pausar** para a rolagem para você ler com calma; **Retomar** volta ao vivo. * Dá para copiar os logs com um clique. * O status do projeto muda na hora, sem recarregar a página. Os logs são de retenção curta: ficam as linhas mais recentes, não o histórico de meses. Guarde o que for importante no seu próprio sistema. Em Python, o `print` aparece na hora porque a variável `PYTHONUNBUFFERED` já vem ligada. Em Node.js, `console.log` e `console.error` aparecem normalmente. Pela API, os logs chegam por streaming (SSE): veja [Logs do projeto](/api-reference/projects/logs). ## Métricas A **Visão geral** do projeto mostra o uso agora, em cartões fixos no topo, e gráficos ao longo do tempo: | Métrica | O que mostra | | --------------- | ------------------------------------------------------- | | **Memória** | O que o processo usa, comparado com a memória reservada | | **Processador** | O uso de CPU. 100% é um núcleo inteiro | | **Rede** | Bytes por segundo recebidos e enviados | | **Tempo no ar** | Há quanto tempo o processo está de pé sem reiniciar | Escolha a janela dos gráficos: | Janela | Detalhe | | ------------ | --------------------------- | | **15 min** | Um ponto a cada 15 segundos | | **1 hora** | Um ponto por minuto | | **24 horas** | Médias de 5 minutos | As métricas ficam guardadas por 24 horas. Pela API: [Métricas do projeto](/api-reference/projects/metrics). ## Uso e Atividade da conta A memória reservada e em uso de cada projeto, CPU e rede da última hora ou das 24 horas, o disco e os limites do seu plano. O histórico de tudo o que aconteceu na conta: envios, iniciar e parar, arquivos, variáveis (só os nomes), configurações, logins e cobrança. # Sites e APIs Source: https://docs.cubehosting.com.br/hosting/sites-and-apis Coloque um site ou API no ar com HTTPS em nome.cubehost.dev: Express, Flask, Next.js e o que mais escutar numa porta. Um projeto do tipo `site` recebe visitas pela internet. Ele ganha um endereço `https://nome.cubehost.dev`, com HTTPS automático desde o primeiro deploy. Sites e APIs são dos planos pagos, a partir do **Block**. O mínimo de memória de um site é **512 MB**. Veja os [planos](/account/plans). ## A regra de ouro: `0.0.0.0` e `PORT` O seu app precisa escutar em **`0.0.0.0`** (não em `localhost` nem `127.0.0.1`), na porta da variável de ambiente **`PORT`**. A porta vem do `port` do `cube.json` (padrão `8080`). Se o app escutar em outro endereço ou porta, o visitante vê a página **Este site não respondeu**. ## Exemplos ```js server.js theme={null} const express = require('express'); const app = express(); app.get('/', (req, res) => res.send('Olá da Cube!')); const port = Number(process.env.PORT) || 8080; app.listen(port, '0.0.0.0', () => console.log(`No ar na porta ${port}`)); ``` ```json package.json theme={null} { "name": "minha-api", "main": "server.js", "dependencies": { "express": "^4.21.0" } } ``` ```json cube.json theme={null} { "name": "Minha API", "type": "site", "language": "node", "command": "node server.js", "memoryMb": 512, "subdomain": "minha-api" } ``` Use o `gunicorn` para servir o app. Ele precisa estar no `requirements.txt`. ```python app.py theme={null} from flask import Flask app = Flask(__name__) @app.get("/") def inicio(): return "Olá da Cube!" ``` ```text requirements.txt theme={null} flask==3.0.3 gunicorn==23.0.0 ``` ```json cube.json theme={null} { "name": "Minha API", "type": "site", "language": "python", "command": "gunicorn -w 2 -b 0.0.0.0:$PORT app:app", "memoryMb": 512 } ``` O build roda sozinho, porque o `package.json` do Next.js tem o script `build`. O comando de início passa o endereço e a porta. ```json package.json theme={null} { "name": "meu-site", "scripts": { "dev": "next dev", "build": "next build", "start": "next start" }, "dependencies": { "next": "^15.0.0", "react": "^19.0.0", "react-dom": "^19.0.0" } } ``` ```json cube.json theme={null} { "name": "Meu site", "type": "site", "language": "node", "command": "npx next start -H 0.0.0.0 -p $PORT", "memoryMb": 1024 } ``` As variáveis de ambiente chegam ao app quando ele inicia, **não durante o build**. Variáveis que o Next.js embute no build (as `NEXT_PUBLIC_…`) ficam vazias. Por enquanto, coloque esses valores públicos num arquivo do projeto, como `.env.production` (nunca um segredo). ## O que o seu site ganha Todo site abre com cadeado em `https://nome.cubehost.dev`, e o certificado renova sozinho. Conexões WebSocket e respostas em streaming (SSE) passam normalmente. O cabeçalho `X-Forwarded-For` traz o IP de quem visitou, e `X-Forwarded-Proto` diz se foi `https`. O tráfego passa por uma rede de proteção antes de chegar ao seu app, e o endereço do servidor não aparece. ## Páginas que o visitante pode ver | O visitante vê | Quando | O que fazer | | --------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------- | | **Este site está parado** (503) | O projeto não está no ar | Inicie o projeto no painel | | **Este site não respondeu** (502) | O app não escuta em `0.0.0.0` na porta `PORT`, ou ainda está subindo | Confira o endereço e a porta no código e os logs | | **Este endereço não existe** (404) | Nenhum site usa esse subdomínio | Confira o endereço em **Configurações** › **Rede** | | **Este site está sobrecarregado** (503) | Conexões demais ao mesmo tempo no site | Espere alguns segundos; se for sempre assim, fale com a gente | Uma conexão que fica 100 segundos sem trocar nenhum byte é encerrada. Em WebSocket, mande um ping de tempos em tempos. ## Endereço O subdomínio vem do `cube.json`, do painel ou é gerado a partir do nome. Troque quando quiser em **Configurações** › **Rede**. Veja as regras em [Endereço e domínios](/hosting/domains). # Limites do .zip Source: https://docs.cubehosting.com.br/hosting/zip-limits Até 5 MB no Free e 10 MB nos planos pagos. As dependências são instaladas aqui, então o .zip leva só o seu código. ## Tamanho | Plano | Tamanho máximo do .zip | | ---------------- | ---------------------- | | **Free** | 5 MB | | **Planos pagos** | 10 MB | O limite vale para o envio de um projeto novo e para o [envio de código novo](/hosting/files#atualizar-o-código-com-um-novo-zip). O painel avisa antes de enviar se o arquivo passar do limite; pela API, a resposta é `413 invalid_zip` com o campo `limitMb`. Quase sempre, o que estoura o limite são as dependências. Você não precisa enviar `node_modules` nem `venv`: a Cube instala tudo a partir do `package.json` ou do `requirements.txt`. ## O que fica de fora Estas pastas são ignoradas na extração, mesmo que estejam no `.zip`: Instalada a partir do `package.json`. Criado a partir do `requirements.txt`. O histórico do repositório não é usado. Gerado pelo Python ao rodar. Sobra do "Comprimir" do macOS. Mesmo ignoradas, elas **contam no tamanho do .zip**. Tire antes de compactar: ```bash Node.js theme={null} zip -r projeto.zip . -x "node_modules/*" ".git/*" ".env" ``` ```bash Python theme={null} zip -r projeto.zip . -x "venv/*" ".venv/*" "__pycache__/*" ".git/*" ".env" ``` Não coloque o `.env` no `.zip`. Guarde tokens e senhas em [variáveis de ambiente](/hosting/environment-variables). ## O que é recusado | O .zip é recusado se | Erro | | ----------------------------------------------------------------------------------------------- | ------------- | | Não é um `.zip`, está corrompido, vazio ou tem senha | `invalid_zip` | | Tem atalhos (links simbólicos), caminhos para fora da pasta ou arquivos especiais | `unsafe_zip` | | Passa de **500 MB** ou de **20.000 arquivos** ao descompactar, ou cresce demais ao descompactar | `unsafe_zip` | Um `.zip` recusado não muda nada: num projeto que já existe, os arquivos de antes continuam lá. ## Uma pasta dentro do .zip Se você compactou a **pasta** (e não o conteúdo dela), tudo bem: quando o `.zip` tem uma única pasta no topo e nenhum `cube.json` na raiz, essa pasta vira a raiz do projeto. ## A instalação Depois de extrair, a Cube instala as dependências numa etapa separada: * **Node.js:** `npm ci` com `package-lock.json`, senão `npm install`. Depois, o build (veja a chave `build` do [`cube.json`](/cube-json)). * **Python:** `pip install -r requirements.txt` num ambiente próprio do projeto. * A instalação tem até **5 minutos** e até **1 GB** de memória, que **não** sai do seu plano. * A saída aparece em **Logs** › **Instalação**. * Num envio seguinte, se o manifesto não mudou, a instalação é pulada. # Documentação da Cube Hosting Source: https://docs.cubehosting.com.br/index Hospede bots de Discord, sites e APIs em Node.js e Python. Envie um .zip, a Cube instala as dependências e deixa no ar. A Cube Hosting roda o seu código 24 horas por dia. Você compacta o projeto em `.zip`, envia pelo painel ou pela API, e a gente instala as dependências, sobe o processo e mostra os logs ao vivo. ## Comece por aqui Do `.zip` ao bot no ar, passo a passo pelo painel. Diga a linguagem, o comando de início e a memória numa linha só. Envie, inicie, pare e leia os logs dos seus projetos por código. discord.js, discord.py e TypeScript com build automático. Express, Flask e Next.js com HTTPS em `nome.cubehost.dev`. ## O que você ganha Node.js 20, 22 e 24. Python 3.11 e 3.12. As dependências são instaladas aqui. Veja a saída do seu app e da instalação em tempo real. Nos planos pagos, o projeto reinicia sozinho se cair. Tokens e senhas fora do código, guardados cifrados. Pergunte por que o bot caiu e receba a resposta com base nos seus logs. Sem cartão e sem fidelidade. A assinatura pelo painel abre em breve. ## Como funciona Crie um `.zip` com o seu código, sem `node_modules` nem `venv`. Um `cube.json` na raiz é opcional, mas deixa tudo automático. Arraste o `.zip` em **Novo projeto** no [painel](https://app.cubehosting.com.br) ou mande pela [API](/api-reference/projects/create). O painel lê o `.zip` antes de enviar e já sugere a configuração. A Cube instala as dependências, roda o build (se houver) e inicia o processo. Os logs aparecem na hora. Tem dúvida ou achou um problema? Fale com a gente no [Discord da Cube](https://discord.gg/pv6D9tUsDV). # Primeiros passos Source: https://docs.cubehosting.com.br/quickstart Hospede um bot de Discord em 5 minutos pelo painel: do .zip ao bot no ar, com o token guardado fora do código. Neste guia você coloca um bot de Discord em Node.js no ar. O caminho é o mesmo para Python e para sites: muda só o código e o comando de início. **Você vai precisar de:** uma conta na Cube, o token do seu bot (do [Portal de Desenvolvedores do Discord](https://discord.com/developers/applications)) e o código do bot numa pasta. Abra o [painel](https://app.cubehosting.com.br) e clique em **Criar conta**. Toda conta nova começa no plano **Free**, com 100 MB de memória para 1 bot. Depois do cadastro, você cai na **Visão geral** do painel. **Projetos** e **Chaves de API** ficam na barra lateral, à esquerda. **Minha conta**, **Plano e cobrança**, **Uso** e **Atividade** ficam no menu da conta, que abre ao clicar no seu nome, no pé da barra. Um bot mínimo com [discord.js](https://discord.js.org) tem dois arquivos. O token **não** fica no código: o bot lê da variável de ambiente `TOKEN`. ```js index.js theme={null} const { Client, Events, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.once(Events.ClientReady, (c) => { console.log(`Logado como ${c.user.tag}`); }); client.login(process.env.TOKEN); ``` ```json package.json theme={null} { "name": "meu-bot", "main": "index.js", "dependencies": { "discord.js": "^14.16.0" } } ``` Não precisa enviar a pasta `node_modules`: a Cube instala as dependências do `package.json` para você. Com um `cube.json` na raiz, o painel já sabe tudo sobre o projeto. Sem ele, o painel detecta sozinho e você confere antes de enviar. ```json cube.json theme={null} { "name": "Meu bot", "language": "node", "version": "24", "command": "node index.js", "memoryMb": 100 } ``` Veja todas as chaves em [O arquivo cube.json](/cube-json). Compacte o **conteúdo** da pasta, sem `node_modules`, `.git` e o seu `.env`. ```bash macOS e Linux theme={null} cd meu-bot zip -r meu-bot.zip . -x "node_modules/*" ".git/*" ".env" ``` ```powershell Windows (PowerShell) theme={null} cd meu-bot Compress-Archive -Path index.js, package.json, cube.json -DestinationPath meu-bot.zip ``` No Free, o `.zip` pode ter até **5 MB**; nos planos pagos, até **10 MB**. Veja [Limites do .zip](/hosting/zip-limits). Em **Projetos**, clique em **Novo projeto** e arraste o `.zip` na área **Arraste o .zip aqui ou clique para escolher**. O painel lê o arquivo ali mesmo, antes de enviar, e abre a tela **Configure o projeto**: * **Ambiente detectado:** linguagem, se usa TypeScript, como instalar as dependências e o tipo sugerido (bot ou site). * **Tipo**, **Linguagem**, **Versão** e **Memória**, já preenchidos. * **Arquivo principal**, com o mais provável marcado. * **Avançado:** o comando de início e o comando de build, se quiser trocar. * **Iniciar assim que terminar**, ligado por padrão. Como o bot precisa do token para entrar, **desligue "Iniciar assim que terminar"** agora e clique em **Enviar e instalar**. O painel mostra o andamento: **Enviando**, **Instalando** e **Pronto**. Abra o projeto e vá em **Configurações** › **Variáveis**. Adicione a variável `TOKEN` com o token do bot e salve. O valor fica cifrado e nunca mais aparece no painel. Se você tiver um arquivo `.env`, use **Importar .env** para colar tudo de uma vez. Clique em **Iniciar**. O status muda para **No ar** e, na aba **Logs**, em **Aplicação**, aparece a linha: ```text theme={null} Logado como MeuBot#1234 ``` Pronto, o bot está no ar. ## E se algo der errado? Abra **Logs** › **Instalação**. Lá aparece a saída do `npm install` ou do `pip install`. Na maioria das vezes é uma dependência com nome errado ou uma versão da linguagem diferente da que o projeto pede. Abra **Logs** › **Aplicação** e procure a última mensagem de erro. Token ausente ou errado é o motivo mais comum: confira a variável `TOKEN` em **Configurações** › **Variáveis**. Você também pode clicar em **Por que caiu?** e [Cube AI](/cube-ai) explica com base nos seus logs. A soma da memória de todos os seus projetos não pode passar a do plano. Diminua a memória de outro projeto ou veja os [planos](/account/plans). ## Próximos passos TypeScript, Python e dicas para bots maiores. Faça o mesmo deploy com um comando, do seu computador ou do CI. # Segurança e isolamento Source: https://docs.cubehosting.com.br/security Cada projeto roda separado dos outros clientes, com a memória e a CPU do plano como teto. Veja o que protege o seu código e o que o seu projeto pode fazer. > Seu projeto roda separado de todos os outros. Se um vizinho tiver problema, o seu continua no ar. ## Isolamento entre clientes Cada projeto roda isolado, sem acesso ao servidor nem aos arquivos de outros projetos. O processo roda sem privilégios de administrador. O limite do plano vale para cada conta. Um projeto que passa da própria memória é encerrado sozinho, sem afetar os vizinhos. Projetos de outras contas não alcançam os seus. Nenhum projeto alcança a rede interna do servidor. Sites recebem visitas só pelo endereço HTTPS, atrás de uma rede de proteção que filtra ataques. O endereço do servidor não aparece. ## O seu código e os seus arquivos * **A instalação também é isolada.** `npm install` e `pip install` rodam scripts dos pacotes, então rodam na mesma caixa do projeto, e **sem as suas variáveis de ambiente**. * **O `.zip` é conferido.** Atalhos, caminhos para fora da pasta e arquivos que crescem demais ao descompactar são recusados (`unsafe_zip`). * **Os arquivos só são abertos dentro do espaço do projeto**, inclusive pelo explorador do painel. * **Download por link temporário.** O link de download vale 5 minutos e só para a sua conta. * **Variáveis cifradas.** Os valores nunca voltam depois de salvos. Veja [Variáveis de ambiente](/hosting/environment-variables). ## Acesso à sua conta * Toda ação confere se o projeto é seu. Um ID de outra conta recebe a mesma resposta de um ID que não existe (`not_found`). * [Verificação em duas etapas](/account/security), sessões que você pode encerrar e histórico de segurança. * [Chaves de API](/api-reference/introduction#autenticação) com permissão de leitura ou de leitura e escrita, revogáveis na hora. Chaves erradas seguidas do mesmo IP ficam barradas por 15 minutos; a chave certa continua passando. * Subdomínios que lembram bancos, marcas e órgãos públicos são bloqueados, para evitar golpes com o nome de outros. ## O que o seu projeto pode fazer | Pode | Não pode | | ------------------------------------------------ | ------------------------------------------------------------------------------------------- | | Conectar ao Discord e a qualquer API na internet | Enviar e-mail direto por SMTP (portas 25, 465 e 587). Use um serviço de e-mail com API HTTP | | Gravar arquivos na pasta do projeto e em `/tmp` | Gravar fora desses lugares | | Receber visitas por HTTPS (sites) | Abrir portas próprias para a internet | | Usar a CPU e a memória do plano | Passar do teto da memória do projeto | Mineração, spam, phishing, selfbot e raid são proibidos pela Política de Uso Aceitável e levam à suspensão da conta. Achou uma falha de segurança? Conte para a gente em particular no [Discord da Cube](https://discord.gg/pv6D9tUsDV), antes de divulgar.