fix(opencode): retire legacy host route
This commit is contained in:
+3
-57
@@ -4,8 +4,7 @@ Este stack ejecuta OpenCode en un contenedor con aislamiento fuerte para exponer
|
||||
|
||||
## Objetivo
|
||||
|
||||
- Dominio sandboxed: `https://ocode.sherlockhomeless.net`
|
||||
- Dominio clasico host/systemd: `https://opencode.sherlockhomeless.net`
|
||||
- Dominio: `https://ocode.sherlockhomeless.net`
|
||||
- Acceso: solo usuarios autorizados en Authentik
|
||||
- Aislamiento: sin privilegios, filesystem raiz de solo lectura y workspace dedicado
|
||||
|
||||
@@ -14,7 +13,6 @@ Este stack ejecuta OpenCode en un contenedor con aislamiento fuerte para exponer
|
||||
- Compose: `opencode/docker-compose.yml`
|
||||
- Variables: `opencode/.env` (copiar desde `opencode/.env.example`)
|
||||
- Middleware Traefik (inyecta `Authorization`): `/opt/traefik/dynamic/opencode-auth.yml`
|
||||
- Config de legado host/systemd: `opencode/systemd/` y `opencode/traefik/opencode.yml`
|
||||
|
||||
## Despliegue en contenedor
|
||||
|
||||
@@ -50,58 +48,6 @@ El router sandboxed usa la cadena `ths-authentik@docker,opencode-inject-auth@fil
|
||||
|
||||
## Authentik (acceso solo a esta app)
|
||||
|
||||
En Authentik, cada dominio necesita su propio `Proxy Provider` publicado en el `authentik Embedded Outpost`:
|
||||
En Authentik, `ocode.sherlockhomeless.net` necesita su propio `Proxy Provider` publicado en el `authentik Embedded Outpost`.
|
||||
|
||||
1. Provider/app para `ocode.sherlockhomeless.net` (sandboxed).
|
||||
2. Provider/app independiente para `opencode.sherlockhomeless.net` (clasico).
|
||||
3. Ambos providers deben estar anadidos al `authentik Embedded Outpost`.
|
||||
4. Para aislar el acceso sandboxed, crea un grupo exclusivo, por ejemplo `opencode-ocode-users`.
|
||||
5. Crea una `Policy Binding` para la app sandboxed que permita solo ese grupo.
|
||||
6. Crea el usuario del colega y anadelo solo a `opencode-ocode-users`.
|
||||
7. No lo anadas a grupos con acceso a otras aplicaciones.
|
||||
|
||||
Si el clasico devuelve una pagina `Not Found` de Authentik, normalmente significa que el provider de `opencode.sherlockhomeless.net` no esta asociado al outpost o fue sustituido por el provider de `ocode.sherlockhomeless.net`.
|
||||
|
||||
## Arquitectura de modelos LLM
|
||||
|
||||
Hay dos instancias de OpenCode con modelos distintos:
|
||||
|
||||
| Instancia | Tipo | Modelos |
|
||||
|-------------------------------|-------------- |----------------------------|
|
||||
| `opencode.sherlockhomeless.net` | Host (systemd) | DeepSeek + **Gemma 4** (Ollama) |
|
||||
| `ocode.sherlockhomeless.net` | Contenedor | Solo DeepSeek (colega) |
|
||||
|
||||
El contenedor sandboxed (`ocode`) **no** usa Ollama ni Gemma 4. Sus modelos ya estan configurados via `DEEPSEEK_API_KEY` en su `.env`.
|
||||
|
||||
### Modelos Gemma 4 via Ollama (para el host OpenCode)
|
||||
|
||||
Ollama corre en contenedor expuesto en `127.0.0.1:11434` (solo localhost).
|
||||
|
||||
```bash
|
||||
cp ollama/.env.example ollama/.env
|
||||
mkdir -p /opt/ollama/data
|
||||
docker compose --env-file ollama/.env -f ollama/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
Pull de modelos:
|
||||
|
||||
```bash
|
||||
docker exec -it ollama ollama pull gemma4:e2b # modelo principal
|
||||
docker exec -it ollama ollama pull gemma4:e4b # opcional si e2b no basta
|
||||
```
|
||||
|
||||
Activar provider en el OpenCode del host:
|
||||
|
||||
```bash
|
||||
sudo install -m 0644 opencode/opencode.json.example /home/felidae/.config/opencode/opencode.json
|
||||
sudo systemctl restart opencode-web
|
||||
```
|
||||
|
||||
Modelos recomendados para este VPS (8 vCPU, 22 GiB RAM, sin GPU):
|
||||
|
||||
| Modelo | RAM aprox | Uso |
|
||||
|------------- |---------- |--------------------- |
|
||||
| `gemma4:e2b` | ~3-4 GiB | Modelo principal |
|
||||
| `gemma4:e4b` | ~5-6 GiB | Solo si e2b no basta |
|
||||
| `gemma4:26b` | ~16 GiB | No recomendable |
|
||||
| `gemma4:31b` | ~20 GiB | No recomendable |
|
||||
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`.
|
||||
|
||||
@@ -3,7 +3,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: local/opencode-sandbox:latest
|
||||
image: local/opencode-sandbox:pinned-20260528
|
||||
container_name: opencode
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 30s
|
||||
@@ -29,14 +29,15 @@ services:
|
||||
networks:
|
||||
- proxy
|
||||
labels:
|
||||
prune.protect: "true"
|
||||
traefik.enable: "true"
|
||||
traefik.docker.network: "${TRAEFIK_DOCKER_NETWORK}"
|
||||
traefik.http.routers.ocode.rule: "Host(`${OPENCODE_DOMAIN}`)"
|
||||
traefik.http.routers.ocode.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
||||
traefik.http.routers.ocode.tls: "true"
|
||||
traefik.http.routers.ocode.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
||||
traefik.http.routers.ocode.middlewares: "crowdsec-bouncer@file,${TRAEFIK_AUTH_CHAIN}"
|
||||
traefik.http.services.ocode.loadbalancer.server.port: "4096"
|
||||
traefik.http.routers.opencode.rule: "Host(`${OPENCODE_DOMAIN}`)"
|
||||
traefik.http.routers.opencode.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
||||
traefik.http.routers.opencode.tls: "true"
|
||||
traefik.http.routers.opencode.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
||||
traefik.http.routers.opencode.middlewares: "crowdsec-bouncer@file,${TRAEFIK_AUTH_CHAIN}"
|
||||
traefik.http.services.opencode.loadbalancer.server.port: "4096"
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
OPENCODE_SERVER_USERNAME=opencode
|
||||
OPENCODE_SERVER_PASSWORD=change-me
|
||||
OPENCODE_DISABLE_AUTOUPDATE=true
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"provider": {
|
||||
"ollama-vps": {
|
||||
"npm": "@ai-sdk/openai-compatible",
|
||||
"name": "Ollama VPS",
|
||||
"options": {
|
||||
"baseURL": "http://localhost:11434/v1",
|
||||
"apiKey": "ollama"
|
||||
},
|
||||
"models": {
|
||||
"gemma4:e2b": {
|
||||
"name": "Gemma 4 E2B VPS",
|
||||
"limit": {
|
||||
"context": 16384,
|
||||
"output": 2048
|
||||
}
|
||||
},
|
||||
"gemma4:e4b": {
|
||||
"name": "Gemma 4 E4B VPS",
|
||||
"limit": {
|
||||
"context": 16384,
|
||||
"output": 2048
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
[Unit]
|
||||
Description=OpenCode Web UI
|
||||
Documentation=https://opencode.ai/docs/web/
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=felidae
|
||||
Group=felidae
|
||||
WorkingDirectory=/home/eduardo/Portainer_repo
|
||||
EnvironmentFile=/etc/opencode-web.env
|
||||
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
Environment=HOME=/home/felidae
|
||||
ExecStart=/usr/local/bin/opencode-host web --hostname 10.0.0.1 --port 4096 --print-logs
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
# OpenCode necesita operar sobre repos y herramientas del host; se mantiene sin
|
||||
# sandboxing restrictivo de systemd a proposito.
|
||||
NoNewPrivileges=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,27 +0,0 @@
|
||||
http:
|
||||
routers:
|
||||
opencode:
|
||||
rule: Host(`opencode.sherlockhomeless.net`)
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- crowdsec-bouncer@file
|
||||
- ths-authentik@docker
|
||||
- opencode-basic-auth
|
||||
service: opencode
|
||||
|
||||
middlewares:
|
||||
opencode-basic-auth:
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
# En el host desplegado se genera desde /etc/opencode-web.env.
|
||||
# No versionar el secreto real en el repo.
|
||||
Authorization: "Basic <base64(usuario:password-opencode)>"
|
||||
|
||||
services:
|
||||
opencode:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://host.docker.internal:4096
|
||||
Reference in New Issue
Block a user