mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-27 20:29:10 +00:00
8e1b9826cf
* fix(api): add tiered rate limiting to prevent polling lockouts Replace the single global rate limiter (100 req/min/IP) with a tiered system that separates high-frequency polling endpoints from standard API traffic: - Polling tier (300/min): /stats, /system/stats, /stacks/statuses, /metrics/historical, /health, /meta, /auth/status, /auth/sso/providers, /license. Exempt from the global limiter but governed by their own safety net to prevent resource exhaustion. - Standard tier (200/min): All other endpoints, raised from 100. - Webhook tier (500/min): POST /webhooks/:id/trigger, dedicated limiter for CI/CD platforms sharing datacenter IPs. - Auth tier: Unchanged (5-10 attempts / 15 min). Enterprise adaptations: - Authenticated requests keyed by user session (JWT sub/username) instead of IP, preventing shared NAT/VPN environments from pooling budgets. - Internal node-to-node traffic (node_proxy tokens) bypasses all rate limiters entirely. Includes comprehensive stress tests (21 cases) validating tier separation, node proxy bypass, and per-user keying. * chore(deps): bump axios to 1.15.0 to fix SSRF vulnerability Addresses GHSA-3p68-rc4w-qgx5 (NO_PROXY hostname normalization bypass).
97 lines
4.5 KiB
Plaintext
97 lines
4.5 KiB
Plaintext
---
|
|
title: Self-Hosting Best Practices
|
|
description: Volume mounts, Docker socket security, networking, and resource recommendations for running Sencho in production.
|
|
---
|
|
|
|
## The 1:1 path rule
|
|
|
|
This is the most common setup mistake. When Sencho deploys a Docker Compose stack, Docker resolves bind-mount volume paths relative to the **host filesystem**, not the Sencho container. If your compose files reference relative paths like `./data:/app/data`, Docker looks for `./data` on the host, starting from the directory where the compose file lives on the host.
|
|
|
|
This means the path to your compose directory **must be identical** inside and outside the container:
|
|
|
|
```yaml
|
|
# Correct - same path on both sides
|
|
volumes:
|
|
- /opt/compose:/opt/compose
|
|
environment:
|
|
- COMPOSE_DIR=/opt/compose
|
|
|
|
# Wrong - different paths, relative volumes will break
|
|
volumes:
|
|
- /opt/compose:/app/compose
|
|
```
|
|
|
|
See the [Configuration guide](/getting-started/configuration#compose-directory-the-11-path-rule) for a detailed explanation with examples.
|
|
|
|
---
|
|
|
|
## Volume mount checklist
|
|
|
|
Sencho requires three volume mounts to function correctly:
|
|
|
|
| Mount | Purpose | Required |
|
|
|-------|---------|----------|
|
|
| `/var/run/docker.sock:/var/run/docker.sock` | Docker Engine access for managing containers | Yes |
|
|
| `./sencho-data:/app/data` | Persistent storage for the database and encryption key | Yes |
|
|
| `/opt/compose:/opt/compose` | Your compose project files (must follow 1:1 path rule) | Yes |
|
|
|
|
<Warning>
|
|
The data directory contains your Sencho database (`sencho.db`) and encryption key (`encryption.key`). Losing this directory means losing your Sencho configuration entirely. See the [Backup & Restore guide](/operations/backup) for backup procedures.
|
|
</Warning>
|
|
|
|
---
|
|
|
|
## Docker socket security
|
|
|
|
Mounting the Docker socket (`/var/run/docker.sock`) grants the container the ability to manage all containers, images, volumes, and networks on the host. This is equivalent to root access on the host machine.
|
|
|
|
Sencho mitigates this with privilege dropping:
|
|
|
|
1. The container starts as root to fix volume ownership and resolve Docker socket group permissions
|
|
2. The entrypoint script then drops to a non-root `sencho` user
|
|
3. All application code runs as the `sencho` user
|
|
|
|
If your environment requires stricter isolation, consider:
|
|
|
|
- Running Sencho on a dedicated Docker host
|
|
- Using Docker's `--userns-remap` for user namespace isolation
|
|
- Placing Sencho behind a reverse proxy with authentication (see [Configuration](/getting-started/configuration#reverse-proxy-setup))
|
|
|
|
---
|
|
|
|
## Resource recommendations
|
|
|
|
| Resource | Minimum | Recommended | Notes |
|
|
|----------|---------|-------------|-------|
|
|
| CPU | 1 core | 2 cores | Compose operations spawn child processes that benefit from a second core |
|
|
| RAM | 128 MB | 256 MB | Baseline is around 100 MB at idle; increases with concurrent log streams and large fleets |
|
|
| Disk | 200 MB | 500 MB | The Docker image is around 200 MB; the database grows with metrics retention and fleet size |
|
|
|
|
Sencho itself is lightweight. The majority of resource usage on your host comes from the Docker containers it manages, not from Sencho.
|
|
|
|
---
|
|
|
|
## Networking
|
|
|
|
- **Listen port:** 3000 (fixed). Map it to any host port using Docker's `-p` flag or `ports` in your compose file
|
|
- **Inbound:** Only the listen port needs to be reachable (directly or through a reverse proxy)
|
|
- **Outbound:** No outbound connections are required for local-only setups. If you use multi-node management, Sencho needs HTTP/HTTPS access to remote Sencho instances on their configured API URLs
|
|
- **Health check:** `GET /api/health` returns `200` when the application is ready. The Docker image includes a built-in `HEALTHCHECK` that polls this endpoint every 30 seconds
|
|
|
|
---
|
|
|
|
## Environment variable checklist
|
|
|
|
Quick reference for all environment variables. See [Configuration](/getting-started/configuration) for full details.
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `COMPOSE_DIR` | `/app/compose` | Path to compose project files (1:1 rule applies) |
|
|
| `DATA_DIR` | `/app/data` | Persistent data directory |
|
|
| `FRONTEND_URL` | *(empty)* | Frontend origin for CORS; leave empty for same-origin |
|
|
| `API_RATE_LIMIT` | `200` | Maximum API requests per minute per user session (production only) |
|
|
| `API_POLLING_RATE_LIMIT` | `300` | Rate limit for dashboard polling endpoints (production only) |
|
|
| `NODE_ENV` | `production` | Set automatically in the Docker image |
|
|
|
|
SSO variables are documented separately in the [SSO Quickstart](/getting-started/sso-quickstart).
|