mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 20:00:08 +00:00
23bbee4f45
* feat(mesh): replace host-mode with shared sencho_mesh Docker network Phase D of the mesh redesign: drop the operator's `network_mode: host` requirement and the `host-gateway` extra_hosts pattern that did not work on cloud iptables-restrictive distros (OCI, etc.) or Docker Desktop. Each Sencho creates a shared `sencho_mesh` Docker bridge network on boot (default subnet 172.30.0.0/24, override via SENCHO_MESH_SUBNET), pins itself at `<network>+2`, and attaches every meshed user service to the same bridge. Compose overrides now emit IP-based `extra_hosts` plus a top-level `networks` block declaring `sencho_mesh` external. Override delivery: central renders for local stacks; for remote stacks it sends the fleet alias list to the remote's new `PUT /api/mesh/local- override/:stackName` endpoint, which renders against the remote's OWN local senchoIp and writes under its OWN DATA_DIR. Each node may use a different subnet without coordination beyond the env var. Opt-in / opt-out now trigger an automatic redeploy of the affected stack via the existing deploy code path (local: ComposeService; remote: HTTP POST through proxyFetch). The frontend opt-in sheet shows a confirmation modal (ConfirmModal) before the mutation. Failed redeploys emit both a mesh activity event and a durable audit-log row. Hardening: - Reserve port 1852 at opt-in (prevents user containers from racing the Sencho API listener). - ensureMeshNetwork refuses to continue if `sencho_mesh` exists with a mismatched subnet rather than silently routing to the wrong IP. - Idempotent network connect/disconnect helpers in DockerController. - optInStack rolls back the DB row if the just-inserted stack's override push fails (no half-states surviving across calls). - regenerateOverridesForNode runs in parallel and skips the just- pushed stack on opt-in. Operator template: drop `network_mode: host`, restore `ports: ["1852:1852"]`. Mesh now works identically on Linux LAN, OCI, and Docker Desktop without firewall changes. Docs: rewrite docs/features/sencho-mesh.mdx around the shared bridge network, document SENCHO_MESH_SUBNET, surface the host-network-service opt-in restriction, and cross-link with the Pilot Agent docs. BREAKING CHANGE: the operator's `docker-compose.yml` no longer uses `network_mode: host`. After upgrading, redeploy any meshed stacks once so they pick up the new IP-based override and join `sencho_mesh`. * fix(mesh): wrap stackName with path.basename in local-override fs ops CodeQL flagged js/path-injection on the new applyLocalOverride and removeLocalOverride methods because they are publicly reachable and its data-flow model does not recognize isValidStackName / isPathWithinBase as sanitizers. The validation IS sufficient (the allowlist regex blocks path separators, the path-prefix check blocks escape), but path.basename is a model CodeQL recognizes and is purely defensive: for any input that already passes isValidStackName, basename is the identity.
48 lines
2.2 KiB
YAML
48 lines
2.2 KiB
YAML
services:
|
|
sencho:
|
|
image: saelix/sencho:latest
|
|
build: .
|
|
container_name: sencho
|
|
restart: unless-stopped
|
|
# Publish only the Sencho UI / API port. Sencho Mesh runs on an internal
|
|
# `sencho_mesh` Docker network that Sencho creates and joins on boot,
|
|
# so cross-stack mesh routing does not require any extra host ports or
|
|
# firewall rules. Override the mesh subnet (default 172.30.0.0/24) with
|
|
# SENCHO_MESH_SUBNET if it conflicts with your network.
|
|
ports:
|
|
- "1852:1852"
|
|
volumes:
|
|
# Required: Docker Socket for container orchestration
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
|
|
# Required: Sencho's internal database for alerts and settings
|
|
# Format is [Host Path]:[Container Path]
|
|
# You can change the left side to anywhere on your server, but leave the right side as /app/data
|
|
- ./data:/app/data
|
|
|
|
# ⚠️ THE 1:1 COMPOSE PATH RULE ⚠️
|
|
# Mount the root folder where all your compose files live.
|
|
# The path on the left (Host) MUST EXACTLY MATCH the path on the right (Container).
|
|
# EXAMPLE: If your compose files are in /opt/docker, use: - /opt/docker:/opt/docker
|
|
- /path/to/your/docker/folder:/path/to/your/docker/folder
|
|
|
|
# (Optional but Recommended) Media/Data Drives
|
|
# Mount your media drives here so Docker Compose inside Sencho can validate paths during deployment.
|
|
- /path/to/your/media/drives:/path/to/your/media/drives
|
|
|
|
environment:
|
|
# ENVIRONMENT VARIABLES FOR INSIDE THE CONTAINER
|
|
|
|
# This points to the Container Path (right side) of your 1:1 mount above
|
|
- COMPOSE_DIR=/path/to/your/docker/folder/compose
|
|
|
|
# This points to the Container Path (right side) of your database mount above. Leave this as /app/data.
|
|
- DATA_DIR=/app/data
|
|
|
|
# ⚠️ GLOBAL ENVIRONMENT VARIABLES ⚠️
|
|
# If your compose files rely on host-level shell variables (like $PUID, $TZ)
|
|
# or a centralized globals.env file, you MUST pass them into Sencho here.
|
|
# Otherwise, Sencho will evaluate your compose files with empty variables.
|
|
# If you do not use a global env file, you can delete these two lines.
|
|
env_file:
|
|
- /path/to/your/docker/folder/env/globals.env |