Skip to content

Commit d7b63ae

Browse files
2 parents 59dcdcf + df79c7d commit d7b63ae

11 files changed

Lines changed: 323 additions & 83 deletions

File tree

Docker-Images/Designer/Dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ rm /tmp/opencode-desktop.deb
131131
rm -rf /var/lib/apt/lists/*
132132
EOSH
133133

134+
ENV COWORK_VM_BACKEND=host
135+
134136
# Claude Desktop (.deb repo comunitario) + wrapper no-sandbox para Electron
135137
RUN <<'EOSH'
136138
set -e
@@ -143,8 +145,8 @@ if [ -x /usr/share/claude-desktop/claude-desktop ] && [ -x /usr/bin/claude-deskt
143145
mv /usr/bin/claude-desktop /usr/bin/claude-desktop.real || true
144146
cat > /usr/bin/claude-desktop <<'EOFWRAP'
145147
#!/bin/sh
146-
exec env ELECTRON_DISABLE_SANDBOX=1 ELECTRON_OZONE_PLATFORM_HINT="${ELECTRON_OZONE_PLATFORM_HINT:-auto}" \
147-
/usr/share/claude-desktop/claude-desktop --no-sandbox --disable-gpu-sandbox --disable-setuid-sandbox --disable-seccomp-filter-sandbox --no-zygote --disable-gpu "$@"
148+
exec env ELECTRON_DISABLE_SANDBOX=1 ELECTRON_OZONE_PLATFORM_HINT="${ELECTRON_OZONE_PLATFORM_HINT:-auto}" COWORK_VM_BACKEND="${COWORK_VM_BACKEND:-host}" \
149+
/usr/bin/claude-desktop.real "$@"
148150
EOFWRAP
149151
chmod +x /usr/bin/claude-desktop
150152
fi

Docker-Images/Developer/Dockerfile

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ RUN set -e; \
197197
# Electron apps dentro de contenedores Docker necesitan desactivar el sandbox
198198
# (no hay user namespaces). Los wrappers añaden --no-sandbox y pistas de Ozone.
199199
ENV ELECTRON_DISABLE_SANDBOX=1 \
200-
ELECTRON_OZONE_PLATFORM_HINT=auto
200+
ELECTRON_OZONE_PLATFORM_HINT=auto \
201+
COWORK_VM_BACKEND=host
201202
RUN <<'EOSH'
202203
set -e
203204
wrap() {
@@ -206,15 +207,23 @@ wrap() {
206207
mv "$name" "${name}.real" || true
207208
cat > "$name" <<SHWRAP
208209
#!/bin/sh
209-
exec env ELECTRON_DISABLE_SANDBOX=1 ELECTRON_OZONE_PLATFORM_HINT="${ELECTRON_OZONE_PLATFORM_HINT:-auto}" \
210+
exec env ELECTRON_DISABLE_SANDBOX=1 ELECTRON_OZONE_PLATFORM_HINT="${ELECTRON_OZONE_PLATFORM_HINT:-auto}" COWORK_VM_BACKEND="${COWORK_VM_BACKEND:-host}" \
210211
"$target" --no-sandbox --disable-gpu-sandbox --disable-setuid-sandbox --disable-seccomp-filter-sandbox --no-zygote $EXTRA_FLAGS "$@"
211212
SHWRAP
212213
chmod +x "$name"
213214
fi
214215
}
215216
TARGET_BIN=/usr/lib/github-desktop/github-desktop EXTRA_FLAGS="--password-store=basic" wrap /usr/bin/github-desktop /usr/lib/github-desktop/github-desktop
216-
TARGET_BIN=/usr/share/claude-desktop/claude-desktop EXTRA_FLAGS="--disable-gpu" wrap /usr/bin/claude-desktop /usr/share/claude-desktop/claude-desktop
217217
TARGET_BIN=/usr/share/code/bin/code EXTRA_FLAGS="" wrap /usr/bin/code /usr/share/code/bin/code
218+
if [ -x /usr/bin/claude-desktop ]; then
219+
mv /usr/bin/claude-desktop /usr/bin/claude-desktop.real || true
220+
cat > /usr/bin/claude-desktop <<'EOFWRAP'
221+
#!/bin/sh
222+
exec env ELECTRON_DISABLE_SANDBOX=1 ELECTRON_OZONE_PLATFORM_HINT="${ELECTRON_OZONE_PLATFORM_HINT:-auto}" COWORK_VM_BACKEND="${COWORK_VM_BACKEND:-host}" \
223+
/usr/bin/claude-desktop.real "$@"
224+
EOFWRAP
225+
chmod +x /usr/bin/claude-desktop
226+
fi
218227
# Google Chrome (no es Electron pero también necesita --no-sandbox en Docker)
219228
if [ -x /opt/google/chrome/google-chrome ]; then
220229
mv /usr/bin/google-chrome-stable /usr/bin/google-chrome-stable.real 2>/dev/null || true

Docker-Images/DeveloperAndroid/Dockerfile

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,6 @@ RUN mkdir -p /etc/pulse/default.pa.d && \
6565
printf 'load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable"\nset-default-sink vcable\n' \
6666
> /etc/pulse/default.pa.d/10-null-sink.pa
6767

68-
# Vulkan loader + Mesa Vulkan drivers (incluye Zink: OpenGL sobre Vulkan para NVIDIA en KasmVNC)
69-
RUN apt-get update && \
70-
apt-get install -y --no-install-recommends \
71-
libvulkan1 \
72-
mesa-vulkan-drivers \
73-
&& rm -rf /var/lib/apt/lists/*
74-
7568
# GitHub CLI (repositorio oficial)
7669
RUN install -m 0755 -d /etc/apt/keyrings && \
7770
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | gpg --dearmor -o /etc/apt/keyrings/githubcli-archive-keyring.gpg && \
@@ -150,28 +143,44 @@ RUN set -e; \
150143
rm -rf /var/lib/apt/lists/* /tmp/opencode-desktop.deb
151144

152145
# Android SDK commandline tools + componentes principales
153-
ENV ANDROID_HOME=/opt/android-sdk \
154-
ANDROID_SDK_ROOT=/opt/android-sdk \
146+
ENV ANDROID_HOME=/home/coder/Android/Sdk \
147+
ANDROID_SDK_ROOT=/home/coder/Android/Sdk \
148+
ANDROID_EMULATOR_DEFAULT_GPU=swiftshader \
155149
ANDROID_USER_HOME=/home/coder/.android \
156-
PATH=$PATH:/opt/android-sdk/platform-tools:/opt/android-sdk/cmdline-tools/latest/bin:/opt/android-sdk/emulator:/opt/gradle/gradle-9.3.1/bin
150+
PATH=$PATH:/home/coder/Android/Sdk/platform-tools:/home/coder/Android/Sdk/cmdline-tools/latest/bin:/home/coder/Android/Sdk/emulator:/opt/gradle/gradle-9.3.1/bin
157151

158152
ARG ANDROID_SDK_VERSION=14742923
159-
RUN mkdir -p /opt/android-sdk/cmdline-tools && \
153+
RUN mkdir -p /home/coder/Android/Sdk/cmdline-tools && \
160154
curl -fsSL "https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_VERSION}_latest.zip" -o /tmp/cmdline-tools.zip && \
161-
unzip -q /tmp/cmdline-tools.zip -d /opt/android-sdk/cmdline-tools && \
162-
mv /opt/android-sdk/cmdline-tools/cmdline-tools /opt/android-sdk/cmdline-tools/latest && \
155+
unzip -q /tmp/cmdline-tools.zip -d /home/coder/Android/Sdk/cmdline-tools && \
156+
mv /home/coder/Android/Sdk/cmdline-tools/cmdline-tools /home/coder/Android/Sdk/cmdline-tools/latest && \
163157
rm /tmp/cmdline-tools.zip && \
164-
yes | /opt/android-sdk/cmdline-tools/latest/bin/sdkmanager --licenses >/dev/null || true && \
165-
/opt/android-sdk/cmdline-tools/latest/bin/sdkmanager --update && \
166-
/opt/android-sdk/cmdline-tools/latest/bin/sdkmanager \
158+
yes | /home/coder/Android/Sdk/cmdline-tools/latest/bin/sdkmanager --licenses >/dev/null || true && \
159+
/home/coder/Android/Sdk/cmdline-tools/latest/bin/sdkmanager --update && \
160+
/home/coder/Android/Sdk/cmdline-tools/latest/bin/sdkmanager \
167161
"platform-tools" \
168162
"emulator" && \
169-
chown -R coder:coder /opt/android-sdk && \
163+
mv /home/coder/Android/Sdk/emulator/emulator /home/coder/Android/Sdk/emulator/emulator.real && \
164+
{ \
165+
printf '%s\n' '#!/usr/bin/env bash' 'set -e' ''; \
166+
printf '%s\n' 'default_gpu="${ANDROID_EMULATOR_DEFAULT_GPU:-swiftshader}"'; \
167+
printf '%s\n' 'for arg in "$@"; do'; \
168+
printf '%s\n' ' if [ "$arg" = "-gpu" ]; then'; \
169+
printf '%s\n' ' exec /home/coder/Android/Sdk/emulator/emulator.real "$@"'; \
170+
printf '%s\n' ' fi'; \
171+
printf '%s\n' 'done' ''; \
172+
printf '%s\n' 'exec /home/coder/Android/Sdk/emulator/emulator.real -gpu "$default_gpu" "$@"'; \
173+
} > /home/coder/Android/Sdk/emulator/emulator && \
174+
chmod +x /home/coder/Android/Sdk/emulator/emulator && \
175+
ln -sfn /home/coder/Android/Sdk /opt/android-sdk && \
176+
chown -R coder:coder /home/coder/Android /home/coder/.android && \
170177
install -d -o coder -g coder /home/coder/.android
171178

172179
# Android Studio
173-
ARG ANDROID_STUDIO_VERSION=2025.2.3.9
174-
RUN curl -fsSL "https://redirector.gvt1.com/edgedl/android/studio/ide-zips/${ANDROID_STUDIO_VERSION}/android-studio-${ANDROID_STUDIO_VERSION}-linux.tar.gz" -o /tmp/android-studio.tar.gz && \
180+
ARG ANDROID_STUDIO_VERSION=2025.3.2
181+
ARG ANDROID_STUDIO_BUILD=2025.3.2.6
182+
ARG ANDROID_STUDIO_PACKAGE=android-studio-panda2-linux.tar.gz
183+
RUN curl -fsSL "https://redirector.gvt1.com/edgedl/android/studio/ide-zips/${ANDROID_STUDIO_BUILD}/${ANDROID_STUDIO_PACKAGE}" -o /tmp/android-studio.tar.gz && \
175184
tar -xzf /tmp/android-studio.tar.gz -C /opt && \
176185
rm /tmp/android-studio.tar.gz && \
177186
chown -R coder:coder /opt/android-studio && \

workspaces/AdvancedHostDANGER/main.tf

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,34 @@ PULSECFG
194194
done
195195
unset _pa_try
196196
197+
# Configurar Claude Desktop cowork VM para usar HostBackend en Docker
198+
# COWORK_VM_BACKEND=host evita que Claude Desktop use bwrap (que falla en contenedores)
199+
# El contenedor Docker ya provee el aislamiento necesario
200+
COWORK_TAG="# managed-by-danger-template: cowork-vm-backend"
201+
for cowork_file in "$HOME/.xsessionrc" "$HOME/.profile"; do
202+
if ! grep -qF "$COWORK_TAG" "$cowork_file" 2>/dev/null; then
203+
printf '%s\nexport COWORK_VM_BACKEND=host\n' "$COWORK_TAG" >> "$cowork_file"
204+
fi
205+
done
206+
mkdir -p "$HOME/.config/environment.d"
207+
cat > "$HOME/.config/environment.d/claude-cowork.conf" <<EOF
208+
$${COWORK_TAG}
209+
COWORK_VM_BACKEND=host
210+
EOF
211+
CLAUDE_WRAP_TAG="# managed-by-danger-template: claude-desktop-wrapper"
212+
if [ -x /usr/bin/claude-desktop ] && ! grep -qF "$CLAUDE_WRAP_TAG" /usr/bin/claude-desktop 2>/dev/null; then
213+
if [ ! -x /usr/bin/claude-desktop.real ]; then
214+
sudo cp /usr/bin/claude-desktop /usr/bin/claude-desktop.real
215+
fi
216+
sudo tee /usr/bin/claude-desktop >/dev/null <<EOF
217+
#!/bin/sh
218+
$${CLAUDE_WRAP_TAG}
219+
exec env ELECTRON_DISABLE_SANDBOX=1 ELECTRON_OZONE_PLATFORM_HINT="$${ELECTRON_OZONE_PLATFORM_HINT:-auto}" COWORK_VM_BACKEND="$${COWORK_VM_BACKEND:-host}" \
220+
/usr/bin/claude-desktop.real "$$@"
221+
EOF
222+
sudo chmod 0755 /usr/bin/claude-desktop
223+
fi
224+
197225
# Asegurar /home/coder como HOME efectivo incluso si se ejecuta como root
198226
sudo mkdir -p /home/coder
199227
sudo chown "$USER:$USER" /home/coder || true
@@ -331,17 +359,35 @@ PY
331359
touch "$HOME/.codex/config.toml"
332360
# Migrar config antigua de chrome-devtools (formato bash -lc) si existe
333361
python3 - <<'PY'
334-
import re, os
362+
import os
335363
path = os.path.expanduser("~/.codex/config.toml")
336364
try:
337-
with open(path) as f:
365+
with open(path, encoding="utf-8") as f:
338366
content = f.read()
339367
except FileNotFoundError:
340368
content = ""
341369
if "[mcp_servers.chrome-devtools]" in content and '"bash"' in content:
342-
content = re.sub(r'\n*\[mcp_servers\.chrome-devtools\][^\[]*', '', content, flags=re.DOTALL)
343-
with open(path, 'w') as f:
344-
f.write(content.rstrip('\n') + '\n')
370+
lines = content.splitlines()
371+
cleaned = []
372+
i = 0
373+
removed = False
374+
while i < len(lines):
375+
if lines[i].strip() == "[mcp_servers.chrome-devtools]":
376+
j = i + 1
377+
block = [lines[i]]
378+
while j < len(lines) and not lines[j].lstrip().startswith("["):
379+
block.append(lines[j])
380+
j += 1
381+
if '"bash"' in "\n".join(block):
382+
removed = True
383+
i = j
384+
continue
385+
cleaned.append(lines[i])
386+
i += 1
387+
if removed:
388+
content = "\n".join(cleaned).rstrip("\n")
389+
with open(path, "w", encoding="utf-8") as f:
390+
f.write((content + "\n") if content else "")
345391
PY
346392
if ! grep -q '^\[mcp_servers\.chrome-devtools\]' "$HOME/.codex/config.toml" 2>/dev/null; then
347393
cat >> "$HOME/.codex/config.toml" <<'CODEXCFG'
@@ -1212,6 +1258,9 @@ resource "docker_container" "workspace" {
12121258

12131259
# Para mejorar KasmVNC y navegadores
12141260
shm_size = 2 * 1024 * 1024 * 1024
1261+
# seccomp=unconfined: necesario para bwrap (Claude Code/Desktop usan bwrap para sandbox bash)
1262+
# SYS_ADMIN solo no es suficiente; seccomp bloquea CLONE_NEWUSER incluso con esa capability
1263+
security_opts = ["seccomp=unconfined"]
12151264
# Permitir FUSE/SSHFS y montajes remotos
12161265
capabilities {
12171266
add = ["SYS_ADMIN"]

workspaces/Developer/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Workspace de desarrollo general, con **Docker in Docker (DinD)**, escritorio XFC
4646
- El daemon Docker se arranca dentro del contenedor (`dockerd` con overlay2) y guarda datos en `/var/lib/docker`.
4747
- Usa KasmVNC para escritorio XFCE (consola del workspace -> abrir URL de KasmVNC).
4848
- El contenedor lleva labels `com.centurylinklabs.watchtower.*` para auto-actualización vía Watchtower.
49+
- Claude Desktop fuerza `COWORK_VM_BACKEND=host` para que el modo cowork no intente usar `bwrap` dentro del contenedor.
4950

5051
### Limitaciones de DinD
5152
- No hay Swarm ni orquestador, por lo que `docker compose` ignora la sección `deploy.*` (incluidos `resources.reservations/limits`, `placement`, `replicas`); solo aplican los flags directos de `docker run`/`docker compose` como `--cpus` o `--memory`.

workspaces/Developer/main.tf

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,34 @@ PULSECFG
237237
done
238238
unset _pa_try
239239
240+
# Configurar Claude Desktop cowork VM para usar HostBackend en Docker
241+
# COWORK_VM_BACKEND=host evita que Claude Desktop use bwrap (que falla en contenedores)
242+
# El contenedor Docker ya provee el aislamiento necesario
243+
COWORK_TAG="# managed-by-developer-template: cowork-vm-backend"
244+
for cowork_file in "$HOME/.xsessionrc" "$HOME/.profile"; do
245+
if ! grep -qF "$COWORK_TAG" "$cowork_file" 2>/dev/null; then
246+
printf '%s\nexport COWORK_VM_BACKEND=host\n' "$COWORK_TAG" >> "$cowork_file"
247+
fi
248+
done
249+
mkdir -p "$HOME/.config/environment.d"
250+
cat > "$HOME/.config/environment.d/claude-cowork.conf" <<EOF
251+
$${COWORK_TAG}
252+
COWORK_VM_BACKEND=host
253+
EOF
254+
CLAUDE_WRAP_TAG="# managed-by-developer-template: claude-desktop-wrapper"
255+
if [ -x /usr/bin/claude-desktop ] && ! grep -qF "$CLAUDE_WRAP_TAG" /usr/bin/claude-desktop 2>/dev/null; then
256+
if [ ! -x /usr/bin/claude-desktop.real ]; then
257+
sudo cp /usr/bin/claude-desktop /usr/bin/claude-desktop.real
258+
fi
259+
sudo tee /usr/bin/claude-desktop >/dev/null <<EOF
260+
#!/bin/sh
261+
$${CLAUDE_WRAP_TAG}
262+
exec env ELECTRON_DISABLE_SANDBOX=1 ELECTRON_OZONE_PLATFORM_HINT="$${ELECTRON_OZONE_PLATFORM_HINT:-auto}" COWORK_VM_BACKEND="$${COWORK_VM_BACKEND:-host}" \
263+
/usr/bin/claude-desktop.real "$$@"
264+
EOF
265+
sudo chmod 0755 /usr/bin/claude-desktop
266+
fi
267+
240268
# Asegurar /home/coder como HOME efectivo incluso si se ejecuta como root
241269
sudo mkdir -p /home/coder
242270
sudo chown "$USER:$USER" /home/coder || true
@@ -374,17 +402,35 @@ PY
374402
touch "$HOME/.codex/config.toml"
375403
# Migrar config antigua de chrome-devtools (formato bash -lc) si existe
376404
python3 - <<'PY'
377-
import re, os
405+
import os
378406
path = os.path.expanduser("~/.codex/config.toml")
379407
try:
380-
with open(path) as f:
408+
with open(path, encoding="utf-8") as f:
381409
content = f.read()
382410
except FileNotFoundError:
383411
content = ""
384412
if "[mcp_servers.chrome-devtools]" in content and '"bash"' in content:
385-
content = re.sub(r'\n*\[mcp_servers\.chrome-devtools\][^\[]*', '', content, flags=re.DOTALL)
386-
with open(path, 'w') as f:
387-
f.write(content.rstrip('\n') + '\n')
413+
lines = content.splitlines()
414+
cleaned = []
415+
i = 0
416+
removed = False
417+
while i < len(lines):
418+
if lines[i].strip() == "[mcp_servers.chrome-devtools]":
419+
j = i + 1
420+
block = [lines[i]]
421+
while j < len(lines) and not lines[j].lstrip().startswith("["):
422+
block.append(lines[j])
423+
j += 1
424+
if '"bash"' in "\n".join(block):
425+
removed = True
426+
i = j
427+
continue
428+
cleaned.append(lines[i])
429+
i += 1
430+
if removed:
431+
content = "\n".join(cleaned).rstrip("\n")
432+
with open(path, "w", encoding="utf-8") as f:
433+
f.write((content + "\n") if content else "")
388434
PY
389435
if ! grep -q '^\[mcp_servers\.chrome-devtools\]' "$HOME/.codex/config.toml" 2>/dev/null; then
390436
cat >> "$HOME/.codex/config.toml" <<'CODEXCFG'

workspaces/DeveloperAndroid/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ tags: [android, mobile, kde, workspace, makespace]
1111
Workspace gráfico KDE/KasmVNC con toolchain Android preinstalado. Usa la imagen `ghcr.io/makespacemadrid/coder-mks-developer-android:latest`.
1212

1313
## Qué incluye
14-
- Android SDK CLI con `platform-tools`, emulator y `cmdline-tools;latest` (instala tus propias plataformas/ build-tools según el proyecto).
14+
- Android SDK CLI en `/home/coder/Android/Sdk` con `platform-tools`, emulator y `cmdline-tools;latest` (instala tus propias plataformas/ build-tools según el proyecto).
1515
- Android Studio Otter 3 Feature Drop (2025.2.3.x).
1616
- Java 17, Node.js 22 (npm/pnpm/yarn), git/git-lfs y utilidades de desarrollo.
1717
- VS Code listo para personalizar tus extensiones (sin bundle preinstalado) y soporte C/C++ vía paquetes base.
@@ -37,6 +37,8 @@ Workspace gráfico KDE/KasmVNC con toolchain Android preinstalado. Usa la imagen
3737

3838
## Notas
3939
- Escritorio KDE vía KasmVNC; VS Code (web y desktop) listo para configurar a tu gusto.
40+
- El SDK Android canónico del workspace es `/home/coder/Android/Sdk`; `/opt/android-sdk` queda como compatibilidad para tooling heredado.
41+
- El emulador Android usa `-gpu swiftshader` por defecto para evitar cierres con `-gpu host` en escritorios remotos; puedes sobrescribirlo con `ANDROID_EMULATOR_DEFAULT_GPU` o pasando `-gpu` manualmente.
4042
- Bloqueo de pantalla/ahorro de energía deshabilitado para no interrumpir builds largos.
4143
- Botones JetBrains disponibles en el dashboard (IntelliJ IDEA remoto); instala el plugin de Android para emular Android Studio y requiere JetBrains Gateway/Coder Desktop.
4244
- Home persistente en `/home/coder` (volumen o bind mount según parámetros); labels de Watchtower habilitadas.

0 commit comments

Comments
 (0)