Linux (server)
El manager se distribuye como una imagen Docker (ongrid:<version>) y se opera a través de docker compose. Ambos vienen del tarball de release producido por make package — sin apt install ongrid, sin daemon host-side.
Distribuciones soportadas
Corremos el manager día a día en los siguientes hosts. Cualquier cosa que corra Docker Engine 24+ debería funcionar; la lista de abajo es lo que se testea explícitamente por release.
| Distribución | Testeado en |
|---|---|
| Ubuntu | 22.04 LTS, 24.04 LTS |
| Debian | 12 (bookworm) |
| RHEL | 9 |
| Rocky Linux | 9 |
| AlmaLinux | 9 |
CentOS 7 no está soportado — su glibc y systemd son demasiado viejos para el stack Compose bundled y han llegado a EOL upstream.
Software requerido
- Docker Engine 24.0 o posterior. Las releases más viejas no tienen la plomería
--platformen la que confíamake docker-buildy rompenextra_hosts: host-gateway. - Docker Compose v2 (el plugin CLI
docker compose, no el binario legacydocker-compose). El archivo compose endeploy/docker-compose.ymldeliberadamente omite la key top-levelversion:, que v1 rechaza. - systemd para el host. El propio manager no registra una unit systemd — el script de install
deploy/install/server-install.shsolo se apoya en systemd para arrancar Docker — pero auto-restart en reboot necesitadocker.servicehabilitado. - iptables / nftables está bien; ambos backends funcionan.
Sin módulos de kernel requeridos más allá de lo que el propio Docker necesita (overlayfs, namespaces, cgroups v1 o v2).
Pisos de recursos
| Recurso | Piso | Cómodo | Por qué |
|---|---|---|---|
| CPU | 2 vCPU | 4 vCPU | El proceso Go del manager, Prometheus, Loki, Tempo, Grafana, MySQL todos viven en el mismo host. |
| Memoria | 4 GB | 8 GB | Prometheus + Loki juntos pueden pegar 1.5 GB en idle. El espacio mantiene al OOM killer lejos de MySQL. |
| Disco | 20 GB | 100 GB | La retención de Prometheus es 90 días / 20 GB por defecto (ver --storage.tsdb.retention.* en el archivo compose). Loki + Tempo comparten el resto. |
| Red | 10 Mbps | 100 Mbps | La telemetría es el data plane — el shipping de logs desde muchos edges puede saturar un caño delgado mucho antes que el propio manager. |
El piso de 20 GB asume que solo testeas con un puñado de edges. Una vez que cruzas ~25 hosts enviando métricas + logs + trazas, planea 200 GB solo para mantener 30 días de Loki.
Puertos
| Puerto | Dirección | Protocolo | Qué es |
|---|---|---|---|
| 443 | entrante | HTTPS | nginx — SPA, REST API, ingest de log/traza |
| 80 | entrante | HTTP | redirect de nginx a 443 |
| 40012 | entrante | TCP (geminio) | Broker frontier — cada edge marca a esto |
| 3306 | expuesto localmente | TCP | MySQL — bind a 127.0.0.1 en producción |
| 9090 | expuesto localmente | HTTP | Prometheus — bind a 127.0.0.1 en producción |
| 9100 | entrante (opcional) | HTTP | /metrics del manager — para un Prometheus externo que scrapee |
Solo 443, 80 y 40012 necesitan ser alcanzables desde internet público (o la red de tu flota de edges). Todo lo demás se queda bindeado a localhost en producción — nginx pone la cara al API, y Grafana / Prometheus / Loki / Tempo se alcanzan sobre la red docker.
Qué corre el stack compose
De deploy/docker-compose.yml:
| Servicio | Imagen | Rol |
|---|---|---|
mysql | mysql:8.0 | Store primario del manager (usuarios, edges, devices, reglas de alerta, sesiones). |
ongrid | ongrid:<version> | Manager — binario Go construido desde cmd/ongrid. |
nginx | ongrid-web:<version> | Terminación TLS, SPA, reverse proxy /api/*, /edge/* estático para el bundle de install. |
frontier | singchia/frontier:1.2.5 | Broker geminio; endpoint del túnel del edge (ADR-007). |
prometheus | prom/prometheus:v2.54.0 | Store de métricas + receptor remote_write (ADR-009). |
loki | grafana/loki:3.4.0 | Store de logs (ADR-012). |
tempo | grafana/tempo:2.5.0 | Store de trazas (ADR-013). |
searxng | searxng/searxng:latest | Backend de búsqueda self-hosted para el skill web_search. |
grafana | grafana/grafana-oss:11.1.4 | Embed de dashboard para la página Monitor. |
El archivo compose es la forma de producción — no hay un segundo archivo "prod". Sobrescribe perillas vía el bloque env (ONGRID_* — ver Variables de entorno) en vez de forkear el YAML.
TLS
nginx termina TLS usando certificados bind-mounted desde deploy/certs/ (cert.pem, key.pem). Para el primer boot el install script genera un cert autofirmado; sustitúyelo por un cert real en cualquier momento y docker compose restart nginx. Let's Encrypt está soportado vía un patrón sidecar documentado en deploy/README.md.
Selinux + AppArmor
Ambos funcionan de fábrica. El archivo compose no monta paths host sensibles read-write; los bind mounts (./edge, ./nginx, ./certs, ./grafana/provisioning) son todos :ro. Si tu política SELinux refuerza labels estrictas en bind mounts, anexa :Z a los strings de mount dentro de docker-compose.override.yml.
Upgradear
make package # produces 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 al lado del tarball y hace el baile idempotente: carga la nueva imagen, escribe un docker-compose.override.yml temporal pineando el nuevo tag, docker compose up -d, prune de la imagen previa después de un minuto sano. Ver Upgrade.
Qué NO funciona
- Podman + podman-compose: el archivo compose usa shorthand Docker-específico (
extra_hosts: host-gateway, semántica SELinux:Z) que podman o parsea incompatiblemente o ignora. No testeamos. - Networking host-mode de K3s: funciona para el manager, pero el installer de edge está construido alrededor de systemd desnudo — ver Kubernetes para el patrón daemonset.
- OpenRC / runit / s6: al contenedor del manager no le importa, pero el daemon Docker del host necesita arrancar en boot. Si tu sistema init puede hacer eso, estás bien.