Created
May 20, 2026 08:31
-
-
Save rhuss/0321c36106c10430c84a301c264b6510 to your computer and use it in GitHub Desktop.
OpenShell sandbox Containerfile for Claude Code (cc-deck) - reproduces getifaddrs issue with Vertex AI auth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # GENERATED BY cc-deck.build --target openshell - DO NOT EDIT MANUALLY | |
| # Regenerate with: claude /cc-deck.build --target openshell | |
| FROM ghcr.io/nvidia/openshell-community/sandboxes/base:latest | |
| ARG TARGETARCH | |
| # Layer: System packages (Ubuntu 24.04, apt-get) | |
| # Pre-installed: git, node v22, npm, python3, curl, make, claude, gh, uv | |
| USER root | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| zsh \ | |
| jq \ | |
| ripgrep \ | |
| bat \ | |
| binaryen \ | |
| fzf \ | |
| unzip \ | |
| xz-utils \ | |
| && ln -sf /usr/bin/batcat /usr/bin/bat \ | |
| && apt-get clean && rm -rf /var/lib/apt/lists/* | |
| # Layer: Rust (via rustup, for sandbox user) | |
| USER sandbox | |
| ENV RUSTUP_HOME=/sandbox/.rustup CARGO_HOME=/sandbox/.cargo | |
| RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \ | |
| && . /sandbox/.cargo/env \ | |
| && rustup target add wasm32-wasip1 | |
| ENV PATH="/sandbox/.cargo/bin:${PATH}" | |
| USER root | |
| # Layer: Go (official tarball) | |
| RUN GOARCH=$([ "$(uname -m)" = "aarch64" ] && echo arm64 || echo amd64) && \ | |
| curl -fsSL "https://go.dev/dl/go1.25.3.linux-${GOARCH}.tar.gz" | tar -C /usr/local -xzf - | |
| ENV PATH="/usr/local/go/bin:${PATH}" | |
| # Layer: Developer tools from GitHub releases | |
| RUN ARCH=$(uname -m) && \ | |
| GOARCH=$([ "$ARCH" = "aarch64" ] && echo arm64 || echo amd64) && \ | |
| # starship prompt | |
| curl -fsSL https://starship.rs/install.sh | sh -s -- -y && \ | |
| # zoxide | |
| curl -fsSL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh && \ | |
| mv /root/.local/bin/zoxide /usr/local/bin/zoxide && \ | |
| # lsd | |
| LSD_VER=$(curl -fsSL https://api.github.com/repos/lsd-rs/lsd/releases/latest | jq -r '.tag_name' | sed 's/^v//') && \ | |
| curl -fsSL "https://github.com/lsd-rs/lsd/releases/download/v${LSD_VER}/lsd-v${LSD_VER}-${ARCH}-unknown-linux-gnu.tar.gz" \ | |
| | tar xz -C /tmp && mv /tmp/lsd-v${LSD_VER}-${ARCH}-unknown-linux-gnu/lsd /usr/local/bin/lsd && \ | |
| # helix editor | |
| HX_VER=$(curl -fsSL https://api.github.com/repos/helix-editor/helix/releases/latest | jq -r '.tag_name') && \ | |
| curl -fsSL "https://github.com/helix-editor/helix/releases/download/${HX_VER}/helix-${HX_VER}-${ARCH}-linux.tar.xz" \ | |
| | tar xJ -C /opt && ln -sf /opt/helix-${HX_VER}-${ARCH}-linux/hx /usr/local/bin/hx && \ | |
| # rtk (tar.gz, not tar.xz) | |
| curl -fsSL "https://github.com/rtk-ai/rtk/releases/latest/download/rtk-${ARCH}-unknown-linux-gnu.tar.gz" \ | |
| | tar xz -C /usr/local/bin rtk && chmod +x /usr/local/bin/rtk && \ | |
| # abtop (nested in directory inside archive) | |
| curl -fsSL "https://github.com/graykode/abtop/releases/latest/download/abtop-${ARCH}-unknown-linux-gnu.tar.xz" \ | |
| | tar xJ -C /tmp && mv /tmp/abtop-${ARCH}-unknown-linux-gnu/abtop /usr/local/bin/abtop && chmod +x /usr/local/bin/abtop && \ | |
| rm -rf /tmp/abtop-* && \ | |
| rm -rf /tmp/lsd-* | |
| # ============================================================ | |
| # MANDATORY: cc-deck + Zellij + cc-session + cc-setup (DO NOT OMIT) | |
| # ============================================================ | |
| # MANDATORY Layer: cc-session (nested archive) | |
| RUN ARCH=$(uname -m) && \ | |
| curl -fsSL "https://github.com/cc-deck/cc-session/releases/latest/download/cc-session-${ARCH}-unknown-linux-gnu.tar.xz" \ | |
| | tar xJ -C /tmp && \ | |
| mv /tmp/cc-session-${ARCH}-unknown-linux-gnu/cc-session /usr/local/bin/cc-session && \ | |
| chmod +x /usr/local/bin/cc-session && \ | |
| rm -rf /tmp/cc-session-* | |
| # MANDATORY Layer: cc-setup (Go-style naming: version-os-goarch.tar.gz) | |
| RUN GOARCH=$([ "$(uname -m)" = "aarch64" ] && echo arm64 || echo amd64) && \ | |
| VERSION=$(curl -fsSL https://api.github.com/repos/cc-deck/cc-setup/releases/latest | jq -r '.tag_name' | sed 's/^v//') && \ | |
| curl -fsSL "https://github.com/cc-deck/cc-setup/releases/download/v${VERSION}/cc-setup-${VERSION}-linux-${GOARCH}.tar.gz" \ | |
| | tar xz -C /usr/local/bin cc-setup && \ | |
| chmod +x /usr/local/bin/cc-setup | |
| # MANDATORY Layer: cc-deck self-install (Zellij + plugin + layouts + hooks) | |
| COPY openshell/context/cc-deck-linux-${TARGETARCH} /usr/local/bin/cc-deck | |
| RUN chmod +x /usr/local/bin/cc-deck && \ | |
| mkdir -p /sandbox/.claude /sandbox/.cache/zellij && \ | |
| HOME=/sandbox \ | |
| ZELLIJ_CONFIG_DIR=/sandbox/.config/zellij \ | |
| cc-deck config plugin install --install-zellij --force --skip-backup && \ | |
| chown -R sandbox:sandbox /sandbox/.config/zellij /sandbox/.cache/zellij /sandbox/.claude && \ | |
| rm -rf /root/.claude /root/.cache/zellij | |
| # MANDATORY Layer: Claude Code (upgrade existing installation) | |
| RUN mkdir -p /sandbox/.cache && chown sandbox:sandbox /sandbox/.cache | |
| USER sandbox | |
| RUN curl -fsSL https://claude.ai/install.sh | bash | |
| USER root | |
| ENV PATH="/sandbox/.local/bin:${PATH}" | |
| # ============================================================ | |
| # Layer: Claude Code plugins | |
| USER sandbox | |
| RUN claude plugins marketplace add anthropics/claude-plugins-official && \ | |
| claude plugins marketplace add kepano/obsidian-skills && \ | |
| claude plugins install superpowers@claude-plugins-official && \ | |
| claude plugins install gopls-lsp@claude-plugins-official && \ | |
| claude plugins install rust-analyzer-lsp@claude-plugins-official && \ | |
| claude plugins install obsidian@obsidian-skills | |
| USER root | |
| # Layer: Skills directories | |
| RUN mkdir -p /sandbox/.agents/skills/ /sandbox/.claude/skills/ && \ | |
| chown -R sandbox:sandbox /sandbox/.agents /sandbox/.claude | |
| # Layer: OpenShell policy | |
| RUN mkdir -p /etc/openshell | |
| COPY openshell/policy.yaml /etc/openshell/policy.yaml | |
| # Layer: Shell environment | |
| ENV SHELL="/bin/zsh" | |
| # Layer: User configuration | |
| # Git identity | |
| USER sandbox | |
| RUN git config --global user.name "Roland Huß" && \ | |
| git config --global user.email "rhuss@redhat.com" | |
| USER root | |
| # Shell: set zsh as default, append custom config | |
| RUN chsh -s /bin/zsh sandbox 2>/dev/null || usermod -s /bin/zsh sandbox | |
| COPY --chown=sandbox:sandbox openshell/context/zshrc /sandbox/.zshrc.custom | |
| RUN touch /sandbox/.zshrc && cat /sandbox/.zshrc.custom >> /sandbox/.zshrc && rm /sandbox/.zshrc.custom | |
| # Zellij user config (controller block stripped, re-injected by cc-deck below) | |
| COPY --chown=sandbox:sandbox openshell/context/zellij-config.kdl /sandbox/.config/zellij/config.kdl | |
| COPY --chown=sandbox:sandbox openshell/context/zellij-theme-claude-dark.kdl /sandbox/.config/zellij/themes/claude-dark.kdl | |
| RUN grep -qE '^default_shell' /sandbox/.config/zellij/config.kdl || \ | |
| echo 'default_shell "zsh"' >> /sandbox/.config/zellij/config.kdl | |
| # Claude global instructions | |
| COPY --chown=sandbox:sandbox openshell/context/CLAUDE.md /sandbox/.claude/CLAUDE.md | |
| # Claude settings (merge with existing cc-deck hooks) | |
| COPY --chown=sandbox:sandbox openshell/context/claude-settings.json /tmp/user-settings.json | |
| RUN jq -s '.[0] * .[1]' /sandbox/.claude/settings.json /tmp/user-settings.json > /tmp/merged.json \ | |
| && mv /tmp/merged.json /sandbox/.claude/settings.json \ | |
| && chown sandbox:sandbox /sandbox/.claude/settings.json \ | |
| && rm -f /tmp/user-settings.json | |
| # cc-setup MCP cache | |
| RUN mkdir -p /sandbox/.config/cc-setup | |
| COPY --chown=sandbox:sandbox openshell/context/cc-setup-mcp.json /sandbox/.config/cc-setup/mcp.json | |
| # Tool configs | |
| COPY --chown=sandbox:sandbox openshell/context/starship.toml /sandbox/.config/starship.toml | |
| RUN mkdir -p /sandbox/.config/helix | |
| COPY --chown=sandbox:sandbox openshell/context/helix-config.toml /sandbox/.config/helix/config.toml | |
| RUN mkdir -p /sandbox/.config/bat /sandbox/.config/lsd | |
| COPY --chown=sandbox:sandbox openshell/context/bat-config /sandbox/.config/bat/config | |
| COPY --chown=sandbox:sandbox openshell/context/lsd-config.yaml /sandbox/.config/lsd/config.yaml | |
| # Re-inject cc-deck controller and hooks after config copies | |
| USER sandbox | |
| RUN cc-deck config plugin install --force --skip-backup | |
| USER root | |
| # RTK post-install | |
| RUN mkdir -p /sandbox/.config/rtk && chown -R sandbox:sandbox /sandbox/.config/rtk | |
| USER sandbox | |
| RUN rtk init -g || true | |
| USER root | |
| # ============================================================ | |
| # FINAL SHELL SETUP (MUST come AFTER all user config COPY/RUN layers) | |
| # These append to .bashrc/.zshrc and must not be overwritten by later steps. | |
| # ============================================================ | |
| # Layer: Starship prompt init (if starship is available in the image) | |
| RUN if command -v starship >/dev/null 2>&1; then \ | |
| for PAIR in "bash:/sandbox/.bashrc" "zsh:/sandbox/.zshrc"; do \ | |
| SHELL_NAME="${PAIR%%:*}"; RC="${PAIR#*:}"; \ | |
| if [ -f "$RC" ] && ! grep -q 'starship init' "$RC"; then \ | |
| echo 'eval "$(starship init '"$SHELL_NAME"')"' >> "$RC"; \ | |
| fi; \ | |
| done; \ | |
| fi | |
| # Layer: Auto-start Zellij on interactive login (for cc-deck ws attach) | |
| # This MUST be the LAST addition to shell rc files (exec replaces the shell). | |
| RUN PREFERRED_SHELL=$(getent passwd sandbox | cut -d: -f7) && \ | |
| for RC in /sandbox/.bashrc /sandbox/.zshrc; do \ | |
| if [ -f "$RC" ] || [ "$(basename $RC)" = ".bashrc" ]; then \ | |
| printf '\n# cc-deck: auto-start Zellij with cc-deck layout on interactive login\nif [ -z "$ZELLIJ" ] && [ -t 0 ]; then\n export SHELL=%s\n exec zellij --layout cc-deck attach --create cc-deck\nfi\n' "$PREFERRED_SHELL" >> "$RC"; \ | |
| fi; \ | |
| done | |
| # Layer: Fix ownership of all sandbox home files modified by root layers above. | |
| RUN chown -R sandbox:sandbox /sandbox | |
| USER sandbox | |
| WORKDIR /sandbox | |
| ENTRYPOINT ["/bin/bash"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment