From e312827daab653904d70a9aead6603c62e1bb544 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Mon, 2 Mar 2026 00:34:45 +0200 Subject: [PATCH 01/15] feat: add update tealdeer step --- base/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/base/Dockerfile b/base/Dockerfile index 4555ff8..6df5ae0 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -189,6 +189,8 @@ RUN bash /tmp/setup-claude.sh && rm -f /tmp/setup-claude.sh RUN echo 'source $HOME/.local/bin/init-claude-mcp.sh 2>/dev/null' >> /home/dev/.bashrc +RUN tldr --update + # ── Final root section ────────────────────────────────────────────────────── USER root From 1c180ed06655b401f86073222c27b0c8a034ba01 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Mon, 2 Mar 2026 00:35:08 +0200 Subject: [PATCH 02/15] feat: enable RC for all Claude Code sessions --- scripts/setup-claude.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/setup-claude.sh b/scripts/setup-claude.sh index 4a4bd29..88c6bf5 100755 --- a/scripts/setup-claude.sh +++ b/scripts/setup-claude.sh @@ -69,3 +69,13 @@ if [ -x "$CLAUDE" ]; then else echo "WARNING: Claude CLI not found — skipping MCP server setup" fi + +# --- Enable Remote Control for all sessions --- + +CLAUDE_JSON="$HOME/.claude.json" +if [ -f "$CLAUDE_JSON" ] && command -v jq >/dev/null 2>&1; then + jq '. + {"remoteControlAtStartup": true}' "$CLAUDE_JSON" > "$CLAUDE_JSON.tmp" \ + && mv "$CLAUDE_JSON.tmp" "$CLAUDE_JSON" +else + printf '{"remoteControlAtStartup":true}\n' > "$CLAUDE_JSON" +fi From 4c412aa0d69b0a2724dab661104df6455ac5002a Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Tue, 3 Mar 2026 02:37:18 +0200 Subject: [PATCH 03/15] refactor: setup GSD globally --- scripts/setup-claude.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup-claude.sh b/scripts/setup-claude.sh index 88c6bf5..1113255 100755 --- a/scripts/setup-claude.sh +++ b/scripts/setup-claude.sh @@ -57,7 +57,7 @@ rm -rf /tmp/everything-claude-code cd /workspace -npx -y get-shit-done-cc --claude --local +npx -y get-shit-done-cc --claude --global echo '{ "type": "commonjs" }' > /workspace/.claude/get-shit-done/bin/package.json From 4b0c3123b9df89a30d91dc0893db64e59a95ebe7 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:10:01 +0200 Subject: [PATCH 04/15] docs: update README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3ce938d..d5f6d53 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Docker-based dev containers with Claude Code, MCP servers, and common tooling pr volumes: - ..:/workspace:cached + - home:/home # Overrides default command so things don't # shut down after the process ends @@ -72,6 +73,9 @@ Docker-based dev containers with Claude Code, MCP servers, and common tooling pr ipc: host init: true + volumes: + home: + networks: default: driver: bridge From df0ae4f439221a0c399d534370b98887e9edffda Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:12:08 +0200 Subject: [PATCH 05/15] refactor: comment out RC enable --- scripts/setup-claude.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/setup-claude.sh b/scripts/setup-claude.sh index 1113255..5858b1d 100755 --- a/scripts/setup-claude.sh +++ b/scripts/setup-claude.sh @@ -72,10 +72,10 @@ fi # --- Enable Remote Control for all sessions --- -CLAUDE_JSON="$HOME/.claude.json" -if [ -f "$CLAUDE_JSON" ] && command -v jq >/dev/null 2>&1; then - jq '. + {"remoteControlAtStartup": true}' "$CLAUDE_JSON" > "$CLAUDE_JSON.tmp" \ - && mv "$CLAUDE_JSON.tmp" "$CLAUDE_JSON" -else - printf '{"remoteControlAtStartup":true}\n' > "$CLAUDE_JSON" -fi +# CLAUDE_JSON="$HOME/.claude.json" +# if [ -f "$CLAUDE_JSON" ] && command -v jq >/dev/null 2>&1; then +# jq '. + {"remoteControlAtStartup": true}' "$CLAUDE_JSON" > "$CLAUDE_JSON.tmp" \ +# && mv "$CLAUDE_JSON.tmp" "$CLAUDE_JSON" +# else +# printf '{"remoteControlAtStartup":true}\n' > "$CLAUDE_JSON" +# fi From e5d1057861b7c7eac0305a429e1d33abb222cd5d Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:14:55 +0200 Subject: [PATCH 06/15] fix: GSD setup --- scripts/setup-claude.sh | 2 -- scripts/verify-tools.sh | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/setup-claude.sh b/scripts/setup-claude.sh index 5858b1d..08b5760 100755 --- a/scripts/setup-claude.sh +++ b/scripts/setup-claude.sh @@ -59,8 +59,6 @@ cd /workspace npx -y get-shit-done-cc --claude --global -echo '{ "type": "commonjs" }' > /workspace/.claude/get-shit-done/bin/package.json - # --- MCP Servers --- if [ -x "$CLAUDE" ]; then diff --git a/scripts/verify-tools.sh b/scripts/verify-tools.sh index 827e027..61fba61 100755 --- a/scripts/verify-tools.sh +++ b/scripts/verify-tools.sh @@ -129,7 +129,8 @@ verify_base() { done # Claude ecosystem - check_file "GSD directory" "/workspace/.claude/get-shit-done" + check_file "GSD directory" "/home/dev/.claude/get-shit-done" + for script in ntfy-hook.sh suggest-context7-hook.sh init-claude-mcp.sh; do check_file "$script" "$HOME/.local/bin/$script" done From b6d6bc5e194f6c5c4eb2b8fa8006a55bc9d306e1 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:26:00 +0200 Subject: [PATCH 07/15] feat: add homebrew --- base/Dockerfile | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/base/Dockerfile b/base/Dockerfile index 6df5ae0..d24d186 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -8,6 +8,10 @@ ENV LC_ALL=C.UTF-8 # ── System packages (apt-get) ──────────────────────────────────────────────── +RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common + +RUN add-apt-repository -y ppa:git-core/ppa + RUN apt-get update \ && apt-get -y install --no-install-recommends \ apt-transport-https \ @@ -41,14 +45,48 @@ RUN apt-get update \ python3-pip \ redis-tools \ ripgrep \ - tealdeer \ sudo \ tmux \ tree \ unzip \ vim \ wget \ - xclip + xclip \ + bzip2 \ + file \ + fonts-dejavu-core \ + g++ \ + libz-dev \ + locales \ + make \ + netbase \ + patch \ + uuid-runtime \ + tzdata + +RUN localedef -i en_US -f UTF-8 en_US.UTF-8 + +RUN useradd -m -s /bin/bash linuxbrew + +RUN echo 'linuxbrew ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers + +ENV PATH=/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH + +WORKDIR /home/linuxbrew + +RUN cd /home/linuxbrew/.linuxbrew \ + && mkdir -p bin etc include lib opt sbin share var/homebrew/linked Cellar \ + && ln -s ../Homebrew/bin/brew /home/linuxbrew/.linuxbrew/bin/ \ + && git -C /home/linuxbrew/.linuxbrew/Homebrew remote set-url origin https://github.com/Homebrew/brew \ + && HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_AUTO_UPDATE=1 brew tap homebrew/core \ + && brew install-bundler-gems \ + && brew install tealdeer \ + && brew cleanup \ + && rm -rf ~/.cache \ + && chown -R linuxbrew: /home/linuxbrew/.linuxbrew \ + && chmod -R g+w,o-w /home/linuxbrew/.linuxbrew + +WORKDIR /workspace # ── CLI tools (apt repos) ─────────────────────────────────────────────────── From 1bb6c586a65fa19851603cfea1c4821faeec9425 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:33:45 +0200 Subject: [PATCH 08/15] fix: homebrew setup --- base/Dockerfile | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/base/Dockerfile b/base/Dockerfile index d24d186..61ed058 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -8,10 +8,6 @@ ENV LC_ALL=C.UTF-8 # ── System packages (apt-get) ──────────────────────────────────────────────── -RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common - -RUN add-apt-repository -y ppa:git-core/ppa - RUN apt-get update \ && apt-get -y install --no-install-recommends \ apt-transport-https \ @@ -66,25 +62,20 @@ RUN apt-get update \ RUN localedef -i en_US -f UTF-8 en_US.UTF-8 -RUN useradd -m -s /bin/bash linuxbrew +RUN useradd -m -s /bin/bash -G sudo linuxbrew \ + && echo 'linuxbrew ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers -RUN echo 'linuxbrew ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers +USER linuxbrew + +RUN NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ENV PATH=/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH -WORKDIR /home/linuxbrew +RUN HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_AUTO_UPDATE=1 brew install tealdeer \ + && brew cleanup \ + && rm -rf /home/linuxbrew/.cache -RUN cd /home/linuxbrew/.linuxbrew \ - && mkdir -p bin etc include lib opt sbin share var/homebrew/linked Cellar \ - && ln -s ../Homebrew/bin/brew /home/linuxbrew/.linuxbrew/bin/ \ - && git -C /home/linuxbrew/.linuxbrew/Homebrew remote set-url origin https://github.com/Homebrew/brew \ - && HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_AUTO_UPDATE=1 brew tap homebrew/core \ - && brew install-bundler-gems \ - && brew install tealdeer \ - && brew cleanup \ - && rm -rf ~/.cache \ - && chown -R linuxbrew: /home/linuxbrew/.linuxbrew \ - && chmod -R g+w,o-w /home/linuxbrew/.linuxbrew +USER root WORKDIR /workspace @@ -136,7 +127,7 @@ RUN curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | gpg --d # ── User setup ─────────────────────────────────────────────────────────────── -RUN id dev >/dev/null 2>&1 || useradd -m -s /bin/bash -u 1000 dev +RUN id dev >/dev/null 2>&1 || useradd -m -s /bin/bash -u 1000 -G linuxbrew dev RUN chsh -s $(which bash) dev \ && echo 'export PS1="\e[01;32m\u\e[m:\e[01;34m\w\e[m\$ "' >> /home/dev/.bashrc From 2eb8a1f745481c9771bc63137cff32df76efe86c Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:36:44 +0200 Subject: [PATCH 09/15] fix: homebrew setup UID --- base/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/base/Dockerfile b/base/Dockerfile index 61ed058..7c78950 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -62,7 +62,7 @@ RUN apt-get update \ RUN localedef -i en_US -f UTF-8 en_US.UTF-8 -RUN useradd -m -s /bin/bash -G sudo linuxbrew \ +RUN useradd -m -s /bin/bash -u 1500 -G sudo linuxbrew \ && echo 'linuxbrew ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers USER linuxbrew @@ -127,7 +127,9 @@ RUN curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | gpg --d # ── User setup ─────────────────────────────────────────────────────────────── -RUN id dev >/dev/null 2>&1 || useradd -m -s /bin/bash -u 1000 -G linuxbrew dev +RUN id dev >/dev/null 2>&1 \ + && usermod -aG linuxbrew dev \ + || useradd -m -s /bin/bash -u 1000 -G linuxbrew dev RUN chsh -s $(which bash) dev \ && echo 'export PS1="\e[01;32m\u\e[m:\e[01;34m\w\e[m\$ "' >> /home/dev/.bashrc From ec2ebcd03d163e46bebca0c17a66af92a9847245 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:41:05 +0200 Subject: [PATCH 10/15] fix: dir ownership --- base/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/Dockerfile b/base/Dockerfile index 7c78950..928f379 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -176,7 +176,8 @@ RUN apt-get autoremove -y \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -RUN chown -R dev:dev /home/dev +RUN chown -R dev:dev /home/dev \ + && mkdir -p /workspace && chown dev:dev /workspace # ── User-space tools (as USER dev) ────────────────────────────────────────── From 32e6966dcb466ea9d20df7fd06c15d937ec2f679 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 14:16:36 +0200 Subject: [PATCH 11/15] refactor: use user scope --- scripts/init-claude-mcp.sh | 17 +++++++++++------ scripts/setup-claude.sh | 6 ++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/scripts/init-claude-mcp.sh b/scripts/init-claude-mcp.sh index f87f5dd..f2851b5 100644 --- a/scripts/init-claude-mcp.sh +++ b/scripts/init-claude-mcp.sh @@ -61,10 +61,11 @@ if [ -n "$NTFY_URL" ] && [ -n "$NTFY_TOKEN" ]; then fi fi -# --- Serena project-scope config --- -# Exclude Serena memory tools via project config (not user-scope) -SERENA_PROJECT="/workspace/.serena/project.yml" -if [ -f "$SERENA_PROJECT" ] && grep -q '^excluded_tools: \[\]' "$SERENA_PROJECT"; then +# --- Serena user-scope config --- +# Exclude Serena memory tools via user config +SERENA_USER="$HOME/.serena/user.yml" +mkdir -p "$HOME/.serena" +if [ ! -f "$SERENA_USER" ] || grep -q '^excluded_tools: \[\]' "$SERENA_USER"; then if [ -n "$AUTOMEM_ENDPOINT" ] && [ -n "$AUTOMEM_API_KEY" ]; then # Automem replaces all Serena memory/onboarding tools TOOLS=(write_memory read_memory edit_memory delete_memory list_memories check_onboarding_performed onboarding) @@ -79,8 +80,12 @@ if [ -f "$SERENA_PROJECT" ] && grep -q '^excluded_tools: \[\]' "$SERENA_PROJECT" - ${t}" done - awk -v new="$YAML" '/^excluded_tools: \[\]/ { print new; next } 1' "$SERENA_PROJECT" > "$SERENA_PROJECT.tmp" - mv "$SERENA_PROJECT.tmp" "$SERENA_PROJECT" + if [ -f "$SERENA_USER" ]; then + awk -v new="$YAML" '/^excluded_tools: \[\]/ { print new; next } 1' "$SERENA_USER" > "$SERENA_USER.tmp" + mv "$SERENA_USER.tmp" "$SERENA_USER" + else + printf '%s\n' "$YAML" > "$SERENA_USER" + fi fi touch /tmp/.claude-mcp-init diff --git a/scripts/setup-claude.sh b/scripts/setup-claude.sh index 08b5760..88b639f 100755 --- a/scripts/setup-claude.sh +++ b/scripts/setup-claude.sh @@ -36,9 +36,9 @@ fi # --- Agent Browser --- -mkdir -p /workspace/.claude/skills/agent-browser +mkdir -p /home/dev/.claude/skills/agent-browser -curl -o /workspace/.claude/skills/agent-browser/SKILL.md https://raw.githubusercontent.com/vercel-labs/agent-browser/main/skills/agent-browser/SKILL.md +curl -o /home/dev/.claude/skills/agent-browser/SKILL.md https://raw.githubusercontent.com/vercel-labs/agent-browser/main/skills/agent-browser/SKILL.md # --- Hookify Fix --- @@ -55,8 +55,6 @@ rm -rf /tmp/everything-claude-code # --- GSD --- -cd /workspace - npx -y get-shit-done-cc --claude --global # --- MCP Servers --- From 816b458a2a14a1926ba6e2e1a6ef3d5c7fbaa704 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 14:17:00 +0200 Subject: [PATCH 12/15] refactor: improve user scope CLAUDE.md --- base/devcontainer-claude.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/base/devcontainer-claude.md b/base/devcontainer-claude.md index 02afda7..e860144 100644 --- a/base/devcontainer-claude.md +++ b/base/devcontainer-claude.md @@ -10,8 +10,10 @@ This is a DevContainer running Debian Trixie. You are the `dev` user with passwo ### CLI Tools - `git`, `gh` (GitHub CLI), `delta` (git-delta) +- `docker`, `docker compose` (Docker CLI + Compose plugin) - `aws` (AWS CLI v2), `terraform`, `kubectl`, `stripe` - `claude` (Claude Code CLI) +- `brew` (Homebrew — used for select packages, on `$PATH` via `/home/linuxbrew/.linuxbrew/bin`) ### Search & Productivity - `rg` (ripgrep), `fdfind` (fd-find), `fzf`, `batcat` (bat), `tldr` (tealdeer) @@ -29,13 +31,19 @@ This is a DevContainer running Debian Trixie. You are the `dev` user with passwo ### Networking - `curl`, `wget`, `nc` (netcat), `ssh` +### PDF & Document Tools +- `pdftotext`, `pdftoppm`, `pdfinfo` (poppler-utils) + ### Other -- `tmux`, `ttyd`, `agent-browser`, `xclip`, `unzip` +- `tmux`, `ttyd` (web terminal on port 7681), `agent-browser`, `xclip`, `unzip` ## Working directory Default: `/workspace` ## MCP Servers + +MCP servers are configured on first shell login via `init-claude-mcp.sh`. Optional servers are only added when their env vars are set. + - `serena` — semantic code analysis (symbols, references, overview) - `context7` — library documentation lookup (if CONTEXT7_API_KEY is set) - `memory` — persistent memory via Automem (if AUTOMEM_ENDPOINT is set) @@ -43,13 +51,28 @@ Default: `/workspace` ## Plugins & Skills - GSD (`/gsd:*`) — project management and execution workflow - superpowers — brainstorming, TDD, debugging, code review skills +- everything-claude-code (ECC) — rules installed at `~/.claude/rules/` - feature-dev, frontend-design, code-review, commit-commands, pr-review-toolkit -- hookify, playground, claude-md-management +- hookify, playground, claude-md-management, claude-code-setup +- ralph-loop, security-guidance +- explanatory-output-style, learning-output-style +- typescript-lsp, pyright-lsp, php-lsp, laravel-boost +- agent-browser skill at `~/.claude/skills/agent-browser/SKILL.md` ## Hooks - Context7 suggestion hook — suggests context7 when WebSearch is used (if configured) - Ntfy notification hook — sends push notifications on task completion (if configured) +## Browser Automation + +Use `agent-browser` for web automation. Run `agent-browser --help` for all commands. + +Core workflow: +1. `agent-browser open ` - Navigate to page +2. `agent-browser snapshot -i` - Get interactive elements with refs (@e1, @e2) +3. `agent-browser click @e1` / `fill @e2 "text"` - Interact using refs +4. Re-snapshot after page changes + ## Notes - Shell is bash. `/bin/sh` is symlinked to `/bin/bash`. - Passwordless sudo is available via `sudo`. From 66c0bc07e96e1b9e62a64fd4cea4f73f98e09c77 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 14:17:17 +0200 Subject: [PATCH 13/15] fix: homebrew setup permissions --- base/Dockerfile | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/base/Dockerfile b/base/Dockerfile index 928f379..39ec4be 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -77,6 +77,8 @@ RUN HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_AUTO_UPDATE=1 brew install tealdeer \ USER root +RUN chmod -R g+rX /home/linuxbrew + WORKDIR /workspace # ── CLI tools (apt repos) ─────────────────────────────────────────────────── @@ -85,6 +87,11 @@ WORKDIR /workspace RUN curl -s https://packages.stripe.dev/api/security/keypair/stripe-cli-gpg/public | gpg --dearmor | tee /usr/share/keyrings/stripe.gpg \ && echo "deb [signed-by=/usr/share/keyrings/stripe.gpg] https://packages.stripe.dev/stripe-cli-debian-local stable main" | tee -a /etc/apt/sources.list.d/stripe.list +# Docker CLI +RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/debian trixie stable" \ + | tee /etc/apt/sources.list.d/docker.list + # GH CLI + Stripe CLI install RUN mkdir -p -m 755 /etc/apt/keyrings \ && out=$(mktemp) \ @@ -94,7 +101,7 @@ RUN mkdir -p -m 755 /etc/apt/keyrings \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ && apt-get update \ - && apt-get -y install --no-install-recommends gh stripe + && apt-get -y install --no-install-recommends gh stripe docker-ce-cli docker-compose-plugin # ── CLI tools (releases) ──────────────────────────────────────────────────── @@ -127,9 +134,11 @@ RUN curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | gpg --d # ── User setup ─────────────────────────────────────────────────────────────── +RUN groupadd -f docker + RUN id dev >/dev/null 2>&1 \ - && usermod -aG linuxbrew dev \ - || useradd -m -s /bin/bash -u 1000 -G linuxbrew dev + && usermod -aG linuxbrew,docker dev \ + || useradd -m -s /bin/bash -u 1000 -G linuxbrew,docker dev RUN chsh -s $(which bash) dev \ && echo 'export PS1="\e[01;32m\u\e[m:\e[01;34m\w\e[m\$ "' >> /home/dev/.bashrc From 77085ec2eb51c5e92ab3adcc2156234a266a73f5 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 14:21:55 +0200 Subject: [PATCH 14/15] docs: update README --- README.md | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d5f6d53..759c2e4 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Docker-based dev containers with Claude Code, MCP servers, and common tooling pr volumes: - ..:/workspace:cached - home:/home + - /var/run/docker.sock:/var/run/docker.sock # Overrides default command so things don't # shut down after the process ends @@ -93,6 +94,10 @@ Docker-based dev containers with Claude Code, MCP servers, and common tooling pr "service": "app", "workspaceFolder": "/workspace", + "mounts": [ + "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" + ], + "forwardPorts": [3000, 4983, 5173, 5174], "portsAttributes": { @@ -140,10 +145,12 @@ All images extend a shared base (`base/Dockerfile` — `debian:trixie`) and run | Image | Extra stack | |-------|-------------| +| `ghcr.io/recoskyler/devcontainer-base:latest` | — (base only) | | `ghcr.io/recoskyler/trixie-bun-nvm-uv-claude:latest` | Bun | | `ghcr.io/recoskyler/trixie-php-nvm-uv-claude:latest` | PHP 8.4, Composer | | `ghcr.io/recoskyler/trixie-rust-nvm-uv-claude:latest` | Rust toolchain | | `ghcr.io/recoskyler/trixie-vnc-nvm-uv-claude:latest` | x11vnc, Xvfb | +| `ghcr.io/recoskyler/trixie-vnc-flutter-rust-nvm-uv-claude:latest` | Flutter, Rust, Android SDK, VNC | ## What's Included @@ -155,8 +162,10 @@ All images extend a shared base (`base/Dockerfile` — `debian:trixie`) and run - **MCP servers**: Serena, Context7, Automem - **GSD** (Get Shit Done for Claude Code) - **Agent Browser** + Chrome +- **Docker** CLI + Compose plugin (`docker`, `docker compose`) — mount the host socket to use - **CLI tools**: git, curl, wget, vim, nano, jq, tmux, xclip, openssh-client, gnupg, cmake, less, unzip, gh, pnpm, tsx - **Search & file tools**: ripgrep, fd-find, fzf, bat, tree +- **PDF tools**: poppler-utils (pdftotext, pdfinfo, etc.) - **Networking & HTTP**: httpie, netcat - **Cloud & infra**: AWS CLI v2, Terraform, kubectl, Stripe CLI - **Utilities**: duf, git-delta, tldr @@ -185,6 +194,18 @@ All images extend a shared base (`base/Dockerfile` — `debian:trixie`) and run - **x11vnc**, **Xvfb**, xdg-utils +### Flutter (`trixie-vnc-flutter-rust-nvm-uv-claude`) + +Extends the VNC image with Flutter, Rust, and Android tooling. + +- **Flutter** via FVM (`flutter`, `dart`, `fvm`) +- **Rust** toolchain (rustup, rustfmt, clippy, cargo-watch, cargo-edit, cargo-nextest) +- **Android SDK**: cmdline-tools, platform-tools, build-tools (28.0.3 + 35.0.0), API 35 + 36 +- **Android Emulator** with SwiftShader (AVD: `flutter_pixel7`, Pixel 7, API 35) +- **Android Studio** Panda 1 (at `/opt/android-studio`) +- **Chromium** (`CHROME_EXECUTABLE` set for `flutter run -d chrome`) +- **OpenJDK 21** (headless) + ## Build Arguments | Argument | Default | Description | @@ -209,10 +230,10 @@ Secret-dependent MCP servers and ntfy hooks are configured at **runtime** (first Two GitHub Actions workflows build and verify images: -- **`build.yml`** — Runs on push to `latest` or version tags. Builds the base image with GHA cache, then builds and pushes all 4 variants to GHCR in parallel (matrix strategy). -- **`check.yml`** — Runs on PRs to `latest`. Same structure but read-only cache (no `cache-to`) and no push to GHCR. +- **`build.yml`** — Runs on push to `latest` or version tags. Builds the base image with GHA cache, then builds and pushes all 5 variants to GHCR in parallel (matrix strategy). +- **`check.yml`** — Runs on PRs to `latest`. Same structure but read-only cache (no `cache-to`) and no push to GHCR. Each variant runs tool verification and posts results as PR comments. -Both workflows use a local `registry:2` service container and `build-contexts` to remap `FROM devcontainer-base:latest` at build time, requiring zero Dockerfile changes. +Both workflows use a local `registry:2` service container and `build-contexts` to remap `FROM` images at build time, requiring zero Dockerfile changes. The flutter variant has a three-tier chain (base → VNC → flutter) with a conditional VNC rebuild step. Images are published to GHCR at `ghcr.io//`. @@ -230,14 +251,22 @@ Images are published to GHCR at `ghcr.io//`. Build locally: ```bash -# Build base first -docker build -t devcontainer-base:latest -f base/Dockerfile . +# Build base first (NODE_VERSION is a base ARG) +docker build -t devcontainer-base:latest \ + --build-arg NODE_VERSION=24.12.0 \ + -f base/Dockerfile . # Then build a variant docker build \ -f trixie-bun-nvm-uv-claude/Dockerfile \ - --build-arg NODE_VERSION=24.12.0 \ -t trixie-bun-nvm-uv-claude . + +# Flutter requires VNC as an intermediate layer +docker build -t trixie-vnc-nvm-uv-claude:latest \ + -f trixie-vnc-nvm-uv-claude/Dockerfile . +docker build \ + -f trixie-vnc-flutter-rust-nvm-uv-claude/Dockerfile \ + -t trixie-vnc-flutter-rust-nvm-uv-claude . ``` Then run with your API keys as environment variables: @@ -254,7 +283,7 @@ docker run -it \ ## Agent Browser -The skill is already installed. You may want to add the following to `AGENTS.md`/`CLAUDE.md`: +The skill is already installed, and the following section is already included in all images `~/.claude/CLAUDE.md`. ```md ## Browser Automation From 7acb75fae366f934ca9cb4f11a803f94bede4c46 Mon Sep 17 00:00:00 2001 From: Adil Atalay Hamamcioglu <38231748+recoskyler@users.noreply.github.com> Date: Sat, 7 Mar 2026 14:22:19 +0200 Subject: [PATCH 15/15] chore: ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8ae687c..0a5d564 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ docs/plans node_modules .serena CLAUDE.md +.devcontainer