Repository navigation
Expand file tree
/
Copy pathcompose.headless.yml
More file actions
91 lines (85 loc) · 3.56 KB
/
Copy pathcompose.headless.yml
File metadata and controls
91 lines (85 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# Headless agentic UI iteration stack.
#
# tauri-headless : the dev (debug) app + Xvfb + tauri-driver (port 4444),
# driven by Claude Code through the tauri-docker MCP
# (docker exec -i tauri-headless npx -y github:VoltiusApp/mcp-tauri-automation).
# ssh-host-1 : a throwaway SSH server (linuxserver/openssh-server) so the
# app has a real host to add / connect / SFTP against.
#
# Both services share one user-defined network, so the app resolves the host
# by name (ssh-host-1). It listens on port 2222 with password auth —
# user "voltius", password "voltius".
#
# docker compose -f compose.headless.yml up -d
# docker compose -f compose.headless.yml logs -f tauri-headless # wait for tauri-driver
# claude mcp add tauri-docker -- docker exec -i tauri-headless npx -y github:VoltiusApp/mcp-tauri-automation
#
# NOTE: tauri-headless needs seccomp=unconfined — the app's OS keychain uses the
# kernel keyutils keyring, which the default Docker seccomp profile blocks
# (otherwise the app hangs on its splash).
name: voltius-headless
services:
tauri-headless:
build:
context: .
dockerfile: Dockerfile.tauri-headless
args:
# Matches the container's build user to the host's, so pnpm install and
# cargo stop leaving root-owned files in the mounted worktree. Export
# UID/GID before `up` if your host ids are not 1000.
UID: ${UID:-1000}
GID: ${GID:-1000}
image: tauri-mcp
container_name: tauri-headless
security_opt:
- seccomp=unconfined
environment:
# WebKitGTK renders opacity/transform animations on GPU compositor layers that
# Xvfb's software path never flushes to the X framebuffer — so screen-grabbed
# captures (ffmpeg x11grab / driver screenshots) miss every CSS transition and
# animation. Forcing compositing off paints everything into the readable window
# buffer, so captured video/screenshots show animations faithfully.
- WEBKIT_DISABLE_COMPOSITING_MODE=1
volumes:
- .:/app
# The container gets its own node_modules. Sharing the host's poisons it:
# pnpm records an absolute `storeDir` in node_modules/.modules.yaml, the
# container's differs from the host's, and the next host command decides
# the tree is foreign and asks to purge it — which fails outside a TTY,
# so the plugin-bundle tests start failing with a bare "Command failed".
# (Recovery if it happens anyway: `CI=true pnpm install` on the host.)
- voltius-node-modules:/app/node_modules
# CARGO_TARGET_DIR. Deliberately not inside /app: vite's watcher crawls a
# target dir under its root, climbs to ~15GB RSS, and the webview then
# never loads — which presents as every WebDriver call hanging.
- voltius-target:/target
networks:
- voltius-test
ssh-host-1:
image: lscr.io/linuxserver/openssh-server:latest
container_name: ssh-host-1
hostname: ssh-host-1
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- PASSWORD_ACCESS=true
- USER_NAME=voltius
- USER_PASSWORD=voltius
- SUDO_ACCESS=true
networks:
- voltius-test
# Debian/glibc/apt shape for catalogue snippet testing. No sshd — it is driven
# with `docker exec`, because the scripts under test are shell, not SSH.
deb-host:
image: debian:bookworm-slim
container_name: deb-host
command: sleep infinity
networks:
- voltius-test
networks:
voltius-test:
driver: bridge
volumes:
voltius-target:
voltius-node-modules: