FROM coder-devbox-base-config:latest AS base-default USER root RUN DEBIAN_FRONTEND=noninteractive apt-get update -y -qqq \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends -qqq libpq-dev libffi-dev zlib1g-dev libedit-dev libyaml-dev redis-server libicu-dev postgresql-client psmisc USER coder RUN echo "[ Installing .NET SDK via dotnet-install.sh (jincod/dotnetcore-buildpack approach) ]" \ && sudo DEBIAN_FRONTEND=noninteractive apt-get update -y -qqq \ && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends -qqq libicu-dev libssl-dev curl \ && DOTNET_INSTALL_DIR="$HOME/.dotnet" \ && mkdir -p "$DOTNET_INSTALL_DIR" \ && curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh \ && chmod +x /tmp/dotnet-install.sh \ && /tmp/dotnet-install.sh --channel LTS --install-dir "$DOTNET_INSTALL_DIR" \ && "$DOTNET_INSTALL_DIR/dotnet" tool install --global dotnet-ef \ && "$DOTNET_INSTALL_DIR/dotnet" --version USER root # .NET lives entirely under /home/coder/.dotnet — invisible to Kilo's own # agent process (spawned non-interactively, never sources ~/.bashrc), needed # for the csharp built-in LSP, which auto-installs roslyn-language-server via # `dotnet tool install` if `dotnet` is found on PATH. Copy out to image-owned # territory and put on PATH via ENV, so it works regardless of the home # volume's state. RUN mkdir -p /usr/local/dotnet \ && cp -a /home/coder/.dotnet/. /usr/local/dotnet/ \ && chown -R coder:coder /usr/local/dotnet ENV DOTNET_ROOT=/usr/local/dotnet ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 ENV NUGET_XMLDOC_MODE=skip ENV PATH="/usr/local/dotnet:/usr/local/dotnet/tools:${PATH}" USER coder RUN dotnet --version # csharp-ls (.NET tool) + Claude Code's plugin wrapper around it — same # pattern as php-lsp/intelephense and ruby-lsp. `--tool-path # /usr/local/dotnet/tools` (not plain `--global`, which would resolve to # ~/.dotnet/tools under /home/coder — the per-workspace volume the dotnet-ef # install above was deliberately copied OUT of) puts it directly in the # already-PATH'd, image-owned tools dir, so it works regardless of the home # volume's state, same as dotnet-ef. RUN dotnet tool install --tool-path /usr/local/dotnet/tools csharp-ls \ && "$HOME/.local/bin/claude" plugin install csharp-lsp@claude-plugins-official \ && codex plugin add csharp-lsp@claude-plugins-official RUN echo "[ Installing Heroku CLI ]" \ && curl https://cli-assets.heroku.com/install.sh | sh RUN echo ".NET ready: $(dotnet --version)"