Linux (servidor)
O manager é distribuído como uma imagem Docker (ongrid:<version>) e é operado através de docker compose. Ambos vêm do tarball de release produzido por make package — sem apt install ongrid, sem daemon host-side.
Distribuições suportadas
Rodamos o manager no dia-a-dia nos seguintes hosts. Qualquer coisa que rode Docker Engine 24+ deve funcionar; a lista abaixo é o que recebe teste explícito por release.
| Distribuição | Testado em |
|---|---|
| Ubuntu | 22.04 LTS, 24.04 LTS |
| Debian | 12 (bookworm) |
| RHEL | 9 |
| Rocky Linux | 9 |
| AlmaLinux | 9 |
CentOS 7 não é suportado — seu glibc e systemd são antigos demais para a stack Compose bundled e atingiram EOL upstream.
Software requerido
- Docker Engine 24.0 ou posterior. Releases mais antigas faltam plumbing de
--platformquemake docker-builddepende e quebramextra_hosts: host-gateway. - Docker Compose v2 (o plugin CLI
docker compose, não o binário legadodocker-compose). O compose file emdeploy/docker-compose.ymldeliberadamente omite a chave top-levelversion:, que v1 rejeita. - systemd para o host. O próprio manager não registra uma unit systemd — o script de instalação
deploy/install/server-install.shsó depende do systemd para iniciar o Docker — mas auto-restart em reboot precisa dedocker.servicehabilitado. - iptables / nftables está OK; ambos os backends funcionam.
Sem módulos de kernel requeridos além do que o próprio Docker precisa (overlayfs, namespaces, cgroups v1 ou v2).
Floors de recursos
| Recurso | Floor | Confortável | Por quê |
|---|---|---|---|
| CPU | 2 vCPU | 4 vCPU | O processo Go do manager, Prometheus, Loki, Tempo, Grafana, MySQL todos vivem no mesmo host. |
| Memória | 4 GB | 8 GB | Prometheus + Loki juntos podem bater 1.5 GB em idle. Headroom mantém o OOM killer longe do MySQL. |
| Disco | 20 GB | 100 GB | Retenção do Prometheus é 90 dias / 20 GB por padrão (veja --storage.tsdb.retention.* no compose file). Loki + Tempo compartilham o resto. |
| Rede | 10 Mbps | 100 Mbps | Telemetria é o data plane — shipping de log de muitos edges pode saturar um pipe fino bem antes do próprio manager. |
O floor de 20 GB assume que você só testa com um punhado de edges. Uma vez que você atravessa ~25 hosts enviando metrics + logs + traces, planeje 200 GB só para manter 30 dias de Loki.
Portas
| Porta | Direção | Protocolo | O que é |
|---|---|---|---|
| 443 | inbound | HTTPS | nginx — SPA, REST API, ingest de log/trace |
| 80 | inbound | HTTP | redirect do nginx para 443 |
| 40012 | inbound | TCP (geminio) | Broker Frontier — cada edge disca isso |
| 3306 | exposto localmente | TCP | MySQL — bind em 127.0.0.1 em produção |
| 9090 | exposto localmente | HTTP | Prometheus — bind em 127.0.0.1 em produção |
| 9100 | inbound (opcional) | HTTP | /metrics do manager — para um Prometheus externo raspar |
Apenas 443, 80, e 40012 precisam ser alcançáveis da internet pública (ou da rede da sua frota de edges). Tudo mais fica vinculado ao localhost em produção — nginx frenteia a API, e Grafana / Prometheus / Loki / Tempo são alcançados pela rede docker.
O que a stack compose roda
De deploy/docker-compose.yml:
| Serviço | Imagem | Papel |
|---|---|---|
mysql | mysql:8.0 | Store primário do manager (users, edges, devices, alert rules, sessions). |
ongrid | ongrid:<version> | Manager — binário Go buildado de cmd/ongrid. |
nginx | ongrid-web:<version> | Terminação TLS, SPA, reverse proxy /api/*, estático /edge/* para o bundle de install. |
frontier | singchia/frontier:1.2.5 | Broker geminio; endpoint de tunnel do edge (ADR-007). |
prometheus | prom/prometheus:v2.54.0 | Store de métrica + receiver remote_write (ADR-009). |
loki | grafana/loki:3.4.0 | Store de log (ADR-012). |
tempo | grafana/tempo:2.5.0 | Store de trace (ADR-013). |
searxng | searxng/searxng:latest | Backend de busca self-hosted para a skill web_search. |
grafana | grafana/grafana-oss:11.1.4 | Embed de dashboard para a página Monitor. |
O compose file é o formato de produção — não há um segundo arquivo "prod". Sobrescreva knobs via o bloco env (ONGRID_* — veja Variáveis de ambiente) em vez de forkar o YAML.
TLS
O nginx termina TLS usando certificados bind-mounted de deploy/certs/ (cert.pem, key.pem). Para o primeiro boot o script de instalação gera um cert self-signed; substitua por um cert real a qualquer momento e docker compose restart nginx. Let's Encrypt é suportado via um padrão sidecar documentado em deploy/README.md.
Selinux + AppArmor
Ambos funcionam de fábrica. O compose file não monta paths sensíveis do host read-write; os bind mounts (./edge, ./nginx, ./certs, ./grafana/provisioning) são todos :ro. Se sua política SELinux impõe labels estritas em bind mounts, anexe :Z às strings de mount dentro de docker-compose.override.yml.
Fazendo upgrade
make package # produz dist/out/ongrid-vX.Y.Z-linux-amd64.tar.xz
scp dist/out/ongrid-vX.Y.Z-linux-amd64.tar.xz host:/tmp/
ssh host /tmp/upgrade.shupgrade.sh vive ao lado do tarball e faz a dança idempotente: carrega a imagem nova, escreve um docker-compose.override.yml temporário fixando a tag nova, docker compose up -d, prune da imagem anterior depois de um minuto saudável. Veja Upgrade.
O que NÃO funciona
- Podman + podman-compose: o compose file usa atalho Docker-específico (
extra_hosts: host-gateway, semântica SELinux:Z) que o podman ou parseia de forma incompatível ou ignora. Não testamos. - K3s host-mode networking: funciona para o manager, mas o instalador do edge é construído em torno de systemd bare — veja Kubernetes para o padrão daemonset.
- OpenRC / runit / s6: o container do manager não se importa, mas o daemon Docker do host precisa subir no boot. Se seu init system consegue fazer isso, você está OK.