mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +00:00
9eb945a6f0
Every filesystem operation against user compose folders (save, create, deploy, update, rollback, template install, fleet snapshot restore) previously failed with EACCES whenever a stack container had chowned its own bind mount to another UID, which is extremely common with linuxserver/* images and anything that runs as root by default. Running Sencho as root eliminates the entire class of permission bugs at the source and matches the default posture of Portainer, Dockge, Komodo, and Yacht. Mounting /var/run/docker.sock is already equivalent to root-on-host, so the previous non-root hardening provided essentially no additional isolation while breaking real features. Changes: - docker-entrypoint.sh: default path stays root, no GID dance, no privilege drop. Opt-out via SENCHO_USER=sencho restores the legacy behavior bit-for-bit (chown data dir, match Docker socket GID, su-exec to the user). Fails fast if SENCHO_USER names a nonexistent account. Kubernetes / OpenShift forced-non-root compat preserved via the existing id -u = 0 guard. - FileSystemService: delete forceDeleteViaDocker (the ~40-line helper that shelled out to an alpine container to work around EACCES during deleteStack) and simplify deleteStack to a single fsPromises.rm call. Tests updated accordingly. - Dockerfile: keep the sencho user+group pre-created so the opt-out path works out of the box; comments updated to document the new default. - Docs: new "Container user" section in configuration.mdx documenting the root default and the SENCHO_USER opt-out; troubleshooting and self-hosting updated to match.
94 lines
5.1 KiB
Plaintext
94 lines
5.1 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, regardless of which user the Sencho process itself runs as.
|
|
|
|
Because the Docker socket is already the effective privilege boundary, Sencho runs as `root` inside the container by default. This matches Portainer, Dockge, Komodo, and Yacht, and ensures Sencho can always write to your compose folders, even when a stack container (for example anything from `linuxserver/*`) has chowned its own bind mount. See [Configuration: Container user](/getting-started/configuration#container-user) for details on the default and the `SENCHO_USER` opt-out.
|
|
|
|
If your environment requires stricter isolation, the Docker socket itself is the right place to focus:
|
|
|
|
- Running Sencho on a dedicated Docker host so a compromise cannot reach unrelated workloads
|
|
- Using Docker's `--userns-remap` for user namespace isolation at the daemon level
|
|
- Running Sencho behind a reverse proxy with authentication (see [Configuration](/getting-started/configuration#reverse-proxy-setup)) so the UI is not exposed to untrusted networks
|
|
- Setting `SENCHO_USER=sencho` to drop privileges inside the container as a defense-in-depth measure, accepting that filesystem writes to permission-restricted stack folders will fail in that mode
|
|
|
|
---
|
|
|
|
## 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).
|