mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-05 16:37:46 +00:00
116f15dae9
* fix(stacks): resolve permission denied error when deleting stacks with root-owned files When Docker Compose creates files as root inside a stack directory, the non-root Sencho process cannot remove them. This adds a Docker-based fallback: if fsPromises.rm fails with EACCES/EPERM, Sencho spawns a short-lived Alpine container to clean up the root-owned files. Also enhances docker compose down with --volumes --remove-orphans to let Docker clean up its own resources before filesystem deletion. * docs: clarify that pre-existing root-owned stacks can be deleted * fix(stacks): include Docker stderr in fallback deletion error message Fixes CI lint failure: 'stderr' was assigned but never read in forceDeleteViaDocker(). Now surfaces Docker stderr output in the error message when the fallback cleanup fails.
184 lines
6.7 KiB
Plaintext
184 lines
6.7 KiB
Plaintext
---
|
|
title: Troubleshooting
|
|
description: Solutions to the most common Sencho setup and runtime problems.
|
|
---
|
|
|
|
## Containers won't start after deploy
|
|
|
|
**Symptom:** You click Deploy and containers immediately exit or never appear.
|
|
|
|
**Check:** Open the [Host Console](/features/host-console) and run:
|
|
|
|
```bash
|
|
docker compose -f /path/to/your/stack/compose.yaml logs
|
|
```
|
|
|
|
The most common causes:
|
|
|
|
- **Missing environment variable** - a required variable in your `.env` file is empty or has the wrong name.
|
|
- **Port already in use** - another container or host process is bound to the same port. Change the host port in the compose file.
|
|
- **Volume path does not exist** - a bind-mount path on the host doesn't exist yet. Create the directory manually.
|
|
|
|
---
|
|
|
|
## The 1:1 path rule - volumes resolve to wrong paths
|
|
|
|
**Symptom:** Stacks deploy but relative volume paths (e.g. `./config:/config`) point to the wrong location inside the container, or `docker compose` exits with a path error.
|
|
|
|
**Cause:** Your `COMPOSE_DIR` is mounted at a different path inside the Sencho container than it has on the host.
|
|
|
|
**Fix:** Your compose volume mount and `COMPOSE_DIR` environment variable must use the **same absolute path** on both sides:
|
|
|
|
```yaml
|
|
# docker-compose.yml for Sencho itself
|
|
volumes:
|
|
- /opt/docker:/opt/docker # same path inside and outside
|
|
environment:
|
|
- COMPOSE_DIR=/opt/docker
|
|
```
|
|
|
|
See [Configuration - the 1:1 path rule](/getting-started/configuration#compose-directory-the-11-path-rule) for a full explanation.
|
|
|
|
---
|
|
|
|
## "Permission denied" on the Docker socket
|
|
|
|
**Symptom:** Sencho starts but shows errors accessing Docker, or the stack list is empty even though containers exist.
|
|
|
|
**Cause:** The Sencho container cannot read `/var/run/docker.sock`.
|
|
|
|
**Fix:** Ensure the socket is mounted:
|
|
|
|
```yaml
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
```
|
|
|
|
On Linux, the Docker socket is owned by the `docker` group. The Sencho entrypoint detects the socket's GID automatically and adds the internal `sencho` user to the matching group. If you see permission errors despite a correct mount, check that the socket file is readable:
|
|
|
|
```bash
|
|
ls -la /var/run/docker.sock
|
|
# Expected: srw-rw---- 1 root docker ...
|
|
```
|
|
|
|
If the group is not `docker`, the auto-detection still works - Sencho reads the GID from the socket file at startup.
|
|
|
|
---
|
|
|
|
## "Permission denied" when deleting a stack
|
|
|
|
**Symptom:** Clicking Delete on a stack fails with a permission error mentioning `EACCES`.
|
|
|
|
**Cause:** Stack directories often contain files owned by root — for example when Docker Compose was run with `sudo`, or when containers write config/data files into the stack directory. Since Sencho runs as a non-root user, the OS denies the removal.
|
|
|
|
This is especially common when installing Sencho on a server where stacks were originally created outside of Sencho (e.g. via `sudo docker compose up`). Those directories and their contents are root-owned, but Sencho can still delete them.
|
|
|
|
**How Sencho handles it:** Sencho automatically detects permission errors during deletion and falls back to a Docker-based cleanup. It spawns a short-lived Alpine container that bind-mounts the stack directory and removes the root-owned files. This happens transparently — no manual intervention is needed in the standard Docker setup.
|
|
|
|
**If automatic cleanup fails:** The error message will include the directory path. Remove it manually:
|
|
|
|
```bash
|
|
sudo rm -rf /path/to/your/compose/dir/stack-name
|
|
```
|
|
|
|
**Prerequisites:** The Docker socket must be mounted (standard setup). If Sencho cannot access Docker, the fallback will not work — see [Permission denied on the Docker socket](#permission-denied-on-the-docker-socket).
|
|
|
|
---
|
|
|
|
## Login page shows "Something went wrong"
|
|
|
|
**Symptom:** You enter credentials and get a generic error instead of being logged in.
|
|
|
|
**Possible causes and fixes:**
|
|
|
|
| Cause | Fix |
|
|
|-------|-----|
|
|
| `JWT_SECRET` is not set or is empty | Set a non-empty value for `JWT_SECRET` in your environment |
|
|
| Container restarted and session cookie is stale | Clear browser cookies for the Sencho domain and try again |
|
|
| Rate limit triggered (5 failed attempts in 15 min) | Wait 15 minutes, or restart the container to reset the limiter |
|
|
|
|
---
|
|
|
|
## WebSocket connections fail (logs/console not streaming)
|
|
|
|
**Symptom:** The log viewer or host console shows a spinner that never resolves, or you see "Disconnected" immediately after connecting.
|
|
|
|
**Cause:** A reverse proxy is not forwarding WebSocket upgrade headers.
|
|
|
|
**Fix:** Add WebSocket support to your proxy config:
|
|
|
|
```nginx
|
|
# Nginx
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_read_timeout 3600s;
|
|
```
|
|
|
|
Traefik handles WebSocket upgrades automatically for HTTP/1.1 backends - no extra config needed.
|
|
|
|
---
|
|
|
|
## Remote node shows "Offline" or "Unknown"
|
|
|
|
**Symptom:** A node you added shows a red or gray status dot.
|
|
|
|
**Checks in order:**
|
|
|
|
1. **Is the remote Sencho instance running?** SSH to that machine and verify.
|
|
2. **Is the API URL correct?** It must include the protocol and port (e.g. `http://192.168.1.20:3001`). Open it in a browser - you should see a JSON response from `/api/health`.
|
|
3. **Is the token correct?** Tokens are long JWT strings. Even one missing character will cause auth to fail. Regenerate the token on the remote instance and update the node config.
|
|
4. **Is there a firewall blocking the port?** The primary Sencho host must be able to reach the remote host's Sencho port.
|
|
|
|
Click the **wifi icon** on the node row to re-test connectivity after making changes.
|
|
|
|
---
|
|
|
|
## Forgotten admin password
|
|
|
|
Sencho has no password recovery flow. To reset the password:
|
|
|
|
1. Stop the Sencho container
|
|
2. Connect to the SQLite database directly:
|
|
|
|
```bash
|
|
sqlite3 /path/to/data/sencho.db
|
|
```
|
|
|
|
3. Delete the existing credentials so Sencho re-enters first-boot setup mode:
|
|
|
|
```sql
|
|
DELETE FROM global_settings WHERE key IN ('auth_username', 'auth_password_hash', 'auth_jwt_secret');
|
|
```
|
|
|
|
4. Restart the container - the setup screen will appear on next visit.
|
|
|
|
<Warning>
|
|
This resets authentication entirely. All active sessions become invalid. Your stacks, nodes, and alert rules are not affected.
|
|
</Warning>
|
|
|
|
---
|
|
|
|
## Checking the health endpoint
|
|
|
|
Sencho exposes a health endpoint for monitoring and container health checks:
|
|
|
|
```bash
|
|
curl http://localhost:3000/api/health
|
|
# {"status":"ok","uptime":12345.67}
|
|
```
|
|
|
|
A `200` response confirms the backend is running. Use this endpoint in your uptime monitor or load balancer health check.
|
|
|
|
---
|
|
|
|
## Getting logs from the Sencho container itself
|
|
|
|
```bash
|
|
docker logs sencho
|
|
# or, to follow:
|
|
docker logs -f sencho
|
|
```
|
|
|
|
The backend logs all route errors and service failures to stdout. This is the first place to look when the UI shows an error with no useful message.
|