Rollback. Branch. Compartilhe. O modelo de estado por baixo de todo contêiner.
Cinco primitivos de sistema de arquivos e uma camada copy-on-write do BTRFS fazem o estado do contêiner sobreviver, viajar no tempo e mover entre servidores — sem sair do HTTP.
/hoody/storage · /hoody/databases · /ramdisk · /hoody/shares · BTRFS snapshots
/ ├── hoody/ │ ├── storage/ ← persistent, per-container │ ├── databases/ ← concurrent-safe SQLite (FUSE) │ └── shares/ ← inter-container directory mounts ├── ramdisk/ ← RAM-backed, 50% of container memory └── ... ← standard Linux FS (ext4, POSIX)
O mapa do sistema de arquivos.
Cada caminho tem uma história diferente de persistência e concorrência. Escolher o certo é todo o modelo mental. Análises completas nas seções abaixo.
/hoody/storage
Diretório persistente por contêiner. Sobrevive a reinicializações; snapshots o capturam. Um diretório ext4 comum — sem FUSE, sem segurança de concorrência além do que seu app fornece.
/hoody/databases
Montagem FUSE. Muitos processos, muitos contêineres (mesmo servidor) podem escrever no SQLite com segurança simultânea — sem 'database is locked'. Apenas mudança de caminho: mova o arquivo de /app/data.db para /hoody/databases/data.db. Nível de host — não replicado entre servidores.
/ramdisk
tmpfs em RAM a 10–20 GB/s, latência < 1µs. Limite de 50% da memória do contêiner, alocação sob demanda (0 bytes usados quando vazio). Persiste durante reinicialização do contêiner, limpo na reinicialização do host. Seu uso compete com a memória da aplicação.
/hoody/shares
Montagens de diretório entre contêineres via API de Storage Shares. Somente leitura ou leitura/escrita, 1-para-1 ou para todo o projeto. Compartilhamentos entre servidores usam NFS automático — sem configuração de montagem. O ciclo de vida (aceitar / rejeitar / montar / revogar) fica em /platform/control-plane.
/ (ext4)
Sistema de arquivos Linux padrão em todo o resto. POSIX, ext4, semântica completa. Se comporta como qualquer VPS fora dos caminhos /hoody/*.
BTRFS por baixo de tudo
Camada copy-on-write sob os caminhos com respaldo em disco. Snapshots em nível de bloco, deduplicação entre contêineres. Criação instantânea, restauração eficiente em espaço. (Não se aplica a /ramdisk — esse é tmpfs em RAM.)
Copy-on-write, nível de bloco, instantâneo.
O BTRFS armazena apenas os blocos que mudaram desde o ponto de snapshot. Criar um snapshot adiciona um marcador, não dados. O custo escala com o quanto um contêiner realmente muda — não com o número de snapshots ou contêineres na mesma imagem base.
t0 — snapshot A
O sistema de arquivos do contêiner tem os blocos a, b, c. O snapshot A referencia todos os três.
t1 — bloco b muda
A modificação de escrita copia b para b'. O b original continua referenciado pelo snapshot A. O contêiner agora vê a, b', c.
t2 — snapshot B
O snapshot B captura a, b', c. A e B compartilham a e c. Apenas b/b' diverge. Armazenamento total: 4 blocos, não 6.
Em execução ou parado — o estado do contêiner determina o tipo de snapshot.
Tire um snapshot enquanto em execução e você obtém os processos, memória, histórico do terminal, abas do navegador e conexões de rede junto com o sistema de arquivos. Tire um enquanto parado e você obtém apenas o sistema de arquivos. A chamada de API é a mesma; o tipo é automático.
Em execução → com estado
O estado completo da máquina, congelado.
- +Sistema de arquivos (tudo em / incluindo /hoody/*)
- +Processos em execução (PIDs, relações de parentesco)
- +Memória + dump de RAM
- +Histórico do terminal e sessões abertas
- +Abas do navegador e conteúdo de display ativo
- +Estado de conexão do banco de dados
- +Conexões de rede (sockets, TCP estabelecido)
- +Arquivos abertos (tabelas de fd)
- +Variáveis de ambiente
Parado → sem estado
Apenas sistema de arquivos. Restaurar = novo início a partir desse FS.
- ·Apenas sistema de arquivos
- ·Sem processos — a restauração inicia um contêiner frio
- ·Sem memória — sem dump de RAM no snapshot
- ·Sem estado de rede — as conexões precisam ser reestabelecidas
— A restauração é destrutiva: sobrescreve o estado ativo atual. Se quiser manter o estado presente, tire um snapshot dele primeiro, depois restaure o alvo.
Deixe o agente tentar. Mantenha o botão de desfazer.
LLMs que tocam em middleware de autenticação, migrações de banco de dados ou refatorações amplas se beneficiam mais do padrão de snapshot-antes-de-executar. Barato de criar. Rápido de restaurar. Uma chamada de API em cada direção.
Sem snapshots
- 1.O agente refatora seu middleware de autenticação. Os primeiros testes de fumaça passam.
- 2.Você faz merge e implanta. Tudo parece bem por dias.
- 3.Sessões começam a cair silenciosamente em produção.
- 4.Fazer bisect nos commits recentes do agente leva horas — a mudança está enterrada em um diff grande.
- 5.O rollback significa reverter manualmente cada PR do agente que foi mergeado e reimplantar.
Com snapshots do Hoody
- 1.Tire um snapshot do contêiner antes do agente executar. Dê a ele um alias como pre-auth-refactor.
- 2.Deixe o agente trabalhar. Ele edita arquivos, reinicia serviços, executa testes de fumaça.
- 3.Algo parece errado em produção uma semana depois.
- 4.PATCH /snapshots/pre-auth-refactor — o contêiner restaura para o estado pré-agente em 5–15s.
- 5.Com o serviço restaurado a partir do snapshot, você pode tirar um novo snapshot do estado quebrado para investigação offline.
O padrão de rede de segurança é o motivo pelo qual todo fluxo de trabalho assistido por IA — geração de código, refatoração de infraestrutura, migrações de banco de dados — deve ser executado dentro de um contêiner com snapshot. O snapshot é barato; o custo de descoberta de uma mudança ruim feita por IA, não.
O fluxo de trabalho é um grafo de commits para máquinas inteiras.
Tire um snapshot antes de uma mudança arriscada. Itere. Se o resultado for bom, continue — o snapshot é barato e expirável. Se quebrar, uma chamada PATCH coloca o contêiner de volta exatamente onde estava — RAM, processos, arquivos abertos e tudo mais.
t0 — baseline
POST /snapshots — marcado v1.4.0-pre
t1 — trabalho arriscado
Agente de IA refatora, migrações executam, serviços reiniciam
t2 — algo quebrou
Testes de fumaça falham. Precisa voltar.
t3 — restauração
PATCH /snapshots/v1.4.0-pre — restauração em 5–15s
t4 — idêntico ao t0
RAM, processos, FS correspondem ao t0. Sem drift.
PATCH /api/v1/containers/ID/snapshots/v1.4.0-preQuando o SSD é o gargalo, /ramdisk é a resposta.
Metade da memória do contêiner, acessível como /ramdisk, alocada sob demanda. Está lá quando você usa, desaparece quando não usa. Persiste durante a reinicialização do contêiner. Limpa na reinicialização do host.
⚠ O uso do /ramdisk conta contra a memória do contêiner. Se o contêiner tem 4 GB e /ramdisk ocupa 3 GB, a aplicação tem 1 GB para trabalhar. Monitore com `free -h` e limite com um design cuidadoso.
Cinco estratégias de snapshot que equipes realmente usam.
Escolha uma e sua disciplina de estado vira uma decisão de uma linha, não um documento de política. A maioria das equipes usa duas ou três em paralelo.
1 · Segurança pré-operação
Snapshot antes de qualquer coisa destrutiva: migrações, geração de código por IA, resposta a incidentes, hotfixes manuais.
2 · Marcos versionados
Snapshots com alias em pontos de release — v1.4.0, v1.5.0-rc. Expiração em semanas. Rollback instantâneo para qualquer versão nomeada.
3 · Automação diária
Snapshot via cron com expiração automática = histórico com auto-poda. Sete dias de ontem, trinta dias de últimos meses.
4 · Branching estilo Git
Snapshot + cópia de contêiner = uma linha do tempo alternativa em um projeto ou servidor diferente. Tente um caminho arriscado na cópia. Se funcionar, reconstrua o baseline lá; a sincronização é unidirecional, então a cópia é onde a nova verdade vive.
5 · Templates de imagem dourada
Crie um snapshot base, copie a partir do snapshot para cada novo contêiner de dev. O onboarding vira uma chamada POST.
Bônus · Preservação forense
Quando a produção é comprometida: tire um snapshot do estado comprometido para investigação, restaure a produção a partir de um snapshot limpo anterior, compare os dois offline. Resposta a incidentes sem perder evidências.
O que você teria que montar por conta própria.
Rollback, captura com estado, SQLite seguro para concorrência, compartilhamentos entre contêineres, espaço de rascunho em RAM — cada um tem uma resposta tradicional. Aqui está a comparação honesta lado a lado.
| Necessidade | Hoody Data & State | Stack tradicional |
|---|---|---|
| Reverter uma máquina inteira | PATCH /containers/ID/snapshots/NAME | Tarball + reimplantação manual + torcer |
| Capturar estado de memória em execução | Stateful snapshot (automatic) | VMware suspend + ferramentas customizadas |
| Compartilhamento de diretório entre contêineres | /hoody/shares + Shares API | Rodar servidor NFS ou SMB por conta própria |
| Escritas SQLite concorrentes | /hoody/databases (FUSE mount) | Reescrever sua camada de dados no Postgres |
| Espaço de rascunho em RAM | /ramdisk (ceiling 50% memory) | tmpfs + ulimits cuidadosos |
| Deduplicação de armazenamento entre contêineres similares | BTRFS copy-on-write (built in) | rsync --link-dest, política manual |
| Replicação de estado entre servidores | POST /containers/ID/copy + /sync | Loops rsync DIY + reinicialização de serviço |
Se você já está em um sistema gerenciado de snapshots de VM para uma carga de trabalho específica, continue lá para essa carga. O modelo de estado do Hoody ganha seu espaço quando o primitivo que você quer é de fato viagem no tempo ao nível de contêiner.
Seu estado já é um grafo de commits. Aprenda a usá-lo.
O sistema de arquivos já está lá. Os snapshots já estão lá. As montagens já estão lá. Suba um contêiner e o modelo de estado completo está ativo.
Veja também — /platform/control-plane para as APIs de snapshot e cópia/sincronização, /kit/files para backends em nuvem, /kit/sqlite para SQLite via HTTP.