|
1 | 1 | FROM mcr.microsoft.com/devcontainers/base:debian |
2 | 2 |
|
3 | | -# gosu is used by the entrypoint to drop privileges. |
4 | 3 | # ca-certificates, curl, git are already in the devcontainers base image. |
| 4 | +# fd-find: fast file finder (aliased to fd below) |
| 5 | +# fzf: fuzzy finder for files and command history |
| 6 | +# gh: GitHub CLI |
| 7 | +# gosu: drops privileges in the entrypoint |
| 8 | +# jq: JSON processor |
| 9 | +# ripgrep: fast recursive grep (rg) |
| 10 | +# tmux: terminal multiplexer |
| 11 | +# vim: text editor |
5 | 12 | RUN apt-get update \ |
6 | | - && apt-get install -y --no-install-recommends gh gosu jq vim \ |
| 13 | + && apt-get install -y --no-install-recommends fd-find fzf gh gosu jq ripgrep tmux vim \ |
| 14 | + && ln -s $(which fdfind) /usr/local/bin/fd \ |
7 | 15 | && rm -rf /var/lib/apt/lists/* |
8 | 16 |
|
9 | 17 | COPY --chmod=755 sandcat/scripts/app-init.sh /usr/local/bin/app-init.sh |
10 | 18 | COPY --chmod=755 sandcat/scripts/app-user-init.sh /usr/local/bin/app-user-init.sh |
| 19 | +COPY --chown=vscode:vscode sandcat/tmux.conf /home/vscode/.tmux.conf |
11 | 20 |
|
12 | 21 | USER vscode |
13 | 22 |
|
14 | | -# Install mise (SDK manager), then use it to install Node.js and Claude Code. |
| 23 | +# Install Claude Code (native binary — no Node.js required). |
| 24 | +RUN curl -fsSL https://claude.ai/install.sh | bash |
| 25 | + |
| 26 | +# Install mise (SDK manager) for language toolchains. |
15 | 27 | RUN curl https://mise.run | sh |
16 | 28 | # Make mise available in login shells (su - vscode) and Docker CMD/RUN. |
17 | 29 | RUN echo 'export PATH="/home/vscode/.local/bin:/home/vscode/.local/share/mise/shims:$PATH"' >> /home/vscode/.profile |
18 | 30 | ENV PATH="/home/vscode/.local/bin:/home/vscode/.local/share/mise/shims:$PATH" |
19 | | -RUN mise use -g node@lts \ |
20 | | - && npm install -g @anthropic-ai/claude-code |
21 | | - |
22 | | -RUN mise use -g java@21 |
23 | | -RUN mise use -g sbt@1.12 |
24 | 31 |
|
25 | | -# If Java was installed above, bake JAVA_HOME and trust-store paths into the |
26 | | -# image. VS Code may probe the environment before the entrypoint finishes |
27 | | -# importing the mitmproxy CA; having these ready avoids a race where Metals |
28 | | -# (or other JVM tooling) starts without JAVA_HOME or JAVA_TOOL_OPTIONS. |
29 | | -# The entrypoint will import the mitmproxy CA into the cacerts copy at runtime. |
| 32 | +# Development stacks (managed by sandcat init --stacks): |
| 33 | +RUN mise use -g java@lts |
| 34 | +RUN mise use -g scala@latest && mise use -g sbt@latest |
| 35 | +# END STACKS |
| 36 | + |
| 37 | +# If Java was installed above, bake JAVA_HOME and JAVA_TOOL_OPTIONS into |
| 38 | +# .bashrc so VS Code's env probe picks them up before the entrypoint runs. |
| 39 | +# Without JAVA_HOME, JVM tooling like Metals fails to find the JDK. |
| 40 | +# JAVA_TOOL_OPTIONS points to a trust store copy that the entrypoint will |
| 41 | +# populate with the mitmproxy CA at runtime; until then it holds the default |
| 42 | +# Java CAs (harmless — equivalent to not setting it at all). |
| 43 | +# A version-independent symlink is used so .bashrc doesn't need updating |
| 44 | +# when the Java version changes — only the symlink target is updated. |
30 | 45 | RUN if MISE_JAVA=$(mise where java 2>/dev/null); then \ |
31 | 46 | dir="$HOME/.local/share/sandcat"; mkdir -p "$dir"; \ |
32 | 47 | ln -sfn "$MISE_JAVA" "$dir/java-home"; \ |
33 | 48 | cp "$MISE_JAVA/lib/security/cacerts" "$dir/cacerts" 2>/dev/null || true; \ |
34 | 49 | { echo ''; \ |
35 | 50 | echo '# sandcat-java-env'; \ |
36 | | - echo '_sc_java="$HOME/.local/share/sandcat/java-home"'; \ |
37 | | - echo '_sc_cacerts="$HOME/.local/share/sandcat/cacerts"'; \ |
38 | | - echo '[ -L "$_sc_java" ] && export JAVA_HOME="$_sc_java"'; \ |
39 | | - echo '[ -f "$_sc_cacerts" ] && export JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStore=$_sc_cacerts -Djavax.net.ssl.trustStorePassword=changeit"'; \ |
40 | | - echo 'unset _sc_java _sc_cacerts'; \ |
| 51 | + echo '[ -L "$HOME/.local/share/sandcat/java-home" ] && export JAVA_HOME="$HOME/.local/share/sandcat/java-home"'; \ |
| 52 | + echo '[ -f "$HOME/.local/share/sandcat/cacerts" ] && export JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStore=$HOME/.local/share/sandcat/cacerts -Djavax.net.ssl.trustStorePassword=changeit"'; \ |
41 | 53 | } >> "$HOME/.bashrc"; \ |
42 | 54 | fi |
43 | 55 |
|
44 | | -# Pre-create the Claude config directory and seed onboarding flag so Claude |
45 | | -# Code can use an API key from the environment without interactive setup. |
46 | | -RUN mkdir -p /home/vscode/.claude \ |
47 | | - && echo '{"hasCompletedOnboarding":true}' > /home/vscode/.claude.json |
| 56 | +# Pre-create ~/.claude so Docker bind-mounts (CLAUDE.md, agents/, commands/) |
| 57 | +# don't cause it to be created as root-owned. |
| 58 | +RUN mkdir -p /home/vscode/.claude |
48 | 59 |
|
49 | 60 | RUN echo 'alias claude-yolo="claude --dangerously-skip-permissions"' >> /home/vscode/.bashrc |
50 | 61 |
|
|
0 commit comments