Docker Commander

Servidor MCP seguro de monitoramento e gerenciamento de Docker para containers, logs, alertas, diagnósticos e controle seguro em hosts locais e remotos.

Documentação

Docker Commander

Um painel de monitoramento e controle do Docker auto-hospedado e de código aberto, com uma interface de nível empresarial — monitore contêineres em tempo real, controle todo o ciclo de vida deles, navegue por logs e arquivos, gerencie imagens, redes e volumes, receba alertas sobre problemas e administre tudo a partir de um único binário.

Um único binário Go com a interface web embutida. Sem banco de dados externo, sem dependências em tempo de execução, sem CGO. Funciona em Linux, macOS e Windows.

🌐 docker-commander.app — a página inicial do projeto. · Documentação · Versões · Patrocinar

CI Release Go version License: MIT


📸 Capturas de tela

Painel principal — visão geral do host, uso de disco e contêineres em execução de relance.

Dashboard

Detalhes do contêiner — CPU/memória ao vivo com histórico e abas para logs, um console interativo, processos, navegador de arquivos, alterações no sistema de arquivos e variáveis de ambiente.

Container detail

Logs agregados — muitos contêineres em um único fluxo, com código de cores por origem, filtros de nível, busca por expressão regular e análise estruturada.

Aggregated logs

✨ Recursos

Monitoramento

  • Gráficos ao vivo de CPU/memória via WebSockets e gráficos históricos (Redis ou em memória).
  • Painel principal que atualiza quase em tempo real (fluxo de eventos do Docker): informações do host, uso de disco, um detalhamento de recursos (a participação de cada contêiner na CPU/memória do host, além da taxa de transferência de rede de todo o host) e uma varredura de portas que identifica o que está realmente escutando.
  • Telemetria de rede — taxa RX/TX por contêiner (derivada, de modo que uma redefinição de contador ao recriar aparece como uma lacuna, não como um pico), totais, pacotes / descartados / erros e o detalhamento por interface, além de totais por endpoint no detalhe de uma rede — rotulados pelo que são, já que o Docker não informa contadores por rede.
  • Logs — cauda por contêiner, além de uma visão global agregada com detecção de nível, busca por expressão regular e regras de análise salvas que transformam linhas em colunas estruturadas.
  • Fluxo de eventos ao vivo, diff / top de contêiner, uso de disco e inspeção JSON bruta de qualquer objeto.
  • Redes e topologia — um grafo interativo de contêineres ↔ redes (com força direcionada, pan/zoom/tela cheia, busca, filtro por pilha compose) e uma visão em lista compacta (estado, imagem, pilha, portas, redes).

Controle

  • Contêineres: criar/executar, iniciar/parar/reiniciar/pausar/despausar/matar, renomear, atualizar limites e política de reinício, commit para uma imagem, um shell interativo (xterm.js) e reinício/parada em massa em uma seleção múltipla (pré-visualização, confirmação, paralelismo limitado, resumo de sucesso/falha por contêiner).
  • Navegador de arquivos dentro de contêineres e volumes — listar, baixar, enviar (incluindo enviar e extrair um .zip/.tar/.tar.gz), excluir, criar pastas.
  • Imagens: baixar (progresso ao vivo), construir, enviar, marcar, salvar/carregar/importar, histórico, limpeza e verificação de vulnerabilidades (Trivy — resumo por gravidade + tabela de CVEs).
  • Volumes e redes: listar, inspecionar, criar, remover, limpar; as redes também conectam/desconectam contêineres, com um detalhe por rede (grafo ou lista).
  • Compose — descubra e gerencie pilhas por rótulo (inclusive as criadas via CLI: iniciar/parar/reiniciar/remover e editar o arquivo compose no host e reimplantar — mantido onde está, para que caminhos relativos de bind/env_file/build.context continuem resolvendo), e Projetos: pastas compose gerenciadas, editadas em um editor de código integrado (CodeMirror) com validação ao vivo e inline — compose (ciente de âncoras/${VAR}), Dockerfile (docker build --check), YAML/JSON/.env — além de uma pré-visualização Resolvida, um Resumo de serviços/portas, modelos, autocompletar Compose ciente do esquema e sugestões de nome de imagem / tag (locais, Docker Hub e registros privados configurados), e implantação via CLI docker compose com perfis (o resumo mostra o estado real de cada serviço e separa claramente o que está atualmente implantado do que está selecionado para a próxima implantação, de modo que um serviço excluído por perfil apareça como tal — não como parado) e importação/exportação .zip — para o host local ou remoto (uma implantação remota copia os configs/scripts montados por bind do projeto para volumes nesse host, e os contextos build: são enviados com a construção; uma reimplantação reconstrói uma imagem editada).

Multi-host

  • Gerencie daemons locais, TCP(+TLS) e SSH; as chaves de host SSH são verificadas (known_hosts / confiança no primeiro uso). Cada visão é vinculada ao host selecionado, e o mecanismo de alertas monitora todos os hosts. Um painel de detalhes por host mostra o hardware/SO/mecanismo, e um host pode ser desativado para sair do monitoramento (por exemplo, um laptop offline).

Alertas e integrações

  • Regras sobre estado, limites de recursos, padrões de log e reinícios/ciclos de falha — editáveis, com gravidade e intervalo de espera.
  • Alertas de limite são condições com duração (firing → escalated/eased → resolved), uma por contêiner + métrica, de modo que regras sobrepostas gerem um único incidente em vez de um para cada — e o feed é paginado, filtrado e ordenado no servidor, com quem reconheceu e cada tentativa de entrega registrada contra ele.
  • Notifique via webhooks, e-mail (SMTP, roteamento por host), um feed no aplicativo e um exportador Prometheus /metrics. Regras importadas/exportadas como um pacote JSON portátil.

Controle remoto por ferramentas de IA (MCP)

  • Um servidor Model Context Protocol opcional, desativado por padrão, permite que ferramentas de IA (Claude Code, Claude Desktop, Cursor) monitorem e operem com segurança o Docker como você: ferramentas de leitura (contêineres, logs, imagens, projetos, estatísticas, eventos, auditoria…), diagnósticos sem shell (docker top / diff, busca de logs entre contêineres), a superfície de alertas (histórico, o que está disparando agora, regras, se um alerta foi realmente entregue, reconhecimento) e controle seguro (iniciar/parar/reiniciar um contêiner ou uma pilha inteira, implantar/derrubar um projeto — inclusive um que tenha como alvo um host remoto — além de uma pré-visualização do que uma implantação mudaria e uma verificação de imagem Trivy), com recursos e prompts MCP.
  • Autentique com um token de API bearer (página de autoatendimento) ou OAuth 2.1 (PKCE, registro dinâmico de clientes). Cada chamada reutiliza o RBAC do aplicativo, e um token só pode restringir seus direitos (um subconjunto de suas seções e dos hosts que você alcança, além de somente leitura). Novos tokens expiram após 30 dias por padrão (configurável pelo administrador, com tokens sem expiração desativados, a menos que habilitados). Alterações são limitadas por taxa (30/min por usuário; leituras não são), de modo que um modelo preso em um loop — ou um token roubado — fica limitado a alguns contêineres em vez de todo o seu ambiente, e atingir esse teto é auditado. Deliberadamente sem exec / exportação de imagem / leitura de arquivo / limpeza / remoção. Veja MCP.

Segurança e administração

  • Senhas Argon2id + 2FA TOTP ou chaves de acesso (WebAuthn — resistentes a phishing e oferecidas onde o navegador permitir: HTTPS ou localhost; uma chave de acesso que verifica você com PIN ou biometria também pode entrar sozinha depois que você ativar isso, com a senha ainda disponível como caminho de volta se a chave for perdida), opcionalmente dispensadas para localhost, com vários autenticadores por conta — pareie o novo telefone antes de apagar o antigo; o último não pode ser removido. Limitação de taxa, cabeçalhos rígidos, cookies HttpOnly assinados. Todos podem ver o que está conectado como sua conta — endereço, navegador, último uso — e desconectar qualquer item, ou tudo o mais, pelo perfil.
  • Multiusuário com funções, permissões por seção, modo somente leitura, sinalizadores de recurso globais e um log de auditoria. Preferências de interface por usuário (filtros) acompanham a conta entre navegadores.
  • Login opcional por LDAP / Active Directory com provisionamento automático e mapeamento de grupos — um grupo de diretório concede funções nomeadas (ou seções brutas), rederivadas a cada login, de modo que a associação dirija as permissões. Segredos de registro / SMTP / LDAP e chaves privadas TLS do host são criptografados em repouso (AES-256-GCM).

Operações

  • Um único binário sem CGO, interface embutida, unidade systemd, arquivo de configuração, HTTPS nativo (auxiliar integrado de certificado autoassinado --make-certs, ou atrás de um proxy), sonda /healthz e registro estruturado de alertas no journal/syslog. Veja Implantação.
  • Autoatualização — atualização e reinício no aplicativo com um toque para administradores (e um banner de "atualização disponível"), além do comando dockercmd --self-upgrade (verificado por SHA-256, substituição atômica do binário).

🏗️ Arquitetura

React + TypeScript SPA  ──REST──▶  Go backend  ──Docker Engine API──▶  dockerd
   (Tailwind, Recharts)  ◀─WebSocket (live stats + logs)─┘

O servidor Go embute o SPA compilado (go:embed) e serve tudo a partir de uma única origem, de modo que o artefato de produção é um único executável.

CamadaTecnologia
BackendGo, chi, coder/websocket, SDK oficial do Docker
ArmazenamentoSQLite via modernc.org/sqlite (Go puro, sem CGO); histórico de métricas em Redis ou memória
AutenticaçãoArgon2id, TOTP (pquerna/otp), JWT, LDAP opcional
FrontendReact, TypeScript, Vite, Tailwind CSS, Recharts, React Flow, xterm.js

🐳 Versões do Docker

O aplicativo fala com o Docker de duas maneiras: a Engine API por meio do SDK oficial do Go e a CLI docker compose como subprocesso para implantações de projetos. Ambas evoluem, e você executa o que sua distribuição fornece — então aqui está o que é realmente testado, não o que se espera que funcione.

Versão
API mínima da Engine1.43 (Docker Engine 24)
Versões principais da Engine testadas24, 25, 26, 27, 28 (noturno; veja as execuções do workflow para o resultado atual)
Patches da Engine testadosalgumas versões exatas de patch das versões principais mais recentes também são fixadas e testadas noturnamente, independentemente das tags principais flutuantes (veja as execuções do workflow para as versões exatas atuais)
Composeo plugin docker compose, v2 ou mais recente (o legado docker-compose v1 não é suportado); algumas versões recentes de v2 são fixadas e testadas noturnamente (veja as execuções do workflow)
SDK do clientefixado em go.mod, negociado para baixo até o daemon no momento da conexão

O SDK chama WithAPIVersionNegotiation(), então um cliente mais novo fala o que o daemon entender — você não precisa igualar versões. Abaixo da API 1.43, o aplicativo não é testado nem declarado como funcional.

Esses números são medidos, não lembrados: o workflow de compatibilidade executa toda a suíte de integração Docker do aplicativo contra um docker:NN-dind fixado para cada versão principal, noturnamente e sob demanda, e imprime a versão de API negociada — além da versão do Compose com a qual rodou — para cada execução. Três eixos são fixados: cada versão principal da Engine é testada contra a mais recente de um pequeno conjunto de versões recentes do Compose, a versão principal mais recente da Engine é adicionalmente testada contra as mais antigas desse conjunto, e algumas versões exatas de patch da Engine (docker:X.Y.Z-dind, não apenas docker:NN-dind) também são fixadas e testadas — já que a tag principal simples sempre flutua para o patch mais recente quando é baixada, ela sozinha não pode provar que um patch específico é bom, apenas que o mais recente atualmente é. Portanto, a matriz responde "quais daemons funcionam", "quais versões recentes do Compose funcionam" e "este patch exato da Engine funciona", sem um produto cruzado completo Engine × Compose. Reproduza qualquer linha localmente:

docker run -d --name dc-compat --privileged -e DOCKER_TLS_CERTDIR="" \
  -p 127.0.0.1:12375:2375 docker:24-dind --host=tcp://0.0.0.0:2375 --tls=false
DC_COMPAT_DOCKER=tcp://127.0.0.1:12375 DOCKER_HOST=tcp://127.0.0.1:12375 \
  go test -count=1 -run 'TestIntegration|TestCompat' ./internal/docker/

Ambas as variáveis importam: DC_COMPAT_DOCKER aponta o aplicativo para o daemon, DOCKER_HOST aponta a CLI do Compose para o mesmo. Defina apenas a primeira e os testes do Compose implantarão no seu próprio daemon e ficarão esperando por contêineres que iniciaram em outro lugar.

🚀 Início rápido

Opção A — baixar um binário de versão

Pegue o binário para seu SO/arquitetura na página Releases e então:

chmod +x dockercmd-linux-amd64
./dockercmd-linux-amd64           # serves on http://127.0.0.1:8470

No Windows, execute dockercmd-windows-amd64.exe a partir de um terminal.

Usuários de Debian/Ubuntu e Fedora podem pegar um .deb / .rpm na mesma página — ele configura o serviço systemd. Veja Deployment → packages.

Opção B — Homebrew (macOS e Linux)

brew install koduj-dev/tap/dockercmd
dockercmd --version

Instala o binário de release assinado para seu SO/arquitetura a partir do koduj-dev/homebrew-tap.

Opção C — compilar a partir do código-fonte

Requer Go ≥ 1.26, Node.js ≥ 18 (para compilar a interface) e um daemon Docker em execução. Veja Building para detalhes por SO.

git clone https://github.com/koduj-dev/docker-commander.git
cd docker-commander
make build      # builds the UI, then the binary with the UI embedded
./dockercmd     # http://127.0.0.1:8470

Opção D — Docker

docker run -d --name dockercmd \
  -p 127.0.0.1:8470:8470 \
  --group-add "$(stat -c '%g' /var/run/docker.sock 2>/dev/null || stat -f '%g' /var/run/docker.sock)" \
  --read-only --tmpfs /tmp \
  --security-opt no-new-privileges \
  --cap-drop ALL \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v dockercmd-data:/data \
  ghcr.io/koduj-dev/docker-commander:latest

Multi-arquitetura (amd64/arm64), distroless, executa como usuário não-root com sistema de arquivos raiz somente leitura e sem capabilities adicionadas. Notas:

  • ⚠️ Montar o socket do Docker concede acesso equivalente ao root do host — quem acessa a interface (ou escapa do aplicativo) controla o daemon, ou seja, o host. Mantenha a interface em localhost (como acima) ou atrás de HTTPS + autenticação forte; nunca a exponha sem autenticação. A linha --group-add dá ao usuário não-root o GID proprietário do socket do Docker — lido do próprio /var/run/docker.sock (stat, com fallback para BSD), então funciona mesmo sem um grupo docker. Em rootless / Docker Desktop, onde o socket pertence ao seu usuário, remova a linha --group-add.
  • Os dados ficam no volume nomeado dockercmd-data (um novo herda a propriedade correta). Um bind mount (-v /srv/dc:/data) deve ser gravável pelo uid 65532 primeiro: sudo chown 65532:65532 /srv/dc.
  • Em produção, fixe um digest imutável (...@sha256:…) em vez de :latest, e verifique a imagem (veja abaixo).

Opção E — go install

go install github.com/koduj-dev/docker-commander/cmd/dockercmd@latest

Instala em $(go env GOPATH)/bin/dockercmd. (Compilado desta forma, a versão reporta dev; os binários de release e a imagem carregam a versão real.)

Verificando um download

Cada release inclui um SHA256SUMS além de um pacote de assinatura cosign sem chave (SHA256SUMS.bundle) cobrindo os binários e o SBOM SPDX, além de proveniência de build por binário:

sha256sum -c SHA256SUMS --ignore-missing        # checksums (binaries + SBOM)

cosign verify-blob --bundle SHA256SUMS.bundle \
  --certificate-identity-regexp '^https://github\.com/koduj-dev/docker-commander/\.github/workflows/release\.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMS

gh attestation verify dockercmd-linux-amd64 --repo koduj-dev/docker-commander

Verificar o pacote requer cosign v3+. Releases até e incluindo v1.5.0 foram assinados com cosign v2 e incluem um par SHA256SUMS.sig / SHA256SUMS.pem — verifique-os com cosign verify-blob --certificate SHA256SUMS.pem --signature SHA256SUMS.sig ….

A imagem do contêiner é assinada e carrega proveniência SLSA + um SBOM também:

# verify the exact digest you'll run (copy it from the release notes or
# `docker buildx imagetools inspect ghcr.io/koduj-dev/docker-commander:latest`):
IMAGE=ghcr.io/koduj-dev/docker-commander@sha256:<digest>
cosign verify "$IMAGE" \
  --certificate-identity-regexp '^https://github\.com/koduj-dev/docker-commander/\.github/workflows/release\.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

gh attestation verify "oci://$IMAGE" --repo koduj-dev/docker-commander

Abra http://127.0.0.1:8470, crie a conta de administrador, escaneie o código QR para ativar 2FA — pronto.

⚙️ Configuração

Cada opção é uma flag com equivalente em variável de ambiente, e também pode ficar em um arquivo de configuração — veja deploy/commander.conf.example para a lista completa. A conexão Docker também respeita as variáveis padrão DOCKER_HOST / DOCKER_CERT_PATH.

FlagEnvPadrãoDescrição
-hostDC_HOST127.0.0.1Host/interface de escuta. Use 0.0.0.0 para vincular a todos (deliberado).
-port / -pDC_PORT8470Porta de escuta.
-addrDC_ADDR(não definido)host:port completo legado; substitui -host/-port.
-tls-certDC_TLS_CERT(desativado)Caminho do certificado PEM; com -tls-key, serve HTTPS diretamente.
-tls-keyDC_TLS_KEY(desativado)Caminho da chave privada PEM.
-mcp-enabledDC_MCP_ENABLED=1offAtiva o servidor MCP remoto para ferramentas de IA. Desativado por padrão; sirva atrás de HTTPS. Veja MCP.
-mcp-public-urlDC_MCP_PUBLIC_URL(não definido)URL base acessível externamente (https://host) — necessária para o fluxo OAuth do MCP (tokens bearer funcionam sem ela).
-data-dirDC_DATA_DIRDiretório de config do SOBanco SQLite + chaves de assinatura/criptografia.
-session-ttl—12hTempo de vida do token de sessão.
-devDC_DEV=1offModo dev: apenas API + CORS permissivo para Vite.
-metrics-tokenDC_METRICS_TOKEN(aberto)Se definido, /metrics precisa de Authorization: Bearer <token> (ou ?token=).
-redis-addrDC_REDIS_ADDR(memória)host:port Redis para histórico de métricas; vazio = anel em memória.
-redis-passwordDC_REDIS_PASSWORD(vazio)Senha do Redis; DC_REDIS_DB seleciona o índice do banco.
-metrics-retentionDC_METRICS_RETENTION6hRetenção de histórico (ex.: 30m, 24h).
-trusted-proxiesDC_TRUSTED_PROXIES(nenhum)IPs/CIDRs de proxy reverso cujo X-Forwarded-For pode ser confiável. O IP do cliente chaveia limites de taxa, a isenção de 2FA em localhost e registros de auditoria — defina-o atrás de um proxy, e nunca para um intervalo que você não controla.
-self-updateDC_SELF_UPDATEonPermite que administradores apliquem uma atualização pela interface web. 0 mantém o banner "atualização disponível" mas proíbe auto-substituição acionada pela web.

🖥️ Executar como serviço

O servidor mantém monitoramento, alertas e histórico de métricas em execução 24/7, esteja um navegador conectado ou não — então execute-o como um serviço em segundo plano. Em Linux/macOS/Windows, o binário se instala sozinho:

sudo ./dockercmd --install-service     # Linux — systemd (needs root)
./dockercmd --install-service          # macOS — launchd LaunchAgent (your user, not sudo)
dockercmd.exe --install-service        # Windows — native SCM service (elevated PowerShell/cmd)

Ele cria um usuário dedicado (ou, no Windows, registra no Service Control Manager), escreve a definição de serviço (endurecida) e o inicia. Para ler exatamente o que é instalado, use os scripts equivalentes em deploy/:

sudo ./deploy/install-linux.sh ./dockercmd                  # Linux  — systemd
./deploy/install-macos.sh ./dockercmd                       # macOS  — launchd
.\deploy\install-windows.ps1 -BinPath .\dockercmd.exe       # Windows — Scheduled Task (elevated PowerShell)

O script de Tarefa Agendada do Windows permanece como alternativa sem dependências ao serviço nativo do SCM acima.

Veja Deployment para o que cada instalador faz, os passos manuais de systemd, HTTPS, logs e a referência de configuração.

Ele vincula ao loopback por padrão — coloque-o atrás de um proxy reverso TLS (nginx, Caddy) para expô-lo, e mantenha a isenção de 2FA em localhost desativada em servidores.

🔨 Compilação

A interface é compilada com Node e embutida no binário Go; o resultado é um único executável estático sem CGO.

make build          # current platform → ./dockercmd
make release        # cross-compile all platforms → dist-bin/ (+ SHA256SUMS)
make test vet       # tests + static checks
VERSION=v1.0.0 make release   # stamp the version into the binary

Por SO (compilando a partir do código-fonte — usuários finais podem apenas baixar uma release):

SO do hostNotas
Linuxmake build. Alvo padrão para releases.
macOSmake build (Intel ou Apple Silicon). Compila cruzado para darwin/amd64 e darwin/arm64.
WindowsUse WSL ou Git Bash para make, ou execute os dois passos manualmente: cd web && npm ci && npm run build e depois go build -o dockercmd.exe ./cmd/dockercmd. Releases incluem windows/amd64 + windows/arm64 .exe.

make release compila linux/{amd64,arm64}, darwin/{amd64,arm64} e windows/{amd64,arm64} de qualquer host (sem necessidade de toolchain C).

🧑‍💻 Desenvolvimento

make dev                       # API on :8470 (dev mode)
cd web && npm ci && npm run dev        # UI on :5173, proxies /api → :8470

Testes

go test -short ./...   # fast unit tests (what CI runs)
go test ./...          # + integration tests — needs a local Docker daemon
                       #   (spins throwaway Redis / OpenLDAP / MailHog containers)

📈 Monitoramento e alertas

Defina regras na tela Alerts:

TipoDispara quando…
stateum contêiner emite um evento de ciclo de vida (die, kill, oom, stop, unhealthy)
resourceCPU% ou MEM% cruza um limite por N segundos
loguma linha de log corresponde a uma substring / regex
restartum contêiner reinicia com muita frequência dentro de uma janela (crash loop)

Regras segmentam contêineres por substring do nome, carregam severidade + cooldown, e podem notificar webhooks (corpos em Go-template) e/ou e-mail. Prometheus: colete /metrics para dockercmd_container_cpu_percent, _mem_bytes, _mem_percent, _container_running (rotulados por id, name, host).

🔒 Notas de segurança

  • Local por padrão (vincula ao loopback). Atrás de um servidor, termine TLS em um proxy reverso.
  • 2FA é aplicada em todos os lugares a menos que um administrador ative a isenção de localhost (Configurações), que se aplica apenas a uma conexão direta de loopback — uma solicitação via proxy nunca se qualifica, independentemente de como se apresenta. Tentativas de 2FA com falha são limitadas por taxa e auditadas, então o segundo fator não pode ser forçado por força bruta por alguém que já tem a senha.
  • Passkeys estão vinculadas ao endereço deste site. Uma página que se passa por esta não pode usar uma asserção que captura, e um contador de assinatura que regride — sinal de chave clonada — é recusado e auditado.
  • Sessões são revogáveis. Uma sessão é uma linha registrada, não apenas um token assinado: sair, revogar uma do seu perfil, ou mudar sua senha tem efeito na próxima solicitação em vez de quando o token expiraria.
  • Hosts SSH verificam a chave de host do daemon (known_hosts / trust-on-first-use); uma chave alterada é recusada como possível MITM.
  • A chave de assinatura e a chave de criptografia em repouso são geradas na primeira execução e armazenadas no diretório de dados; segredos armazenados nunca são retornados pela API.
  • O servidor MCP está desativado por padrão (DC_MCP_ENABLED); quando ativado, é autenticado por bearer/OAuth, reutiliza o RBAC do aplicativo (com escopo somente leitura / por seção por token), e expõe apenas leituras + controle seguro — sem exec, exportação de imagem, leitura de arquivos ou prune/remove. Chamadas de controle são adicionalmente limitadas por taxa por usuário para limitar o dano que um token descontrolado ou roubado pode causar. Veja MCP.

🧪 Como é testado

Você está apontando isso para daemons Docker reais, então os testes rápidos são o piso, não o teto. Junto com ~670 testes unitários Go e ~190 testes de frontend, o repositório carrega 115 casos "pentest" adversariais que afirmam que ataques são rejeitados (forja de token, replay OAuth, CSRF, IDOR, bypass de escopo por host, escalonamento de privilégio, path traversal), uma camada de integração contra um daemon Docker real (além de Redis / OpenLDAP / SMTP descartáveis), e uma camada de ponta a ponta que implanta em daemons separados via TCP e SSH — porque um daemon simulado não pode dizer se uma implantação remota funciona.

Além dos testes, a árvore é varrida periodicamente por uma revisão adversarial no Claude Fable 5 — revisores independentes por trilha (auth e criptografia, autorização, entrada não confiável, correção de backend, frontend), cada um instruído a refutar uma descoberta antes de reportá-la. Não é uma camada e não protege nada por si só: uma descoberta conta apenas quando vira uma correção mais o teste que falha sem ela.

CI executa as camadas determinísticas; as apoiadas por daemon são executadas pelo desenvolvedor. docs/testing.md detalha cada camada, como executá-la, e o que é deliberadamente não coberto.

📚 Documentação

Um manual do usuário por recurso vive em docs/ — uma página por agenda (Containers, Images, Logs, Alerts, Hosts, Users, Settings…) além de Getting started, Deployment e How it's tested.

🗺️ Roadmap e changelog

Veja NEXT.md para o status e ideias futuras, e CHANGELOG.md para o que foi lançado em cada release.

🤝 Contribuindo

Issues e pull requests são bem-vindos! Veja CONTRIBUTING.md para diretrizes de build/teste/estilo, CODE_OF_CONDUCT.md, e SECURITY.md para reportar vulnerabilidades (em particular, por favor).

🤖 Feito com IA

Aproximadamente 95 % deste projeto foi construído com IA (Claude Code) — código, testes e documentação — sob direção e revisão humana. 🎉

📄 Licença

MIT.