Fase 2: 04_sanitize.py - scrubbing de secretos de skills/agentes/plans (10 secretos unicos, gate en verde)
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
# Plan: Instalar Claude Code system-wide (username-agnostic, última versión) en el Dockerfile
|
||||
|
||||
## Context
|
||||
|
||||
El [Dockerfile](Dockerfile) instala Claude Code vía el repo apt oficial (`claude-code`,
|
||||
líneas 147‑155) desde el commit `7096b11`. Eso provocó dos problemas:
|
||||
|
||||
1. **Versión vieja**: el canal apt `stable` va por detrás del canal `latest`. En este
|
||||
contenedor hay `2.1.197`, mientras que `latest` ya está en `2.1.207`.
|
||||
2. **MCPs no cargan**: verificado que es *estructural*, no de versión. El usuario declaró sus
|
||||
MCPs (gitea, docmost, github-personal, penpot, atlassian) bajo la clave `mcpServers` dentro
|
||||
de `~/.claude/settings.json`, pero **Claude Code no lee `mcpServers` desde `settings.json`**.
|
||||
`claude mcp list` lo confirmó: solo aparecen los conectores de claude.ai, ninguno de los del
|
||||
usuario. Los MCPs de usuario viven en `~/.claude.json` (archivo hermano de `.claude/`, no
|
||||
dentro), en `.mcp.json` de proyecto, o en `/etc/claude-code/managed-mcp.json` (enterprise).
|
||||
|
||||
Intentos previos y por qué fallaron:
|
||||
- `curl … install.sh | bash` (commit original): deja el binario en `~/.local/bin` del usuario que
|
||||
instala (root) → inalcanzable para otros HOME_USER.
|
||||
- `HOME=/usr/local/claude … install.sh` (`be1a141`): el binario resuelve su home por el registro
|
||||
del SO, ignoró el override y volvió a caer en `/root`.
|
||||
- apt `claude-code` (`7096b11`): quedó en `/usr/bin` (bien para multi-usuario) pero atado al canal
|
||||
`stable` desactualizado.
|
||||
|
||||
**Objetivo**: que `claude` esté disponible por defecto para **cualquier nombre de usuario** del
|
||||
SO, siempre en la **última versión**, con **auto-update en runtime** funcionando, y sin depender
|
||||
de trucos de `$HOME`/`.bashrc`.
|
||||
|
||||
## Alcance (confirmado con el usuario)
|
||||
|
||||
- **Este repo (Dockerfile)**: SOLO arreglar la instalación de Claude Code.
|
||||
- **MCPs**: NO se toca la imagen. Se documenta la guía para que el usuario los reubique vía sus
|
||||
volúmenes (sección "Guía MCPs" abajo).
|
||||
|
||||
## Enfoque recomendado
|
||||
|
||||
Descargar el binario nativo standalone directamente del canal oficial `latest` (el mismo artefacto
|
||||
que `install.sh` usa internamente), verificar su checksum, y colocarlo en `/usr/local/bin/claude`
|
||||
(modo 0755, root). Esa ruta ya está en el PATH por defecto de todo usuario (igual que `gh`,
|
||||
`kubectl`, `docker`), así que es completamente independiente del nombre de usuario y no necesita
|
||||
exports en `.bashrc`.
|
||||
|
||||
El auto-update en runtime sigue funcionando **por usuario**: el updater nativo descarga nuevas
|
||||
versiones en el propio `~/.local/share/claude/versions/` de cada usuario, independiente del binario
|
||||
root de `/usr/local/bin`. La línea existente `export PATH="$HOME/.local/bin:$PATH"` (línea 176)
|
||||
hace que esa copia actualizada por usuario tome precedencia. El binario base de la imagen se
|
||||
refresca además en cada build de CI.
|
||||
|
||||
## Cambios en [Dockerfile](Dockerfile)
|
||||
|
||||
### 1. Reemplazar el bloque apt (líneas 147‑155) por descarga directa del binario `latest`
|
||||
|
||||
`python3` ya está disponible en esta etapa (viene de `python3-pip`), así que se usa para parsear el
|
||||
`manifest.json` de forma robusta. El base es Debian/glibc → variante `linux-<arch>` (no musl).
|
||||
|
||||
```dockerfile
|
||||
# Installing Claude Code (system-wide, latest native build, accessible by any user)
|
||||
# Pull the standalone native binary straight from the official 'latest' release
|
||||
# channel (the same artifact install.sh uses internally) and drop it on the
|
||||
# system PATH at /usr/local/bin -- already on every user's PATH, like gh/kubectl.
|
||||
# Avoids install.sh's per-user ~/.local/bin layout (unreachable for other users)
|
||||
# and the apt 'stable' channel lag that shipped an outdated build. Runtime
|
||||
# auto-update still works per user: the native updater writes new versions into
|
||||
# each user's own ~/.local/share/claude/versions.
|
||||
RUN set -eux; \
|
||||
case "$(dpkg --print-architecture)" in \
|
||||
amd64) CC_ARCH=x64 ;; \
|
||||
arm64) CC_ARCH=arm64 ;; \
|
||||
*) echo "unsupported architecture: $(dpkg --print-architecture)" >&2; exit 1 ;; \
|
||||
esac; \
|
||||
CC_BASE="https://downloads.claude.ai/claude-code-releases"; \
|
||||
CC_VERSION="$(curl -fsSL "${CC_BASE}/latest")"; \
|
||||
CC_CHECKSUM="$(curl -fsSL "${CC_BASE}/${CC_VERSION}/manifest.json" \
|
||||
| python3 -c "import sys,json;print(json.load(sys.stdin)['platforms']['linux-${CC_ARCH}']['checksum'])")"; \
|
||||
curl -fsSL "${CC_BASE}/${CC_VERSION}/linux-${CC_ARCH}/claude" -o /tmp/claude; \
|
||||
echo "${CC_CHECKSUM} /tmp/claude" | sha256sum -c -; \
|
||||
sudo install -m 0755 -o root -g root /tmp/claude /usr/local/bin/claude; \
|
||||
rm -f /tmp/claude; \
|
||||
claude --version
|
||||
```
|
||||
|
||||
### 2. Eliminar la línea de auto-update específica de apt (líneas 177‑178)
|
||||
|
||||
```dockerfile
|
||||
# Let Claude Code auto-upgrade its apt package in the background when a new version ships
|
||||
RUN echo 'export CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE=1' | sudo tee -a /usr/bin/.bashrc
|
||||
```
|
||||
|
||||
Ya no aplica (no es instalación apt). El auto-update nativo funciona por defecto sin esa env var.
|
||||
Se **conserva** la línea 176 (`export PATH="$HOME/.local/bin:$PATH"`) porque es de propósito
|
||||
general y ayuda a que el claude auto-actualizado por usuario tome precedencia.
|
||||
|
||||
### 3. Bump de versión en [README.md](README.md)
|
||||
|
||||
`1.4.1` → `1.4.2` (mismo patrón que los commits previos).
|
||||
|
||||
## Guía MCPs (fuera de la imagen — lo aplica el usuario en sus volúmenes)
|
||||
|
||||
Causa raíz: `mcpServers` en `~/.claude/settings.json` es ignorado. El resto de `settings.json`
|
||||
(`permissions`, `hooks`, `model`, `enabledPlugins`, `env`, `theme`, etc.) **sí es válido y se
|
||||
queda ahí**.
|
||||
|
||||
Pasos:
|
||||
1. Mover el bloque `mcpServers` de `~/.claude/settings.json` al archivo `~/.claude.json`
|
||||
(en el HOME, hermano del directorio `.claude/`), como clave top-level:
|
||||
```json
|
||||
{ "mcpServers": { "gitea": { "type": "http", "url": "…", "headers": { … } }, "docmost": { … } } }
|
||||
```
|
||||
2. Persistir `~/.claude.json` en el volumen por usuario, montado **read-write** (Claude reescribe
|
||||
ese archivo con historial de proyectos; no debe ser read-only). El volumen actual que monta
|
||||
`~/.claude/` no lo cubre porque `~/.claude.json` está fuera de ese directorio.
|
||||
3. Borrar el bloque `mcpServers` obsoleto de `settings.json` para evitar confusión.
|
||||
|
||||
## Verificación
|
||||
|
||||
1. **Build**: `docker build -t vscode-server:test .` (o vía el workflow de Gitea). Confirmar que el
|
||||
nuevo `RUN` imprime `claude --version` = `2.1.207` (o superior) sin error de checksum.
|
||||
2. **Multi-arch**: el `case` cubre amd64/arm64; el build de CI es `linux/amd64,linux/arm64`.
|
||||
3. **Username-agnostic**: correr el contenedor y, como el usuario por defecto y como otro usuario
|
||||
distinto, verificar `which claude` → `/usr/local/bin/claude` y que `claude --version` responde.
|
||||
4. **Auto-update runtime**: tras un rato de uso, confirmar que aparece `~/.local/share/claude/versions/`
|
||||
en el home del usuario (update nativo por usuario) sin permisos root.
|
||||
5. **MCPs** (tras aplicar la guía en el volumen): `claude mcp list` debe listar gitea/docmost/
|
||||
github-personal/penpot/atlassian como `Connected`.
|
||||
Reference in New Issue
Block a user