Files
Portainer/opencode/README.md
T
2026-08-16 21:45:05 +00:00

50 lines
2.5 KiB
Markdown

# OpenCode Web UI
Este stack ejecuta OpenCode en un contenedor con aislamiento fuerte para exponerlo solo por HTTPS detras de Traefik + Authentik.
## Objetivo
- Dominio: `https://ocode.sherlockhomeless.net`
- Acceso: solo usuarios autorizados en Authentik
- Aislamiento: sin privilegios, filesystem raiz de solo lectura y workspace dedicado
## Archivos
- Compose: `opencode/docker-compose.yml`
- Variables: `opencode/.env` (copiar desde `opencode/.env.example`)
## Despliegue en contenedor
```bash
cp opencode/.env.example opencode/.env
mkdir -p /opt/opencode/home /opt/opencode/config /opt/opencode/workspace
docker compose --env-file opencode/.env -f opencode/docker-compose.yml up -d
```
El router activo se define en `/opt/traefik/dynamic/opencode.yml` y aplica Authentik junto con la cabecera Basic necesaria para el backend.
## Endurecimiento aplicado
- `user: 1000:1000`
- `cap_drop: [ALL]`
- `security_opt: [no-new-privileges:true]`
- `read_only: true`
- `/tmp` en `tmpfs` con `exec`, necesario para que Bun/OpenCode cargue librerias temporales
- Home persistente aislada en `/opt/opencode/home`
- Workspace aislado en `/opt/opencode/workspace`, montado dentro de la home como `/home/opencode/workspace`
- Sin `docker.sock` ni montajes del host fuera de los paths definidos
## Authentik (acceso solo a esta app)
En Authentik, `ocode.sherlockhomeless.net` necesita su propio `Proxy Provider` publicado en el `authentik Embedded Outpost`.
Para aislar el acceso, crea un grupo exclusivo, por ejemplo `opencode-ocode-users`, y una `Policy Binding` que permita solo ese grupo. El contenedor usa los modelos configurados mediante `DEEPSEEK_API_KEY` en su `.env`.
## Claude Sonnet 5 mediante LiteLLM
OpenCode consume `claude-sonnet-5` desde el proveedor OpenAI-compatible de LiteLLM. La configuracion activa debe incluir el modelo con el identificador `litellm/claude-sonnet-5` y apuntar `options.baseURL` a `https://llm.sherlockhomeless.net/v1` (o a `http://litellm:4000/v1` si ambos servicios comparten la red Docker).
El fichero `opencode/opencode.json` contiene la configuracion local efectiva y esta ignorado por Git porque incluye la clave maestra de LiteLLM. OpenCode solo necesita esa clave; el OAuth de Claude se mantiene y renueva exclusivamente en LiteLLM, por lo que no se debe montar `.claude/.credentials.json` dentro de OpenCode.
OpenWebUI no requiere una entrada estatica equivalente: obtiene dinamicamente `claude-sonnet-5` de `/v1/models` usando su conexion OpenAI-compatible existente con LiteLLM.