O que há de novo
Cada funcionalidade, correção e melhoria entregue no sh0. 29 fases, 2 auditorias de segurança, mais de 90 sessões de engenharia — construído do zero em Rust.
Cada entrada é uma versão publicada. Os binários e as somas de verificação estão no GitHub Releases; versões candidatas não aparecem aqui.
v1.10.14: uma aba Ambiente que mostra o que cada contêiner recebe, hooks de implantação em todos os caminhos, limites por serviço
A aba Ambiente mostra cada variável que um contêiner recebe e a sua origem, os hooks de implantação são executados em todos os caminhos de implantação, e os limites de memória e CPU aplicam-se por serviço de uma pilha.
Endpoints API
Ferramentas MCP
Testes passando
Templates de deploy
Linha do tempo de desenvolvimento
Do primeiro commit até pronto para produção — o histórico completo de construção
v1.10.14: uma aba Ambiente que mostra o que cada contêiner recebe, hooks de implantação em todos os caminhos, limites por serviço
- Mudança de comportamento: as variáveis partilhadas de uma pilha agora só chegam às suas apps e ao serviço exposto de cada app de modelo ou Compose; um serviço oculto (postgres, redis…) já não as recebe. Para lhe dar um valor, defina-o na app com o nome prefixado do serviço, tal como a aba Ambiente o mostra (por exemplo POSTGRES_POSTGRES_PASSWORD). Os contêineres em execução mantêm o seu ambiente até à próxima reimplantação.
- Aba Ambiente: uma linha por variável recebida pelo contêiner, com a sua origem (Modelo, Pilha, App, Serviço) e os valores substituídos riscados; um aviso «Alterações não aplicadas» com um botão Reimplantar até o contêiner usar os valores guardados; o editor .env assinala chaves inválidas e duplicadas, mostra as chaves adicionadas, alteradas e removidas antes de gravar, e importa por fusão ou substituição.
- Hooks de implantação: os hooks de pré e pós-implantação agora são executados em todos os caminhos — Git, Dockerfile, envio de arquivo, imagem Docker e pilhas —, quando antes só as implantações Git os executavam. A aba Hooks guarda cada execução com o código de saída, a duração, a saída e a data, e um botão Testar executa um hook a pedido.
- Recursos e equipas: um limite de memória ou CPU definido num serviço de uma pilha agora aplica-se a esse serviço, limitado ao host; a aba Escalonamento mostra o limite configurado ao lado do limite em vigor. O cabeçalho de cada pilha mostra o número de membros, a um clique da secção Membros.
- Fiabilidade: uma app que parou já não aparece como «Falhou»; o sh0 executado num contêiner junta-se sozinho à rede sh0-net no arranque, e o `sh0 doctor` verifica-o; a criação interativa da conta de proprietário exige pelo menos 8 caracteres, como a API.
v1.10.13: as variáveis dos modelos chegam aos seus contêineres, «Também no build», reversão a partir de uma release candidate
- Variáveis de ambiente: as variáveis de uma aplicação implantada a partir de um modelo ou de um arquivo Compose agora chegam aos seus contêineres; eram gravadas, mas nunca transmitidas. Uma nova implantação já não sobrescreve um valor gerado que você alterou. Uma variável adicionada ou alterada enquanto um serviço está em execução chega a ele na implantação seguinte.
- Mudança de comportamento: a caixa «Build» passa a ser «Também no build». Toda variável está agora disponível no contêiner em execução; marcada, ela também é passada à construção da imagem. Uma variável que você tinha marcado para mantê-la fora do contêiner em execução agora aparece nele: exclua-a se isso importar.
- Atualizações e desinstalação: `sh0 update --rollback` agora volta atrás a partir de uma release candidate, e o guardião de atualização automática a reconhece; `sh0 destroy` já não encerra o shell que o iniciou.
- E-mail e painel: o estado do relay de saída é lido no servidor de e-mail em vez de ser presumido; `sh0 panel-domain set` recusa expor um painel restrito ao túnel SSH, a menos que se passe `--force`.
- Modelos e dependências: os modelos `ollama` e `localai` recebem agora 4 GB e 4 núcleos (com 1 GB e 1 núcleo, um modelo de 3B não carregava); seis avisos de segurança em dependências de TLS, criptografia e compressão foram corrigidos.
v1.10.12: segredos de autenticação em dois fatores cifrados em repouso, backups remotos cifrados por padrão, verificação da porta 25 de saída
- Autenticação em dois fatores: os segredos TOTP agora são cifrados em repouso com a chave mestra da instância e selados automaticamente na primeira inicialização da 1.10.12. O binário anterior não consegue desfazer esta migração (092): para voltar atrás, use `sh0 update --rollback`, que restaura a cópia do banco de dados feita durante a atualização e descarta o que foi gravado desde então. Recolocar manualmente o binário anterior, sem essa cópia, quebra o login com dois fatores de todas as contas.
- Backups: os backups manuais e agendados enviados ao S3 ou R2 agora são cifrados por padrão; os backups locais não mudam e um `encrypt: false` explícito é respeitado. Exporte já a chave mestra (`sh0 doctor` e a página Segurança mostram o comando): sem ela, um backup cifrado se perde junto com o servidor.
- E-mail: `sh0 doctor`, a página E-mail e um novo cartão do relay de saída verificam se a porta 25 de saída está aberta, bloqueada pelo provedor ou contornada por um relay (a verificação precisa do `dig`). O servidor de e-mail ganha sua própria rede de pilha dupla: o e-mail recebido por IPv6 mantém o endereço real do remetente, o e-mail de saída sai por IPv4 e as caixas de correio são registradas antes e depois da recriação da instância de e-mail.
- Endurecimento: o diretório de dados fica restrito a 0700, de modo que a chave mestra e as cópias do banco de dados não podem mais ser listadas por outros usuários locais; `sh0 doctor` indica um domínio do painel servido no modo "somente túnel"; a página Segurança ganha uma seção "Acesso ao painel" (somente túnel SSH, aplicativos por túnel, SSH atrás de uma VPN).
- Problemas conhecidos, com correção prevista na 1.10.13: `sh0 update --rollback` se recusa a voltar de uma versão candidata; `sh0 destroy` encerra o shell que o iniciou (execute-o com `setsid`); o status do relay de saída mostra "aplicado" sem consultar o servidor de e-mail.
v1.10.11: gêmeo www para cada domínio, webhook do GitHub criado pelo sh0, página Domínios e SSL
- Gêmeo www: ao adicionar um domínio, o equivalente www é proposto (marcado por padrão) e os dois nomes são criados com um redirecionamento 301 do gêmeo para o nome digitado, ou o inverso com «Adicionar e redirecionar». Um aviso no aplicativo e na stack lista os domínios cujo gêmeo falta. Dois defeitos antigos corrigidos no caminho: os redirecionamentos dos aplicativos são restaurados quando o sh0 reinicia (uma atualização os apagava do Caddy), e excluir o último redirecionamento de um aplicativo deixa realmente de servi-lo.
- Implantação automática: ativar a implantação Git automática de um repositório GitHub agora cria o webhook no GitHub, com o token do aplicativo ou o provedor GitHub, e o remove quando ela é desativada ou o aplicativo é excluído. Enquanto nenhuma entrega tiver provado o webhook, o sh0 consulta o branch a cada 150 segundos; a primeira consulta apenas registra o commit atual, e só um commit enviado depois implanta. As entregas (aceitas, ignoradas, recusadas) e o estado de sincronização aparecem sob o interruptor. GitLab, Gitea e Bitbucket usam a mesma consulta de reserva, com o webhook ainda adicionado à mão.
- Domínios e SSL: a página da stack tem título, plural e filtros traduzidos, e um botão «Adicionar domínio» que leva direto ao aplicativo certo. Os links das ferramentas da stack não levam mais a uma página de Armazenamento inexistente, e o salto para uma instância só acontece se ela estiver em execução.
- sh0 Manager: o QR code de pareamento agora traz o domínio do painel, ou o seu endereço *.sh0.app, e um servidor sem endereço público recebe uma recusa clara e traduzida em vez de um código que o telefone não consegue alcançar.
- Voltar manualmente a uma versão anterior: execute primeiro `UPDATE redirects SET is_enabled=0 WHERE host IS NOT NULL` no sh0.db; caso contrário, o binário antigo aplica o redirecionamento www a todos os nomes do aplicativo e entra em loop.
v1.10.10: serviço confinado, registro por IPv6, HTTPS antes da primeira conta
- Confinamento: o instalador grava um drop-in do systemd que deixa /usr e /boot somente leitura para o sh0 e o Caddy, mantendo /usr/local gravável para as atualizações do binário e do Caddy, e /etc, /root e /home graváveis para o gerenciador de arquivos do host. O terminal de host do painel é executado fora desse confinamento.
- *.sh0.app em pilha dupla: numa máquina com IPv4 e IPv6, o registro saía por IPv6 anunciando o endereço IPv4, e o proxy na nuvem o recusava. O sh0 agora se registra a partir do endereço que anuncia, e `sh0 doctor` só informa a via em HTTP simples depois que o proxy aceita o registro.
- HTTPS antes da primeira conta: `sh0 panel-domain set <domínio>` agora funciona antes de existir a conta de proprietário, e a primeira senha não precisa mais atravessar a rede em texto claro.
- Terminal de host: o shell aberto pelo terminal do painel não sobrevive mais à parada do sh0 como um shell root órfão.
- Desinstalação: `sh0 destroy` agora remove as imagens construídas a partir de um arquivo enviado, e vai até o fim quando é iniciado pelo terminal do painel.
v1.10.9: aba Tráfego, erros traduzidos, segredos protegidos
- Tráfego: uma nova aba Tráfego em cada aplicação, baseada no log de acesso do Caddy, com agregados por hora e por dia de requisições, códigos de status e largura de banda; nenhum endereço IP é armazenado; disponível também via GET /apps/:id/traffic e pela ferramenta MCP get_app_traffic.
- Erros traduzidos: todas as recusas do servidor agora são traduzidas para os cinco idiomas do painel (nós, escalonamento, armazenamento de arquivos, e-mail, transferência de projetos, serviços, sandbox, provedores de armazenamento, funções, tempo real e mais); um erro «não encontrado» indica o tipo de recurso ausente.
- Segurança: as credenciais incluídas na URL de um endpoint de armazenamento (usuário e senha de um serviço compatível com S3) são mascaradas em todos os lugares onde são exibidas ou registradas; a biblioteca TLS é atualizada para rustls 0.23.46, que corrige quatro avisos publicados em 14 de outubro.
- Avaliações: o convite para deixar uma avaliação aparece 24 horas após sua primeira implantação bem-sucedida, sem estrelas pré-preenchidas, com um link permanente no menu do usuário.
v1.10.8: implantações Python, serviço de e-mail, redesenho dos stacks
- Implantações Python: um projeto Python genérico sem dependências é construído; gunicorn ou uvicorn só são adicionados se o projeto ainda não fornecer um; a aplicação corre com o uid 1000 e é dona do seu HOME; o erro de porta indica cada linha EXPOSE quando há várias; o registo de falha já não repete as linhas já transmitidas.
- Serviço de e-mail: uma única instância Stalwart por servidor, nas portas públicas 25, 465, 587, 993 e 995, que apresenta os certificados do Caddy em SMTP e IMAP; relay de saída; o webmail vê o endereço real do cliente através do protocolo PROXY v2; as rotas do webmail são reconstruídas no arranque e /admin é devolvido ao Stalwart; os contentores de e-mail órfãos são removidos.
- Cópias de segurança S3: o restauro a partir de um destino externo, a transferência e a eliminação de uma cópia usam agora o fornecedor registado nessa cópia, e não o predefinido.
- Stacks: a lista de stacks e a página de um stack foram redesenhadas; a ordem de arranque dos serviços de um stack pode ser reordenada; o runtime detetado é mantido desde a primeira análise.
- Painel: o registo de auditoria passa a ser uma tabela de largura total com filtros por período, ação e pesquisa, e as falhas de início de sessão são registadas; mais recusas do servidor são traduzidas (bases de dados, projetos, montagens, funções); «Reportar um erro» passa para o menu do utilizador; a página «Como funciona» é atualizada.
v1.10.7: endereçamento S3 corrigido e seguimento da auditoria
- Mudança de comportamento, destinos de cópia de segurança S3: antes da 1.10.7 a definição «Path style» era aplicada ao contrário, o que fazia falhar o teste de ligação dos destinos MinIO e «S3 genérico» criados no painel. Agora faz o que diz, e MinIO e S3 genérico usam sempre path style, pelo que os que funcionavam continuam a funcionar. AWS S3, Cloudflare R2, DigitalOcean Spaces, Backblaze B2, Wasabi e Hetzner Object Storage mudam de endereçamento na atualização (por omissão: estilo virtual-hosted, aceite pelos seis). Para recuperar o comportamento anterior: Definições > Armazenamento, editar o destino, inverter «Path style», guardar e executar «Testar ligação».
- Segurança, segredos e acesso (auditoria independente de 5 de outubro de 2026): os segredos das bases de dados e das chaves de API já não são devolvidos em claro a funções que não os devem ver; a pertença é verificada nas bases geridas; os códigos de recuperação são de utilização única, mesmo com pedidos em paralelo.
- Segurança, atualizações e transporte: a atualização automática e o instalador verificam uma assinatura minisign das somas de verificação da versão; um token git já não é enviado para um anfitrião que se faça passar pelo fornecedor; a repetição de webhooks git é recusada; os tokens WebSocket já não passam no URL; a API de administração do Caddy já não está exposta em TCP.
- Segurança, modelos e IA: os modelos Redis, Valkey, KeyDB e Dragonfly arrancam com palavra-passe; as ferramentas MCP sensíveis exigem confirmação.
- Armazenamento e bases de dados: o MinIO funciona como fornecedor de armazenamento S3; editar um fornecedor já não substitui os segredos nem a configuração guardados; o contador de objetos foi corrigido; o acesso externo a um servidor de bases de dados funciona com um Caddy de origem e a sua expiração é aplicada; «Adicionar base de dados» funciona a partir de uma pilha.
- Implementações e domínios: o domínio de uma aplicação obtém o certificado sem esperar por uma primeira visita; uma imagem pode ser implementada pelo seu digest `@sha256`; o domínio principal pode ser alterado.
- CLI e painel: `sh0 update` reinicia o serviço; `sh0 uninstall` deixa menos restos; os estados, as datas e as notificações estão traduzidos; o cabeçalho da pilha e a paginação cabem a 390 px; a CLI já não imprime uma linha de registo a mais.
v1.10.4: reforço de segurança após a abertura
- Domínio do painel reservado: nenhuma aplicação pode reclamar o domínio do painel nem o seu endereço `*.sh0.app`; o cookie de sessão de um administrador nunca é enviado ao contentor de terceiros.
- Redirecionamentos: destinos e caminhos recusam `undefined`, que o proxy expandiria em segredos do servidor ou conteúdo de ficheiros; as regras existentes são escapadas ao gerar a configuração.
- Primeiro proprietário sob token: `/auth/setup` e o início de sessão com Google exigem o token de instalação num servidor novo; o instalador mostra `sudo sh0 setup-token` em vez de deixar o painel ao primeiro visitante.
- Terminal alojado e WebSockets: um cookie de sessão só é aceite se o pedido vier da origem do painel; os tokens de API não mudam.
- Restaurar uma cópia a partir de um caminho do servidor fica reservado a owners e admins; a lista de domínios só mostra os seus projetos; um volume cujo nome poderia pertencer a outra aplicação é recusado em vez de montado.
- Instalador e higiene: o instalador recusa instalar um binário que não consegue verificar com SHA-256; as chaves TLS importadas são escritas em 0600; um registo de build já não dispara uma sincronização de relógio; as respostas do assistente de IA são saneadas antes de exibidas; os créditos de IA são reservados por pedido, pelo que chamadas paralelas não deixam uma carteira a descoberto.
v1.10.3: atualizações que mantêm seus aplicativos no ar
- Atualizações automáticas com reversão: o sh0 se atualiza no horário escolhido, verifica a nova versão e restaura juntos o binário e o banco se ela não subir. Seus aplicativos continuam respondendo durante a atualização — 0 erros em 378 requisições medidas.
- Pilhas de modelos e Compose podem ser reimplantadas e atualizadas. O sh0 agora guarda a pilha resolvida, criptografada: senhas e volumes permanecem os mesmos, e uma nova imagem ou um novo arquivo Compose é mostrado antes de ser aplicado.
- O Pro agora inclui stacks ilimitados; o plano Scale não é mais vendido e as licenças Scale existentes continuam funcionando.
- Segurança: uma página Segurança do servidor mostra ao vivo as verificações de host do `sh0 doctor`; o instalador pode reforçar o servidor (`--harden`); uma sessão revogada continua revogada; o IP do cliente só é lido atrás de proxies confiáveis; as prévias têm sua própria rede; arquivos, volumes e métricas não cruzam mais a fronteira entre projetos.
- Implantar sem Git: uma URL de implantação dispara uma implantação sem provedor Git nem chave de API; o domínio principal pode ser escolhido; um backup pode ser restaurado em teste num contêiner descartável.
- Relatórios de bug pelo painel com uma prévia exata do que é enviado, e estatísticas de uso opcionais, desativadas por padrão.
v1.10.2: chaves de API que fazem o que dizem
- As chaves de API finalmente fazem o que o seu âmbito diz. Até agora o âmbito só era aplicado pelo MCP: pela API REST, uma chave `read` herdava todos os direitos do seu dono, até criar e excluir aplicações. Três níveis aplicam-se agora em todo o lado: `read` (apenas consultar), `deploy` (fazer deploy, reverter, reiniciar, iniciar, parar e escalar aplicações existentes) e `admin` (todo o resto). Uma data de expiração ilegível é recusada em vez de tornar a chave eterna, e o tela Chaves API mostra o nível, a expiração e o prefixo de cada chave. As chaves `standard` existentes passam a ser chaves `deploy`: se alguma das suas cria aplicações, substitua-a por uma chave `admin`.
- O sandbox e os registros verificam quem está pedindo. As rotas REST do sandbox não tinham qualquer autorização — um `developer` podia executar comandos como root no sandbox compartilhado — e as ferramentas MCP de registros e de sandbox não verificavam o acesso ao projeto. Ambas recusam agora o que o seu papel não permite.
- As suas aplicações mantêm os seus próprios cabeçalhos. As aplicações servidas em `*.sh0.app` recebiam a política de segurança do painel (CSP, `X-Frame-Options: DENY`, CORS), o que quebrava qualquer aplicação que carregue um CDN ou seja feita para ser incorporada. As dependências com avisos RustSec também foram atualizadas: de 21 avisos para 8, `tar` incluído.
- Nós remotos no dia a dia: as réplicas são criadas no nó e não no servidor local, métricas e escalonamento automático funcionam, as tarefas cron rodam no nó e não no host do sh0, um nó inacessível na inicialização é tentado de novo, um nó que recusa o reencaminhamento SSH é identificado em vez de ser tentado sem fim, e `*.sh0.app` serve todas as réplicas.
- O registro de auditoria pode ser exportado, em CSV ou JSON.
- E o resto: o MinIO do sistema usa uma imagem fixada por digest e substituível com `SH0_MINIO_IMAGE`; um modelo baseado em uma imagem congelada ou comunitária avisa antes do deploy; `sh0 update` reinicia o serviço em vez de deixar a versão anterior rodando em silêncio, e `sh0 uninstall` indica o que deixa para trás; datas e horas seguem o idioma da interface; o catálogo de deploy existe agora também em espanhol, português e suaíli.
v1.10.1: o push git faz deploy e as suas credenciais ficam fora do disco
- As suas credenciais ficam onde devem. O token de um repositório HTTPS já não é escrito em claro no `.git/config` do clone em cache, e as exportações de configuração já não copiam o endereço de um repositório com as credenciais lá dentro. As chaves de host SSH são verificadas pelo próprio sh0, e uma falha SSH agora diz qual é.
- Um push git volta a fazer deploy. O segredo do webhook é definido na criação da aplicação, a sua página ganha uma seção de deploy Git e o deploy automático é uma caixa visível.
- Convidar um colega ou recuperar uma conta é feito por um link de uso único. Uma conta Google pode ser vinculada pelo perfil, e as recusas do servidor chegam no seu idioma.
- Fazer deploy do seu próprio código: os cartões de linguagem aceitam um arquivo, o campo da porta começa vazio e, se o deixar vazio, o sh0 adota a única porta em que a sua aplicação realmente escuta. Uma porta fora do intervalo é recusada antes do deploy, a via de arquivo tem o seu relatório de saúde e as respostas da API são comprimidas.
- O painel fala o seu idioma: as datas seguem o idioma da interface, gatilhos e mensagens estão traduzidos e o catálogo de deploy está em francês. O registro de auditoria é visível em todos os planos e não apenas no Business, e as funcionalidades Pro passam a ser reservadas pelo servidor, não só pelo navegador.
v1.10.0: a porta que você escolhe chega à sua aplicação
- A porta que você digita agora chega à sua aplicação. Um formulário de implantação preenchido com 80 fazia todas as aplicações declararem uma porta explícita, o que neutralizava de uma vez duas correções já entregues: o valor chegava ao `EXPOSE`, à porta publicada e à sonda de saúde, mas nunca ao processo. O campo agora começa vazio nos quatro caminhos — envio de arquivo, git, Dockerfile, imagem Docker —, doze modelos a mais escrevem `ENV PORT`, os modelos Java escrevem `ENV SERVER_PORT` para o Spring Boot, e quando você não diz nada é o `EXPOSE` da imagem que decide.
- Uma sonda de saúde que falha nomeia a porta realmente aberta: “Nothing answers on port 3000; the container listens on 9091”. Um Dockerfile que não declara nenhum `EXPOSE` diz para qual porta recorreu, em vez de fazê-lo em silêncio, e uma porta que contradiz o `EXPOSE` da imagem é sinalizada antes da implantação, não depois.
- O segundo fator ganha uma rede de proteção e uma memória. Os códigos de recuperação sobrevivem ao recarregamento do perfil que os apagava, podem ser regenerados pelo painel mediante um código novo do autenticador, e cada acesso protegido — por senha ou pelo Google — grava uma linha datada no registro de auditoria, recusas incluídas.
- O peso. Um visitante baixa um idioma em vez de cinco, e os recursos estáticos são armazenados em cache, revalidados por ETag e pré-comprimidos em brotli e gzip. A página de acesso passou de 1106 KB para 168 KB na primeira visita, e para 763 bytes na seguinte.
- A ligação com a nuvem passa a ser própria de cada instância. Cada instalação carrega agora a sua credencial e um canal cifrado até o proxy, em vez de uma chave partilhada por todos, e o painel pode mudar-se para um domínio seu — anunciado no painel, com o endereço antigo nomeado no momento em que deixa de responder.
- E o resto: onze laços de falha em modelos lidos e classificados — oito corrigidos, dois retirados —, um nome de host de serviço que já não serve o conteúdo do contêiner principal, uma troca de senha que revoga de verdade as outras sessões, e as origens do Google Identity autorizadas pela política de segurança de conteúdo. Cada correção aqui carrega uma observação datada em uma máquina real; o contador de “corrigido no código, nunca visto funcionar” continua em zero.
v1.9.0: um domínio para o painel, e falhas que se distinguem
- O painel recebe um caminho de adoção para o seu próprio domínio. Defini-lo ou removê-lo nomeia o endereço que vai deixar de responder, uma remoção que falha aparece em vermelho em vez de um falso sucesso, e a troca só é oferecida quando o certificado já está ativo.
- Três falhas diferentes do proxy devolviam o mesmo 404. Agora devolvem três códigos distintos, e um domínio conhecido cujo destino está ausente já não se declara desconhecido.
- Os três selos de estado do painel falam o idioma do painel, em vez de responder sempre em inglês.
- O documento OpenAPI anuncia a versão do binário que realmente o serve, em vez de um número fixado no código.
v1.8.0: projetos multisserviço, backup da instância, atualização autônoma
- Os serviços de um projeto se alcançam pelo nome. Um alias interno estável (`<app>.internal`) acompanha o contêiner quando seu endereço muda: ao reimplantar, o IP passa de 172.20.0.4 para 172.20.0.5, o nome continua respondendo e nenhuma URL precisa ser editada. Variáveis compartilhadas no nível do projeto, ordem de inicialização e importação de Compose de ponta a ponta.
- O sh0 faz backup de si mesmo. `sh0 instance backup` tira um instantâneo coerente do próprio banco de dados via `VACUUM INTO` — nunca uma cópia de arquivo, pois o banco roda em WAL —, mantém a chave mestra fora do artefato mas registra sua impressão digital, e `sh0 instance restore` o recoloca em uma máquina nova. Além da importação de projetos entre instâncias e da rotação da chave de criptografia dos segredos.
- O diagnóstico chega durante a espera, não depois dela. Os logs do contêiner aparecem enquanto a sonda de saúde roda, cada etapa de build informa quanto custou, uma linha de contexto abre o log de build, o estado do disco é legível pela API, a coleta de camadas pendentes fica registrada e um alerta precede a saturação em vez de constatá-la.
- A via de arquivo, para quem implanta o próprio código sem repositório git. O tipo de aplicação é aceito no envio, o comando de inicialização é configurável, uma falha de build mostra sua linha de contexto e sua causa, e um worker sem porta não retém mais o envio por 300 segundos deixando um contêiner para trás. Node, Python, Go e Rust implantados pelas duas vias, arquivo e Dockerfile.
- Uma instalação se repara e se atualiza sem SSH. `sh0 update` escolhe seu canal — estável ou preliminar —, verifica a soma de verificação do binário baixado e volta atrás nos dois sentidos; uma atualização não interrompe mais as aplicações implantadas. `sh0 doctor` verifica Docker, portas, disco, certificados e relógio, e termina com erro quando algo falta. Desinstalação limpa e unidade systemd endurecida.
- O correio e o armazenamento de arquivos tornam-se utilizáveis: Stalwart v0.16 controlado por JMAP, as rotações automáticas de DKIM refletidas no DNS, uma credencial recusada que o diz em vez de silenciar. E quarenta e oito correções, cada uma com uma observação datada em uma máquina real: não um teste unitário, uma máquina.
v1.7.1: licenças com data, renovação automática
- Uma licença passa a ter uma data de expiração alinhada com a assinatura que a pagou. As assinaturas mensais emitiam licenças perpétuas: um mês pago dava acesso vitalício.
- Uma passagem diária recupera a chave renovada, verifica a assinatura e substitui a armazenada — nada a fazer quando uma assinatura é renovada. Uma assinatura cancelada revoga a chave e o plano cai na passagem seguinte.
- Desafio DNS-01 por domínio: um servidor atrás de um CDN que termina o TLS (nuvem laranja da Cloudflare) obtém agora um certificado sem desativar a proteção, em vez de queimar o seu orçamento Let’s Encrypt em ciclo.
- Roteamento e ciclo de vida: um reinício que muda a porta publicada atualiza a rota do Caddy; uma aplicação que não escuta na porta configurada deixa de ser declarada saudável enquanto devolve 502; uma reimplantação já não deixa o contentor antigo vivo ao lado do novo.
- Os limites de recursos seguem o hardware e não a licença numa instalação auto-hospedada, e os atualizadores de estado SSL já sabem rebaixar um certificado, e não apenas promovê-lo.
- A v1.7.1 é necessária para qualquer licença comprada depois de 9 de setembro de 2026. As versões anteriores não sabem recuperar uma renovação e param no fim do primeiro período.
v1.7.0: uma licença é um documento assinado
- Uma chave de licença é agora um documento assinado em Ed25519 que carrega o seu próprio plano, e não uma cadeia cujo prefixo era acreditado. Qualquer cadeia não reconhecida ativava o plano Pro.
- A verificação é offline: a chave pública viaja dentro do binário, portanto um servidor isolado da rede valida a sua licença sem chamar nada.
v1.6.29: correções do dogfooding -- paridade .dockerignore, loops de falha nomeados, aplicações worker sem porta
- O contexto de build aplicava um padrão .dockerignore sem barra a qualquer profundidade (semântica gitignore); o Docker ancora cada padrão na raiz e só **/ desce. Um projeto que ignorava *.md e importava src/lib/resources/x.md compilava no Easypanel e falhava no sh0. O sh0 aplica agora as regras do Docker; a sua própria lista gerada escreve **/ explicitamente.
- O ciclo de saúde só lia State.Running. Um contentor que sai ao arrancar sob unless-stopped é reiniciado em menos de um segundo: parecia em execução, a sonda TCP falhava 300 s e o registo concluía tempo esgotado. O ciclo lê agora RestartCount e Restarting, falha em segundos com "crashed N times (exit code X)", para o loop e nomeia um OOM-kill. v1.6.30, no mesmo dia: o código de saída e o indicador OOM são lidos numa captura parada, porque o Docker os repõe a zero assim que reinicia o contentor -- um OOM-kill era anunciado como "exit code 0".
- Os builds de imagem usavam rm=true, que só remove os contentores intermédios em caso de sucesso; cada build falhado deixava um contentor Exited (1) com nome aleatório que nenhuma limpeza via. forcerm=true remove-o em ambos os casos.
- As aplicações têm um tipo: web (inalterado) ou worker. Um worker não resolve nem publica porta, não recebe rota Caddy nem domínio de pré-visualização, e está saudável quando permanece em execução 15 s sem reinício. Celery, BullMQ e processos tipo cron implantam-se sem serem mortos por uma sonda a que nada podia responder. Os formulários do painel expõem a escolha.
Correção v1.6.28: a API congelava após duas reimplantações, e o Sinatra respondia 403
- O proxy de pré-visualização dos endereços *.sh0.app mantinha vivo um guard de leitura do DashMap durante todo o pedido reencaminhado, horas num WebSocket. A limpeza da cache adicionada na reimplantação bloqueava então uma thread do runtime, um escritor em espera bloqueava os novos leitores, e duas reimplantações com tráfego congelaram a API com centenas de ligações em fila. A entrada da cache é agora copiada antes de qualquer await. Não instale a v1.6.27 em produção.
- O modelo Ruby nunca definia RACK_ENV: o Puma arrancava em desenvolvimento e a autorização de host do Sinatra 4 devolvia 403 a todos os hosts públicos, enquanto a sonda em localhost passava. A etapa de produção define agora RACK_ENV e RAILS_ENV como production.
Dezenove correções antes da produção: contexto de build, login em claro, modelos quebrados e um instalador que traz o Docker
- Contexto de build: um único caminho com mais de 100 bytes fazia falhar o arquivo tar (o cabeçalho GNU não tem campo prefix); os caminhos longos passam agora como ligações longas GNU. O sh0 também substituía o .dockerignore do projeto pela sua própria lista, que excluía todos os *.md: o ficheiro do projeto é agora lido e completado, nada é imposto quando traz o seu Dockerfile, e o número de ficheiros excluídos é registado.
- Autenticação: os cookies de sessão e de renovação levam Secure sempre que o pedido chegou por HTTPS, a porta 80 responde um 308 para https:// em cada host gerido (os desafios ACME continuam a passar), o instalador avisa que o primeiro login por IP vai em claro e mostra como pôr um domínio TLS no painel, e as credenciais fictícias [email protected] desaparecem do instalador, do painel e do banner do servidor.
- Stacks: o Go compila qualquer versão de go.mod (GOTOOLCHAIN=auto numa imagem atual) e encontra a raiz do módulo quando o binário vive em cmd/<nome>; a configuração do Bundler em Ruby chega à etapa de produção e o Puma liga-se uma só vez; o .NET deduz o assembly de entrada na construção, inclui o curl para a sua sonda e corre em .NET 10 com roll-forward. Uma reimplantação ou um escalonamento já não serve 502 em *.sh0.app enquanto a cache expira.
- Plataforma: uma cadeia de licença desconhecida é recusada em vez de ativar o Pro, a mensagem de quota nomeia o projeto que ocupa a vaga, `sh0 users list` lê a base local na máquina servidor, o proxy na nuvem encaminha /api/* para a sua aplicação em vez de responder por ela, o cartão Active Servers do site lê batimentos reais, e o get.sh0.dev instala o Docker (ou falha cedo com o comando exato) antes de escrever a unidade systemd.
Duas correções antes do dogfooding: contêineres parados sobrevivem à limpeza, certificados sob demanda já não exigem e-mail
- A limpeza horária do Docker removia todos os contêineres parados geridos pelo sh0, incluindo o de uma aplicação que acabara de falhar: código de saída, logs e o botão Iniciar desapareciam com ele. Um contêiner parado é agora mantido enquanto uma linha da base de dados o referenciar; só os verdadeiros órfãos são removidos, e a etapa é ignorada em vez de executada às cegas se a base não puder ser lida.
- A emissão de certificados sob demanda só era armada com um e-mail ACME configurado, embora o log a anunciasse armada em todos os casos -- numa instalação padrão, o Caddy continuava a emitir ao carregar a rota. A política abrangente sob demanda é agora emitida com ou sem e-mail; o e-mail é simplesmente omitido do emissor quando não existe.
Quatro lotes saem juntos: bloqueio de instância, certificados sob demanda e um estado SSL honesto
- `sh0 serve --port 9001` ao lado de uma instância em execução instalava pacotes, migrava a base de dados e parava o Caddy em execução antes de descobrir que não conseguia arrancar. Um `flock` consultivo sobre `sh0.pid` recusa agora a segunda instância de imediato, indica o PID que ocupa o diretório e não toca em nada. Uma falha deixa o ficheiro sem consequências: o bloqueio morre com o processo, e o arranque seguinte prossegue.
- Os certificados são emitidos sob demanda, no primeiro aperto de mão TLS, em vez de ao carregar a rota -- um domínio cujo DNS ainda não chegou deixa de consumir uma tentativa do Let's Encrypt. Um domínio fica `pending` até alguém se ligar, e o selo diz agora porquê (`ssl_pending_reason`). `ssl_expiry` era sempre `null`; agora é lido do certificado em disco. Um domínio `active` cujo certificado desaparece volta a `pending` após duas verificações consecutivas.
- Um contentor em ciclo de falhas dizia-se `running` porque só o estado do Docker era lido; o contador de reinícios e o código de saída fazem agora parte do veredicto. Os caminhos de streaming do Docker tinham buffers em memória sem limite -- o sh0 foi morto por OOM aos 7,3 GB em isolamento -- e estão agora limitados. O serviço de uma pilha Compose que recebia a rota pública era escolhido pela ordem de iteração de uma tabela hash e podia mudar entre implantações; agora é determinístico.
- As subscrições da página de estado estavam mortas por construção: o e-mail de confirmação nunca era enviado enquanto a API afirmava o contrário. O formulário só aparece agora se o SMTP estiver configurado, as subscrições não confirmadas são limitadas a 200 por domínio, e as linhas não confirmadas são purgadas após 48 horas em vez de 7 dias.
- «Executar agora» num agendamento de cópias lançava uma cópia pontual cujos arquivos escapavam a toda a retenção; agora executa o próprio agendamento. `restore-external` recusava um servidor de base de dados nunca aprovisionado mas aceitava um parado; um servidor parado também é recusado de forma síncrona.
- O importador Compose exigia `image:` e ignorava `build:` em silêncio; agora recusa um serviço `build:` com uma mensagem que diz o que fazer. `--acme-email` é persistido como `--panel-domain`, por isso as renovações deixam de depender de um valor de recurso não verificado. E a API já não anuncia `panel_domain_ssl: "provisioning"` quando nenhum aprovisionamento está a decorrer.
Laravel implanta, o Compose fala a forma longa e a porta para de se perder
- Toda aplicação Laravel era construída como Node. O detector parava no primeiro `package.json`, e um Laravel moderno sempre traz um porque é assim que o Vite compila os assets, então o contêiner morria em `npm start`, um script que nenhum `package.json` do Laravel contém. Agora o PHP vence esse empate quando o projeto apresenta provas: um framework em `composer.json`, um `artisan` ou um `public/index.php`. Um projeto Node que apenas embarca uma biblioteca PHP continua sendo Node.
- Detectar o Laravel não era fazê-lo funcionar. O `package.json` passa a ser uma etapa de assets dentro da imagem PHP, o Composer instala em duas passagens porque o `artisan` ainda não existe na primeira, uma `APP_KEY` é cunhada no primeiro deploy e guardada cifrada em vez de embutida na imagem, e os drivers de sessão, cache e fila passam a usar por padrão os que não exigem banco de dados. Esse último apareceu ao implantar na máquina de demonstração e receber um 500, não lendo código.
- Arquivos Compose escritos na forma longa para `ports` e `volumes` falhavam na leitura — `invalid type: map, expected a string`. As duas chaves aceitam agora qualquer das formas, inteiros nus incluídos, e `read_only: true` vira um monte realmente somente-leitura. Um caminho do host na forma longa continua recusado, mas a recusa agora nomeia a política em vez de devolver um erro de tipo.
- Na via de imagem Docker, a porta resolvida servia para publicar o contêiner e depois era descartada: uma aplicação implantada sem porta devolvia `port: null`, e qualquer domínio associado roteava para 3000 enquanto o contêiner escutava em outro lugar. Agora a porta é gravada em todas as vias, e o teste acrescentado não verifica a função e sim quem a chama, de modo que uma sexta via que esquecer fará a suíte falhar.
- O branch padrão era a string `main`, fixa no código. O sh0 nunca consultava o remoto: `laravel/laravel` (em `13.x`) e todo repositório ainda em `master` falhavam no primeiro passo com uma mensagem do libgit2. Um branch vazio significa agora «o do repositório»: o clone resolve o HEAD remoto, grava o nome encontrado na aplicação, e um branch inexistente é reportado nomeando os que existem.
Guardas que nunca corriam: CSRF, limitação de débito e dez comandos da CLI avariados
- O `sh0 push` não conseguia implantar de todo. Onze isenções de CSRF estavam escritas com um prefixo `/api/v1/` que o axum já tinha retirado: a guarda não correspondia a nada e `/apps/upload` e `/auth/logout` respondiam 415. As isenções correspondem agora aos caminhos que a camada vê realmente; uma implantação através do `sh0 push` foi medida em 25,7 s.
- O `sh0 login` falhava com `Unexpected response format`. O comando ainda desserializava um token que a API já não devolve -- ela coloca cookies HttpOnly e entrega apenas o token CSRF. O início de sessão agora autêntica, ultrapassa o segundo fator quando está configurado, cunha uma chave de API e persiste-a; a chave leva o nome do utilizador, o da máquina e a data.
- O limitador de débito global estava inerte, e o defeito foi medido na própria instância de demonstração pública antes da correção: 1100 leituras, 1100 respostas, nem um único 429, contra as 1000 leituras e 500 escritas por minuto anunciadas. Mesma causa raiz -- a camada está montada dentro do ninho `/api/v1`, pelo que os seus caminhos `/api/v1/...` nunca correspondiam. É uma correção de segurança.
- O `X-Forwarded-For` só é acreditado quando o pedido chega de um par loopback ou privado, que é o que o próprio processo filho Caddy do sh0 é. Nota de compatibilidade: uma instalação por trás de um proxy com endereço público -- Cloudflare e afins -- passa a contar todo o seu tráfego num único compartimento, por falta de uma lista de proxies declarados.
- Oito comandos `list` estavam avariados -- `database-servers`, `auth-servers`, `realtime-servers`, `function-servers`, `mail`, `file-storage`, `uptime` e `nodes` morriam todos em `Failed to parse paginated response`. O `sh0 templates info` e o `sh0 db connection-info` falhavam em nomes de campo que tinham derivado do lado do servidor. O banner de arranque anunciava também systemd no macOS, onde o instalador não regista serviço algum desses; passa a nomear o launchd e cala-se quando o servidor já corre sob um LaunchAgent.
Oito casos de implantação jogados numa máquina real, três muros encontrados
- Esta versão vem de uma matriz de fumo da implantação jogada por inteiro numa máquina real -- oito casos, não uma releitura de código. Seis passam: Node genérico, Next com pnpm, site estático, Dockerfile arbitrário, e os modelos PostgreSQL e Redis. Dois falhavam e continuam abertos: Laravel e docker-compose.
- O falso verde, e o pior dos três. A verificação de saúde sondava o `docker-proxy`, que completa o aperto de mão TCP seja qual for a saúde do contentor: uma aplicação morta era declarada saudável. A sonda devolve agora um estado de três valores, e é o seu desfecho que decide, não a sua falha. Medido: um `nginx:alpine` sem HEALTHCHECK numa porta deliberadamente errada falha agora ao fim de 304 738 ms, ali onde a v1.6.20 o declarava verde em menos de um minuto.
- Sites estáticos: o nginx morria em ciclo por causa do seu pidfile. O `chown` não tinha acompanhado a mudança do pidfile para `/tmp/nginx`. Corrigido, mais um teste que verifica cada caminho gravável individualmente -- o teste existente procurava apenas a subcadeia `chown` e manteve-se verde durante todo o episódio.
- A porta introduzida sobrepunha-se em silêncio ao `EXPOSE` da imagem. O sh0 lê agora o `EXPOSE` quando nenhuma porta é indicada, e avisa em caso de desacordo, nas cinco vias de implantação.
- pnpm. As dependências com scripts de compilação já não eram construídas, e a poda do pnpm falhava duas vezes. Critério de aceitação atingido: o `ts-nextjs-tailwind-starter` compila em 211 s e serve um 200.
- 804 testes passados, `clippy --workspace --all-targets -- -D warnings` verde.
Uma retenção que poupa as cópias manuais e restauros que alcançam servidores autónomos
- A retenção deixa de tocar nas cópias manuais. Um agendamento só conta e remove as cópias que criou; tudo o que for lançado à mão fica imune por construção. A migração 057 liga cada cópia ao seu agendamento e só adota as linhas existentes quando a atribuição é certa -- uma origem com vários agendamentos mantém as linhas antigas intactas em vez de adivinhar. É a alteração de motor anunciada como futura na v1.6.19.
- O modal de agendamento lista os servidores de base de dados autónomos. O cartão Base de dados contava-os, a lista de seleção não: um servidor visível na contagem não podia ser agendado. Ambos mostram agora a mesma população -- bases de aplicações, serviços com base embebida e servidores autónomos com um distintivo «DB Server» -- e o passo para trás regressa à lista correta.
- Um restauro externo pode visar um servidor de base de dados autónomo, servidor inteiro ou base única. A via de servidor inteiro preserva as bases já presentes no destino, a garantia introduzida na v1.6.19. Três casos passam a ser recusados com uma mensagem clara em vez de falharem em silêncio: um servidor sem contentor iniciado, um nome de base começado por hífen e um destino desconhecido.
- O estado de restauro de uma cópia é gravado no momento em que a sua linha é criada. Os restauros externos mostravam um estado vazio até à primeira atualização -- uma lacuna presente desde a inserção original, revelada pelos testes novos. A confirmação de edição de um agendamento está também traduzida nas cinco línguas do painel, em vez de mostrar a chave por traduzir.
Segurança de restauro, reparação de linhas e um contrato de retenção coerente
- Restaurar uma cópia de servidor PostgreSQL completo já não destrói o destino. O restauro da v1.6.18 apagava todas as bases do servidor de destino e depois não restaurava nada -- uma regressão publicada com a correção do pg_dumpall. O restauro filtra agora o script no momento de restaurar: os arquivos já produzidos pela v1.6.18 continuam restauráveis.
- As cópias MongoDB autenticam-se. O mongodump e o mongorestore eram lançados sem credenciais: nenhuma cópia MongoDB de um servidor gerido tinha alguma vez produzido um arquivo -- cada tentativa morria no muro de autenticação. A palavra-passe chega agora às ferramentas pelo ambiente de execução do contentor.
- As cópias de servidor completo CockroachDB são recusadas com uma mensagem clara em vez de fingir. A imagem não inclui ferramentas cliente PostgreSQL, portanto a função não pode funcionar; o ramo morto que sugeria o contrário foi removido.
- A migração 056 repara as linhas de cópia danificadas por versões anteriores: restauros externos registados como arquivos (um caminho sem tamanho) e linhas presas em « restoring » pelo antigo caminho de restauro. Dois invariantes medidos em todo o histórico de versões tornam a reparação segura; as linhas inclassificáveis ficam intactas e documentadas.
- A retenção passa a ter um único contrato: 7 por omissão em todo o lado, 0 significa ilimitado. O formulário dizia 30 enquanto a API dizia 7, e escrever 0 tornava-se silenciosamente 30 porque zero é falsy. Limites 0-365, com rótulos atualizados nas cinco línguas do painel.
- A retenção conta todas as cópias de uma origem -- agendadas e manuais por igual. A documentação prometia que as manuais nunca eram contadas: era falso face ao motor, e a documentação diz agora o que acontece realmente. Tornar as cópias manuais imunes é uma alteração futura do motor, seguida à parte.
Retenção de cópias e dumps de servidor completo
- A retenção de cópias de segurança finalmente corre. A função de purga existia, não era chamada de lado nenhum e nunca tinha corrido desde a v1.0.0: o campo «Retenção» do painel não controlava nada e os repositórios cresciam sem limite. Corre agora após cada cópia agendada bem-sucedida, com uma varredura horária de recuperação para os repositórios já transbordados.
- Uma cópia de um servidor PostgreSQL completo já contém os seus dados. O agendador passava «postgres» como nome da base de dados, pelo que despejava a base de arranque, vazia: o arquivo estava bem formado, era restaurável e estava vazio. As cópias de servidor completo usam agora pg_dumpall, e o restauro já não corre numa transação única, porque criar bases de dados o proíbe.
- As cópias de um servidor MySQL completo funcionam, pura e simplesmente. Nunca tinham chegado a correr: o agendador passava «--all-databases» como nome de base de dados, que a validação rejeitava pelo travessão inicial. Mesma causa da falha do PostgreSQL, sintoma oposto: esta falhava ruidosamente em vez de mentir em silêncio.
- O painel dizia «Retenção (dias)» para aquilo que sempre foi um número de cópias. Corrigido nas cinco línguas do painel.
- Estas duas correções estão verificadas por testes, ainda não num servidor real. Nenhum teste da suite toca numa instância PostgreSQL verdadeira: verificam o comando construído, nunca a sua saída. Considere esta versão corrigida-mas-não-provada nos dumps de servidor completo até ter corrido na sua própria máquina.
Cópias de segurança de bases geridas -- acionamento, agendamento, restauro
- Uma base de dados criada num servidor de bases gerido já pode ser copiada: o acionador consultava apenas a tabela das bases autónomas, pelo que uma base gerida respondia «origem de cópia não encontrada». Verificado num servidor real abrindo o artefacto -- contém a tabela e as suas linhas.
- As cópias de um servidor de bases inteiro já podem ser restauradas. O acionador aceitava um tipo de origem que o restauro desconhecia, por isso cada restauro desse tipo era aceite e falhava depois em segundo plano; os destinos inválidos passam a ser recusados à partida.
- Um restauro externo deixa de provocar a purga de cópias verdadeiras. O registo de um restauro era escrito com o mesmo estado «concluído» de um arquivo, pelo que a retenção o contava e apagava cópias autênticas -- linhas e objetos armazenados -- para respeitar a quota. Cópias e operações de restauro são agora registos de natureza distinta.
- As bases geridas podem entrar num agendamento de cópias, e não apenas ser copiadas a pedido.
- Os projetos Python com Pipfile passam a incluir as suas dependências na imagem de produção. Confirmado abrindo a imagem construída e não por uma resposta HTTP correta: a correção anterior passava nos testes e entregava mesmo assim uma imagem sem elas.
- Os projetos com pnpm voltam a compilar: a imagem gerada instala exatamente a versão do pnpm que produziu o ficheiro de bloqueio, sobre uma base Node suficientemente recente para a executar. Fica um caso em aberto -- um projeto pnpm cujas dependências executam scripts de instalação falha na construção; correção em curso.
Correções de build nos deploys Git -- gestores de pacotes, Django, verificações de saúde
- Projetos com yarn ou bun voltam a compilar: a imagem gerada instala o gestor de pacotes em vez de invocar um que nunca esteve presente. Os projetos com pnpm continuam bloqueados -- a verificação em condições reais mostrou que a imagem base do Node é demasiado antiga para a versão do pnpm que é descarregada; corrigido em 1.6.17.
- Deploys Django executam o collectstatic na etapa de produção, onde as dependências realmente estão -- o passo falhava em silêncio e os ficheiros estáticos devolviam erro 500
- Os projetos Python com Pipfile ainda não estão corrigidos: a verificação em condições reais mostrou que a correção incluída aqui é incompleta -- as dependências continuam a não chegar à imagem final. Corrigido e verificado num servidor real em 1.6.17.
- As verificações de saúde em imagens Alpine consultam 127.0.0.1 com recurso a IPv6 -- o busybox wget resolvia ::1 primeiro, pelo que servidores apenas IPv4 eram reiniciados como não saudáveis
- Projetos Rust compilam com uma toolchain atual (rust:1-alpine) -- a imagem fixada em 1.77 já nem conseguia ler um Cargo.lock moderno
Reforço de alertas e monitoramento -- RBAC, SSRF, servidores de autenticação
- As regras de alerta e os canais de notificação agora aplicam as permissões de função -- os visualizadores do projeto não podem mais criar ou editar alertas, nem ler os segredos das rotas de notificação
- As verificações de uptime e de alerta foram reforçadas contra SSRF -- as requisições de saída não podem mais ser direcionadas a endereços internos ou privados
- O DNS rebinding é neutralizado fixando o IP resolvido durante toda a requisição, e o monitoramento agora falha de forma explícita se o seu cliente HTTP reforçado contra SSRF não puder ser construído, em vez de recorrer silenciosamente a um inseguro
- O provisionamento de servidores de autenticação (Logto) agora concede apenas as funções necessárias e falha de forma explícita em caso de criação parcial, em vez de deixar um servidor meio criado marcado como pronto
- Rotas de notificação mortas foram removidas e as entradas de configuração de alertas e uptime são validadas de forma mais rigorosa
Correções dos hubs BaaS -- segredos, domínios, funções edge
- As restaurações de banco de dados agora substituem o banco de destino e revertem de forma atômica em caso de erro, em vez de mesclar silenciosamente linhas com os dados existentes
- As credenciais dos servidores realtime só são retornadas a desenvolvedores e acima -- visualizadores do projeto não recebem mais os segredos de conexão
- Os servidores realtime, auth e de funções agora são acessíveis nos seus domínios públicos *.sh0.app
- Os servidores de funções Deno iniciam de forma confiável -- uma falha na inicialização é informada imediatamente em vez de um falso status de execução
- Os servidores de funções recebem um domínio público funcional com HTTPS automático na criação
Paridade de execução de contêineres -- correções de confiabilidade
- Restauração externa corrigida -- restaurar um backup armazenado em um destino externo (S3, R2) agora lê corretamente o artefato enviado
- Paridade de previews -- os contêineres de preview agora executam com o mesmo usuário da produção, de modo que aplicações que exigem privilégios elevados não falham mais em loop nas previews
- Paridade de escalonamento -- as réplicas agora herdam o usuário do contêiner principal, de modo que escalar uma aplicação cuja imagem executa como root não produz mais réplicas falhando em loop
- Correções de templates -- Garage, Logto e Plane agora iniciam corretamente logo após a instalação
Reforço de backups e armazenamento
- Restauração corrigida -- restaurar um backup de banco de dados ou de volume pelo painel ou pela API agora é concluído corretamente
- Controle de acesso de backups -- listar, acionar, baixar, restaurar e excluir backups agora exige as permissões adequadas do projeto
- Credenciais protegidas -- os endpoints de armazenamento de arquivos não retornam mais credenciais de administrador compartilhadas, e os destinos de backup só podem ser gerenciados por seus proprietários
- Listagens restritas -- os domínios de armazenamento e as chaves de acesso só são visíveis e gerenciáveis dentro dos seus próprios projetos e instâncias
- Limpeza completa -- excluir um backup remove seu artefato armazenado, e excluir uma instância de armazenamento desfaz suas rotas de proxy e sua configuração TLS
Confiabilidade de implantações -- correções complementares
- Implantações Git acessíveis -- a porta detectada de uma aplicação passa a ser memorizada, de modo que projetos Next.js, Django, FastAPI e Rust respondem na sua URL de pré-visualização sem configuração manual
- TLS mais limpo -- o servidor de origem não tenta mais obter certificados impossíveis para os domínios proxy *.sh0.app, liberando a cota de certificados compartilhada
- Plausible Analytics -- o modelo agora cria o papel e o banco de dados PostgreSQL, de forma que a pilha inicia corretamente
- Zitadel -- o modelo agora fornece uma tela de login funcional por padrão
- Convex -- o backend agora inicia (marcado como experimental enquanto o suporte multiporta é concluído)
- Limpeza aprimorada -- implantações com falha não deixam mais contêineres ou imagens órfãos
Reforço de produção -- lote de correções da auditoria
- As stacks populares são implantadas corretamente -- as aplicações recebem o seu cabeçalho Host real, de modo que WordPress, Laravel e Django funcionam atrás dos domínios *.sh0.app
- Estado de implantação confiável -- contêineres em loop de reinicialização são detectados e relatados como falhos em vez de aparecerem como em execução
- Indicador SSL preciso -- os domínios mostram o estado real do seu certificado e os links usam HTTPS
- Padrões mais seguros -- painéis de administração secundários (consoles de banco de dados, armazenamento de objetos, provedores de identidade) não são mais expostos publicamente por padrão
- Next.js e Rust -- projetos padrão do create-next-app e projetos Rust reais agora são implantados sem configuração manual
- Reparos no catálogo de modelos -- correção do tratamento de credenciais para Zitadel, Chatwoot, Langfuse, SurrealDB e Convex; remoção de modelos cujas imagens de origem não estão mais disponíveis
sh0 Manager: gestão da frota pelo celular
- Aplicativo móvel sh0 Manager: gerencie todas as suas instâncias sh0 pelo celular (iOS e Android)
- Vinculação por código QR: escaneie no painel para vincular instâncias, com tokens seguros de duração limitada
- Visão da frota: todas as instâncias, status on-line ou off-line, número de aplicações e plano, de relance
- Autenticação por token Bearer: o aplicativo móvel usa autenticação de sessão pelo cabeçalho Authorization
- Seção Manager no painel: gere tokens de vinculação, veja as informações da instância e gerencie a propriedade
Logs de construção ao vivo, variáveis de ambiente no envio e confiabilidade
- Logs de construção ao vivo: acompanhe as construções Docker em tempo real, com rolagem automática
- Corrigida a condição de corrida no envio de variáveis de ambiente: elas são salvas atomicamente antes de o pipeline de implantação começar
- Tempo limite de construção ampliado para 30 minutos: atende Rust e outros projetos de compilação longa
- Maior precisão da pontuação de saúde: teto de penalidade por regra, regras de segurança deixam de ser bloqueantes
- 0cron.dev implantado com sucesso no sh0 (backend em Rust e frontend SvelteKit): o primeiro aplicativo Rust real
- Ruído dos registros de sinal de vida eliminado: rotina em nível de depuração, informação apenas na troca de IP
Domínios de pré-visualização: uma URL imediata para cada aplicação
- Cada instância sh0 se registra no proxy em nuvem ao iniciar, sem nenhuma configuração
- Formato de subdomínio plano: undefined-undefined.sh0.app — um único certificado curinga, sustentável acima de 100 000 instalações
- Proxy reverso dos domínios de pré-visualização: um middleware Axum roteia o tráfego para o contêiner Docker correto
- Nenhum registro DNS na Cloudflare é necessário: o curinga *.sh0.app resolve tudo
- O painel exibe um selo “Pré-visualização” e links HTTPS clicáveis para todos esses domínios
- Funciona no plano gratuito: os domínios de pré-visualização não exigem licença
Rodada de QA 1: correções e acabamento
- Corrigido o selo de status SSL que exibia “pendente” com o HTTPS já ativo
- DNS do e-mail: o registro PTR passa a ser opcional (um IP compartilhado não permite DNS reverso)
- URLs do e-mail: portas Docker aleatórias removidas, endereços HTTPS limpos através do proxy Caddy
- Adicionados os redirecionamentos /webmail e /admin no estilo cPanel para os nomes de host do e-mail
- Corrigido o laço infinito de recarregamento do navegador na aba Fila do e-mail
- As credenciais de administração do e-mail aparecem na aba Visão geral, com alternância de exibição
- Tarefas agendadas: os redirecionamentos de shell (> /dev/null 2>&1) são removidos automaticamente dos comandos
- O histórico de execução das tarefas mostra a saída padrão e a de erro em um visualizador expansível
- Disparo de uma tarefa: janela em tempo real com sondagem, em vez de um aviso silencioso
- Corrigido o servidor de autenticação: imagem Docker correta (svhd/logto), ponto de entrada adequado, banco de dados inicializado na primeira execução
- Autenticação, tempo real e funções: estados vazios com explicações e pré-requisitos
- Os erros internos agora retornam a mensagem real (produto auto-hospedado, o usuário é administrador)
- Terminal do servidor e navegador de arquivos nas Configurações, para acesso direto à máquina
- Abas Arquivos e Volumes adicionadas às páginas de detalhe dos servidores de funções e de tempo real
- Corrigida a restrição de domínio sobre service_id (migração 049)
- 475 novas chaves de internacionalização e 4 páginas do site convertidas para o Paraglide
Segurança, Polimento e Feature-Complete
- Recursos avançados de e-mail: configuração de filtro de spam, resposta automática de férias, regras de filtro Sieve, monitoramento da fila de e-mails
- Rotação de chave DKIM e streaming de logs de contêiner para servidores de e-mail
- Controle de licença: todos os serviços BaaS restritos ao Pro+ com popups de UpgradePrompt em 12 páginas
- Integração com Trustpilot como aba fixa em todas as páginas do dashboard
- Estatísticas rápidas de BaaS na página inicial do dashboard
- 8 novas páginas de alternativas SEO: Vercel, Supabase, Firebase, Netlify, cPanel, Render, Railway, Fly.io
- Redesign da página inicial com hero de BaaS, seção de capacidades e faixa de preços
- Matriz de comparação de recursos na página de preços com 27 linhas
- Página de relações com investidores com white paper e PDFs de apresentação
- Prompts de sistema de IA atualizados com recursos e capacidades atuais
- 979 chaves i18n para páginas de SEO em 5 idiomas
- 5 correções de segurança críticas: injeção Sieve, perda de dados em resposta automática de férias, bypass de escopo MCP em 92 ferramentas, travessia de caminho em backups, sobrescrita de estado do Cloudflare
- 10 correções de segurança importantes: validação de entrada, limpeza de DNS, validação de alvo de sandbox, prompts de confirmação no CLI
Armazenamento de Arquivos, Servidores de Banco de Dados e E-mail
- Armazenamento de objetos S3-compatível gerenciado com MinIO — buckets, chaves de acesso, monitoramento de uso
- Servidores de banco de dados standalone: PostgreSQL, MySQL, MariaDB, MongoDB, Redis com gerenciamento de usuários e permissões
- Hospedagem de e-mail gerenciada via Stalwart com configuração automática de DKIM, SPF e DMARC
- Assistente de configuração DNS em 4 etapas para e-mail com suporte a autoconfiguração do Cloudflare
- Caixas de entrada, aliases, regras catch-all e monitoramento de entregabilidade
- Integração de UI de administração de banco de dados: dbGate, phpMyAdmin, Mongo Express
- Acesso externo ao banco de dados com lista de IPs permitidos para conexões remotas seguras
- Página global de domínios: visão central de todas as URLs de serviço em cada app
- Mais de 50 novos endpoints de API para armazenamento de arquivos, servidores de banco de dados e e-mail
- Funciona nativamente com AWS SDK, Laravel, WordPress e qualquer cliente S3-compatível
Infraestrutura Core
- Cargo workspace com 10 crates Rust, gerenciamento de dependências compartilhado
- sh0-db: SQLite com modo WAL, pool r2d2, 30 migrações
- sh0-docker: Cliente completo da API Docker Engine sobre Unix socket (hyper 1.x)
- sh0-api: Servidor REST Axum com CRUD, paginação, streaming de logs via WebSocket
- sh0-git: Git clone/pull (libgit2), parsing de webhooks GitHub/GitLab/Bitbucket com HMAC-SHA256
- sh0-builder: 19 detectores de stack, 15 templates Dockerfile, builds multi-stage
- Motor de Verificação de Saúde do Código: 34 regras em Rust puro em 8 categorias
Proxy Reverso & Pipeline de Deploy Completo
- sh0-proxy: gerenciamento de processo filho Caddy com API admin JSON
- Auto-SSL via Let's Encrypt com e-mail ACME configurável
- Pipeline de deploy ponta a ponta: git pull -> analisar -> construir -> deploy -> verificação de saúde -> rotear
- Troca de container blue-green com deploy sem downtime
- Sistema de limpeza Docker: imagens penduradas, imagens antigas de apps, limpeza de cache de build
- Verificação de espaço em disco pré-deploy (falha em >90%, avisa em >80%)
- Rollback via reutilização de imagem em cache
Autenticação & Monitoramento
- Hashing de senha Argon2id, JWT HS256 (1h access + rotação de refresh de 30d)
- 2FA TOTP com códigos de backup com hash e URI de provisionamento
- Sistema de chaves API: hash SHA-256, prefixo sh0_, comparação em tempo constante
- Chave mestra de criptografia AES-256-GCM (PBKDF2, 100K iterações)
- Coleta de métricas em tempo real: CPU, memória, I/O de rede por container
- Avaliação de alertas: high_cpu, high_memory, app_down com cooldown de 5 min
Motor de Backup & Dashboard
- Dumps de banco via Docker exec: pg_dump, mysqldump, mongodump
- Backup de volume (tar + gzip) com criptografia AES-256-GCM
- Agendamento de backup via cron com limpeza por retenção
- SvelteKit 2 + Svelte 5 runes SPA com TailwindCSS 4
- Tema claro/escuro, i18n em 5 idiomas (EN, FR, ES, PT, SW)
- Cliente API com Bearer token automático, WebSocket com reconexão automática
- Dashboard embarcado no binário Rust via include_dir + build.rs
Dashboard Core & Páginas Estendidas
- Página de detalhe de app com layout de 6 abas: Visão Geral, Deploys, Logs, Domínios, Ambiente, Configurações
- Visualizador de logs em tempo real: WebSocket, estilo terminal, auto-scroll, buffer de 1000 linhas
- Editor de variáveis de ambiente com toggle de criptografia/revelação AES-256-GCM
- Página de gerenciamento de banco de dados com seletor de engine (postgres, mysql, mongodb, redis, mariadb)
- Gerenciador de backup: acionar, restaurar, excluir, criação de agendamento com cron
- Página de monitoramento: medidores de CPU/memória, CRUD de alertas, atualização automática
- Configurações: info do servidor, configuração/desativação 2FA TOTP, gerenciamento de chaves API
CLI, Templates, Alertas & Compose
- Cliente CLI: 7 comandos (apps, deploy, logs, env, check, ssh, status)
- Verificação de Saúde do Código local via sh0 check com saída colorida no terminal
- 170 templates YAML com um clique em 15 categorias (WordPress ao Ollama)
- Motor de substituição de variáveis com geração automática para secrets/senhas
- 5 canais de despacho de alertas: e-mail (SMTP), Slack, Discord, Telegram, webhook
- Parser Docker Compose v3 com deploy multi-serviço
RBAC, Exportação, Cron, Previews & Hooks
- RBAC de 4 níveis: Owner > Admin > Developer > Viewer (global + escopo por projeto)
- Log de auditoria em todos os handlers (assíncrono fire-and-forget)
- 7 formatos de exportação: Docker Compose, Kubernetes, AWS ECS, GCP Cloud Run, Vercel, Railway, Render
- Agendador de cron jobs com execução baseada em ticks, captura de stdout/stderr, histórico de execuções
- Ambientes de preview: auto-deploy baseado em PR com subdomínios únicos e limpeza TTL
- Hooks de deploy: pre_build, post_build, pre_deploy, post_deploy com enforcement de timeout
- sh0.yaml Infraestrutura como Código: defina stacks inteiras em um arquivo
Scaling & Monitoramento de Uptime
- Scaling horizontal: 1-50 réplicas com balanceamento de carga (round_robin, least_conn, random)
- Autoscaling por limites de CPU/memória com cooldowns configuráveis
- Monitoramento de uptime: verificações de saúde HTTP com detecção e ciclo de vida de incidentes
- Páginas de status públicas com histórico de uptime por domínio
- Sistema de assinatura por e-mail para notificações da página de status
51 Problemas Encontrados & Corrigidos
- 2 auditorias de segurança abrangentes em todas as 103 fases
- 13 correções críticas: comparação de chave API em tempo constante, auth JWT WebSocket, hashing de código de backup, lock de deploy por app
- 20 correções altas: validação de domínio, prevenção de path traversal, redação de secrets em logs de build, args Docker codificados em URL
- Expiração JWT reduzida (7d -> 1h) com rotação de refresh token de 30 dias
- Proteção CSRF (enforcement de Content-Type + padrão double-submit)
- Limitação de taxa: login (10/15min), TOTP (5/5min), global (1000/500s)
- Headers de segurança: HSTS, CSP, X-Frame-Options, X-Content-Type-Options
Arquitetura Baseada em Stacks & Polimento
- Barra lateral somente ícones de 56px com tooltips + barra lateral contextual de 240px para navegação de projetos
- Arquitetura baseada em stacks: agrupar serviços por projeto (frontend + backend + db + cache)
- Deploy Hub: wizard unificado com 183 opções de deploy, abas por categoria, seção em destaque
- 7 componentes de formulário de deploy: FormGit, FormUpload, FormDockerImage, FormDockerfile, FormCompose, FormService, FormFramework
- Paleta de comandos Cmd+K: busque páginas, stacks e serviços instantaneamente
- Barra lateral contextual responsiva para mobile com drawer + botão hamburger
- Redesign da página inicial com estatísticas do servidor, grade de stacks, ações rápidas
- Visualização de detalhe de app com 16 abas: Visão Geral, Deploys, Logs, Terminal, Arquivos, Armazenamento, Domínios & SSL, Ambiente, Redirecionamentos, Previews, Hooks, Scaling, Uptime, Cron, Serviços, Configurações
Imagem Docker, Dockerfile, ZIP & PHP/Ruby/.NET
- Deploy direto de Imagem Docker: baixar imagem, pular pipeline git/build
- Deploy somente Dockerfile: colar conteúdo, construir localmente
- Deploy por upload de arquivo ZIP com limite de 500MB e prevenção de path traversal
- Templates Dockerfile para PHP, Ruby e .NET adicionados
- Nomes de apps com escopo por projeto (índice único composto)
- Nomenclatura de container com prefixo de projeto: sh0-undefined-undefined
- 45 novos testes (scaling, compose, YAML)
Templates, Terminal, Navegador de Arquivos, Volumes
- Página Deploy Hub com catálogo de 183 opções de deploy
- Barra de progresso de deploy com rastreamento de etapas nos logs
- 170 templates: bancos de dados (33), CMS (18), analytics (7), auth (6), IA/ML (8), DevTools (12) e mais
- Gerenciamento de sub-serviços (containers MySQL, phpMyAdmin, dbGate)
- URLs de acesso a serviços: endpoints interno/local/externo com toggle externo
- Terminal web: xterm.js com seletor de shell (sh/bash/ash), suporte SSH TTY
- Navegador de arquivos: explorador de dois painéis estilo Docker Desktop com editor inline
- Armazenamento persistente: gerenciamento de volumes Docker, bind mounts, file mounts
- Página de documentação da API com playground interativo (26 grupos de endpoints)
URLs de Conexão, Credenciais, Vars de Ambiente em Lote
- URLs de conexão de banco de dados: interna e externa, calculadas automaticamente a partir da configuração do container
- Card de credenciais do banco: usuário, senha, strings de conexão
- Operações em lote de vars de ambiente com modo editor .env
- Persistência de credenciais de template (vars de ambiente armazenadas no DB)
Certificados SSL, Confiabilidade Caddy, Provedores de Armazenamento
- Migração de cookie HTTP-only com padrão CSRF double-submit (SameSite=Strict)
- Geração automática de chave mestra (derivada do secret JWT na primeira execução)
- Certificados SSL personalizados: geração CSR (rcgen), upload PEM (x509-parser), ssl_mode por domínio
- Criptografia de chave privada (AES-256-GCM) com permissões de arquivo restritas (0o600)
- Confiabilidade do proxy Caddy: matar processos obsoletos, retentar cargas de config, sincronizar rotas do DB
- 13 provedores de armazenamento via OpenDAL: S3, R2, Wasabi, Backblaze B2, SFTP, FTP/FTPS, Dropbox, Google Drive e mais
- Correção de IPv6 FTP/FTPS (modo EPSV, cliente suppaftp direto)
- Alinhamento de planos/preços: Free ($0), Pro (US$ 19/mês), Business (US$ 99/mês)
CronBuilder, Redirecionamentos, Restauração de Backup, Refatoração do Monitoramento
- Componente CronBuilder com 18 presets e sincronização bidirecional
- Regras de redirecionamento de URL: correspondência exata, prefixo, regex com códigos de status 301/302/307/308
- Restauração de backup: Fluxo A (backups sh0) e Fluxo B (upload de fonte externa)
- Refatoração da página de monitoramento: dashboard com 4 abas (Visão Geral, Apps, Uptime, Alertas)
- Redução de falsos positivos na verificação de saúde (mais de 80 novos testes, pular arquivos env/lock/doc)
- Modal de configuração DNS com IP real do servidor e orientação para Cloudflare
- Configuração de e-mail ACME (armazenado no DB, atualizações em runtime)
Multi-Servidor BYOS
- Registro de nó remoto com gerenciamento de túnel SSH (russh)
- SSH TOFU (Trust on First Use) com verificação de fingerprint de chave do host
- Transferência de imagem Docker via save/load por túneis SSH
- Pipeline de deploy com reconhecimento de nó, despachando builds para servidores remotos
- Dashboard de gerenciamento de nós com indicadores de status e monitoramento de saúde
- Hardening de nós: tratamento de erros, validação de conexão, limpeza graceful
Servidor MCP & Assistente IA
- Servidor MCP com 106 ferramentas: transporte Streamable HTTP em /mcp (JSON-RPC 2.0)
- Geração de ferramentas baseada em OpenAPI via utoipa com extensões x-mcp-*
- Segurança em 3 camadas: escopos de chave API (read/standard/admin), classificação de risco por ferramenta, tokens de confirmação para operações destrutivas
- Gateway de IA: roteamento de chat em 3 vias (conector MCP, legacy, especialista em docs)
- AI Sandbox: container sidecar Alpine 3.19 por app com shell root, instalação de pacotes, volumes graváveis
- Integração Claude MCP Connector para execução agêntica de ferramentas no servidor
- Chat IA no dashboard com seletor de modelo, histórico de conversas, timeline de etapas de processamento
- Modal de capacidades: 24 capacidades em 5 categorias, traduzidas em 5 idiomas
- Cobrança por carteira pré-paga com precificação por token (Haiku, Sonnet, Opus)
- Suporte BYOK no plano Business (chaves API Anthropic ou OpenRouter)
- 10 rodadas de auditoria em 5 fases — 0 problemas críticos chegaram à produção
Plano Free, Docker e Distribuição
- Backups liberados para o plano Free (armazenamento local); armazenamento em nuvem restrito ao Pro+
- Imagem Docker publicada no Docker Hub (zerosuiteinc/sh0) e GHCR
- Sistema de autoatualização: sh0 update verifica o GitHub Releases e atualiza automaticamente
- Configuração automática de serviço systemd no Linux (sh0 serve instala e ativa a unit)
- Bloqueios de página inteira para upgrade substituídos por banners inline em monitoramento, backups e equipe
- Matriz de recursos de licença refinada: backups granulares (local/nuvem) e monitoramento (métricas/alertas/uptime)
- Comando de desinstalação: sh0 uninstall remove o binário, a unit systemd e os dados de forma limpa
- Banner de inicialização com versão, URL do dashboard e dica de systemd
Tudo o que o sh0 inclui
Motor de Deploy
- 5 pipelines de deploy: Git, Imagem Docker, Dockerfile, upload ZIP, Template/Compose
- Autodetecção de 19 stacks com 15 templates Dockerfile otimizados
- Deploys blue-green com troca sem downtime e rollback
- 183 opções de deploy no Deploy Hub
- Parser Docker Compose v3 com deploy multi-serviço
Loja de Templates
- 170 templates com um clique em 15 categorias
- Bancos de dados, CMS, IA/ML, DevTools, analytics, auth, e-mail, filas, busca
- Substituição de variáveis com geração automática (secrets, senhas)
- Deploy multi-serviço com ordenação topológica
Domínios & SSL
- Auto-SSL via Let's Encrypt com Caddy ACME
- Upload de certificado SSL personalizado com geração de CSR
- Regras de redirecionamento de URL (prefixo, exato, regex)
- Balanceamento de carga: round_robin, least_conn, random
Monitoramento & Alertas
- Métricas de CPU, memória e rede em tempo real com gráficos sparkline
- 5 canais de alerta: E-mail, Slack, Discord, Telegram, Webhook
- Monitoramento de uptime com páginas de status públicas
- Autoscaling por limites de CPU/memória (1-50 réplicas)
Backup & Armazenamento
- Dumps de banco (pg_dump, mysqldump, mongodump) + backups de volume
- Criptografia AES-256-GCM com backups agendados via cron
- 13 provedores de armazenamento via OpenDAL (S3, R2, SFTP, Dropbox, Google Drive)
- Restauração a partir de backup ou armazenamento externo
Segurança
- 51 problemas de segurança encontrados e corrigidos em 2 auditorias
- Senhas Argon2id, JWT + rotação de refresh, 2FA TOTP, Google OAuth
- Criptografia AES-256-GCM para todos os secrets (vars de ambiente, tokens, chaves)
- Prevenção CSRF, SSRF, rate limiting, hardening de containers
Experiência do Desenvolvedor
- Terminal no navegador (xterm.js) com seleção de shell
- Navegador de arquivos com editor inline, mkdir, delete
- Verificação de Saúde do Código: mais de 34 regras verificadas antes de cada build
- Exportação para 7 plataformas: K8s, AWS, GCP, Vercel, Railway, Render, Compose
Painel
- 22 páginas, mais de 70 componentes, visualização de detalhe de app com 16 abas
- Paleta de comandos Cmd+K, tema claro/escuro, 5 idiomas
- Arquitetura baseada em stacks com barra lateral dupla
- Documentação da API com playground interativo (26 grupos de endpoints)
Automação
- Cron jobs com CronBuilder (18 presets, 50 jobs/app)
- Hooks de deploy: pre_build, post_build, pre_deploy, post_deploy
- Ambientes de preview a partir de webhooks de PR com limpeza TTL
- Infraestrutura como Código via sh0.yaml
Equipe & RBAC
- 4 níveis de papéis: Owner, Admin, Developer, Viewer
- Controle de acesso por escopo de projeto
- Log de auditoria em todas as operações
- Sistema de licenças: Free, Pro (US$ 19/mês), Business (US$ 99/mês)
Assistente IA
- Servidor MCP com 106 ferramentas
- AI Sandbox: container Alpine por app para depuração e desenvolvimento
- Conecte do Claude Desktop, Cursor ou qualquer cliente MCP
- Gateway de IA com chat web, seleção de modelo, histórico de conversas
- Carteira pré-paga com opção BYOK no plano Business
Em números
Crates Rust
Migrações
Endpoints API
Páginas do dashboard
Componentes UI
Idiomas
Templates de deploy
Ferramentas MCP
Regras de saúde
Formatos de exportação
Provedores de armazenamento
Canais de alerta
Testes passando
Protótipo Legacy (Python/FastAPI)
O sh0 original, construído em Python. Arquitetura baseada em agentes com detecção de stack, verificações de saúde e geração de Dockerfile. Serviu como blueprint para a reescrita em Rust.
Por que Rust? Reescrito em Rust por: ~140MB de memória ociosa (vs ~500MB Python), distribuição em binário único, API Docker socket direto (sem shell CLI), zero pausas de GC sob carga.
Pronto para fazer deploy?
Instale sh0 em menos de 60 segundos e faça deploy do seu primeiro app.