# Devora Cloud — manual de operação Plataforma de hospedagem de aplicações. Este arquivo é a documentação completa em texto puro. Versão em página: https://devoracloud.com/docs Se você é um agente preparando o código de uma aplicação para rodar aqui, a seção que importa é "PREPARAR UMA APLICAÇÃO" — cada regra traz a consequência real de ignorá-la. ## Como as coisas se organizam Uma organização é a conta. Dentro dela ficam os projetos, e é o projeto que você abre para trabalhar. Dentro do projeto ficam os serviços — os programas que rodam —, os endereços por onde eles respondem, as variáveis de ambiente e, opcionalmente, um banco de dados. Um repositório com um site e uma API vira UM projeto com dois serviços, não dois projetos. As aplicações rodam distribuídas entre as máquinas do cluster. Os bancos ficam num servidor separado, dedicado só a eles, alcançável pela rede privada. ## Publicar uma aplicação do GitHub 1. Conecte o GitHub — Uma vez por conta. A lista de repositórios se atualiza sozinha sempre que você abre a tela, e também quando você adiciona ou remove um repositório da instalação lá no GitHub. 2. Escolha o repositório — A plataforma lê os arquivos dele e sugere o construtor, a porta e o banco que ele parece precisar. Confira a sugestão — ela acerta na maioria dos casos, não em todos. 3. Confirme a porta — É o erro mais comum. Se o app escuta em outra coisa que não a 3000, diga aqui. Endereço apontando para a porta errada responde 502 com o app perfeitamente saudável por trás. 4. Publique — A primeira construção leva alguns minutos: o código é clonado, a imagem é montada e enviada ao registro interno, e só então o serviço sobe. O projeto nasce com um endereço gratuito em .apps.devoracloud.com, já com HTTPS. Ele serve para testar antes de apontar o domínio de verdade. Repositório com vários programas dentro (monorepo) precisa dizer qual Dockerfile usar — apps/web/Dockerfile, por exemplo. O contexto da construção continua sendo a raiz, então o lockfile compartilhado é encontrado normalmente. Para publicar o segundo programa, acrescente um serviço ao mesmo projeto em vez de criar outro. ## Vários serviços no mesmo projeto Um produto costuma ter mais de um programa: o site que o cliente abre e a API que responde por trás. Os dois vivem no mesmo repositório, cada um com seu Dockerfile e sua porta. Eles ficam no MESMO projeto, como serviços. O serviço novo herda o repositório e a branch do principal — muda só o caminho do Dockerfile e a porta. As variáveis do projeto valem para todos os serviços. É o que importa na prática: o segredo que assina o token no site e é conferido pela API fica gravado uma vez, no projeto, e os dois enxergam. Variável que precisa ser só de um serviço também é possível. O serviço principal é o que responde pelo endereço do projeto. Ele não pode ser removido — removê-lo é excluir o projeto. ## Banco de dados Dentro do projeto, o botão de adicionar cria um banco. Estão disponíveis PostgreSQL, MySQL, MariaDB, MongoDB e Redis. Assim que o banco fica de pé, a variável de conexão é injetada na aplicação automaticamente — DATABASE_URL para os relacionais, REDIS_URL para o Redis. Você não copia nem cola nada. Por padrão o banco só é alcançável pela rede privada. Abrir o acesso público publica uma porta dedicada, protegida por firewall; use quando precisar conectar de um cliente SQL na sua máquina, e feche depois. ATENÇÃO — Antes de excluir: Excluir um banco apaga os dados de forma definitiva. Não existe cópia automática para restaurar depois. Tire seu próprio dump antes. ## Domínio próprio 1. Um registro TXT — Em _devora-verify.seudominio.com, com o valor que a tela mostra. É a prova de que o domínio é seu. 2. Um CNAME — Apontando para o endereço que a tela indica — o subdomínio do próprio projeto, não a zona genérica. Provou uma vez, provou a zona inteira: se exemplo.com já foi verificado na sua conta, então app.exemplo.com e painel.exemplo.com entram já verificados, sem TXT novo. O certificado HTTPS é emitido automaticamente assim que o DNS aponta para cá. Cada endereço tem a sua própria porta: dá para o site responder na 3000 e o painel na 8787 dentro do mesmo projeto. ATENÇÃO — A ordem importa: Aponte o DNS antes de esperar o certificado. Enquanto o domínio resolver para outro servidor, a emissão falha — e cinco falhas seguidas bloqueiam aquele domínio por uma hora na autoridade certificadora. ## Réplicas e escala automática Um projeto pode rodar em várias cópias, espalhadas entre as máquinas. Com a escala automática ligada, a plataforma sobe e desce a quantidade conforme o uso de CPU, dentro do mínimo e do máximo que você definir. Isso funciona bem para aplicação sem estado. Em três casos, mais de uma cópia causa perda de dado silenciosa — sem erro em log nenhum. Neles, deixe a escala automática desligada e a quantidade fixa em 1: - O app guarda estado em memória e grava o conjunto inteiro de volta. A última cópia a escrever apaga o que as outras fizeram. - O app tem um agendador embutido (cobrança, sincronização, bloqueio por inadimplência). Duas cópias executam a rotina duas vezes. - O app usa volume em disco. O volume é local da máquina — cada cópia enxerga uma pasta diferente, e uma remarcação de tarefa sobe com a pasta vazia. ## Deploy automático por push Com o GitHub conectado, todo push na branch configurada dispara uma publicação nova. Não precisa clicar em nada. A publicação aparece marcada como via GitHub, com o commit que a originou. Se o build falhar, a versão anterior continua no ar — a nova só substitui a antiga depois de subir. A branch é a que o projeto declara. Repositório que usa master em vez de main funciona igual, desde que esteja escrito corretamente nas configurações. ## PREPARAR UMA APLICAÇÃO Regras que separam um app que sobe de primeira de um que sobe quebrado. A linha "SE IGNORAR" descreve a falha concreta, observada em produção. ### Leia a porta de process.env.PORT Não fixe a porta no código. Escute em 0.0.0.0, nunca em localhost. SE IGNORAR: O roteador entrega na porta declarada e ninguém atende. O visitante recebe 502 com o container saudável. ### Rode as migrações na inicialização, não na construção Um migrate deploy antes de subir o servidor. Durante a construção da imagem não existe banco para conectar. SE IGNORAR: O banco fica com zero tabelas e o app responde erro na primeira consulta. Foi o defeito mais comum nas migrações reais. ### Falhe alto quando a migração falhar Se o migrate der erro, o processo deve morrer com a mensagem no log — não subir mesmo assim. SE IGNORAR: O app fica no ar servindo erro, o painel mostra verde, e ninguém descobre até um cliente reclamar. ### Variáveis NEXT_PUBLIC_* são argumentos de construção No Next.js elas são gravadas dentro do pacote durante o build. Declare cada uma como ARG e promova a ENV antes da linha que constrói. SE IGNORAR: O valor de desenvolvimento fica embutido para sempre. A API de produção continua apontando para localhost. ### Nada importante no disco do container Upload, imagem, anexo: mande para o armazenamento S3. Disco de container some quando a cópia é recriada. SE IGNORAR: Os arquivos desaparecem no próximo deploy, sem aviso e sem como recuperar. ### Não guarde estado só na memória do processo Sessão, fila, cache compartilhado: coloque no banco ou no Redis. Com mais de uma cópia, cada processo tem a sua memória. SE IGNORAR: O usuário perde a sessão a cada requisição que cai noutra cópia, e escritas somem sem erro nenhum. ### Um agendador embutido exige uma cópia só Se o app tem cron interno, diga isso a quem for publicar. A alternativa é mover a rotina para um serviço próprio. SE IGNORAR: Cobrança em duplicidade, mensagem enviada duas vezes, cliente bloqueado por engano. ### Responda algo em / Qualquer resposta abaixo de 500 serve — inclusive um redirecionamento para o login. É por aí que a plataforma sabe que o app está vivo. SE IGNORAR: O app é considerado fora do ar e o dono recebe aviso de queda que não existe. ### Log no stdout, sem arquivo Escreva na saída padrão. Não abra arquivo de log dentro do container. SE IGNORAR: O log fica preso num disco que ninguém alcança, exatamente quando você precisa dele. ### Todo segredo vem do ambiente Chave de API, segredo de token, credencial de terceiro: só de variável de ambiente. Nunca comitado, nunca com valor padrão que funcione. SE IGNORAR: O segredo vaza no repositório e passa a valer para qualquer um que clone o código. ### Monorepo: um serviço por programa, no mesmo projeto Site e API do mesmo repositório entram como dois serviços do mesmo projeto, cada um com seu Dockerfile e sua porta. Não crie dois projetos. SE IGNORAR: Com dois projetos, os segredos precisam ser copiados de um para o outro na mão — e no dia em que um for trocado e o outro não, o token deixa de ser aceito e ninguém entende por quê. ### Dockerfile: diga o caminho, mantenha o contexto na raiz Em monorepo, informe o caminho completo do Dockerfile do serviço. O contexto continua na raiz para achar o lockfile compartilhado. SE IGNORAR: A construção morre com "open Dockerfile: no such file or directory" num repositório que tem Dockerfile. ## O QUE A PLATAFORMA AINDA NÃO FAZ Não conte com estes recursos; eles não existem hoje: - Backup automático de banco. Não há motor de cópia rodando. Se os dados importam, tire seu próprio dump. - Terminal SQL e troca de senha do banco. Dá para ver as credenciais, não para alterá-las pelo painel. - Alerta de infraestrutura por e-mail. Queda de aplicação avisa por e-mail; disco enchendo, ainda não. ## API Base: https://api.devoracloud.com/v1 Autenticação: header Authorization: Bearer , mais X-Devora-Org: A chave completa é exibida uma única vez, na criação.