FROM debian:bookworm-slim # Base system packages — no golang-go/rustc/cargo from apt (replaced by rustup + install_latest_go.sh) RUN apt-get update && apt-get install -y --no-install-recommends \ clang clangd pkg-config build-essential git make curl \ nodejs npm \ python3 python3-pip pylint black flake8 mypy isort \ logrotate sudo cmake zlib1g-dev \ libcurl4-openssl-dev libssl-dev \ ruby-dev libicu-dev \ jq \ r-base \ sqlite3 wget bash zsh \ && apt-get clean && rm -rf /var/lib/apt/lists/* # Go — latest via script only (no apt golang-go) COPY tools/install_latest_go.sh /tmp/install_latest_go.sh RUN bash /tmp/install_latest_go.sh && rm /tmp/install_latest_go.sh ENV PATH=/usr/local/go/bin:$PATH # Rust — rustup only (no apt rustc/cargo), stable only, no rust-docs ENV RUSTUP_HOME=/usr/local/rustup ENV CARGO_HOME=/usr/local/cargo ENV PATH=/usr/local/cargo/bin:$PATH RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --no-modify-path \ && rustup component add rustfmt clippy rust-src rust-analyzer \ && rustup install nightly --no-self-update \ && rustup component add rust-analyzer --toolchain nightly \ # Install cargo tools via binstall (prebuilt binaries, much faster & smaller) && cargo install cargo-binstall \ && cargo binstall --no-confirm \ cargo-watch cargo-outdated cargo-make \ jj-cli aichat \ && cargo install cargo-edit \ && cargo install --git https://github.com/nilskch/jj-lsp.git \ # Clean build cache (keep installed binaries, drop registry & build artifacts) && rm -rf $CARGO_HOME/registry $CARGO_HOME/git /tmp/cargo-* # Node tools RUN npm install -g typescript @types/node eslint prettier pyright typescript-language-server \ mcp-server-commands \ && npm cache clean --force # Ruby tools RUN gem install github-linguist \ && gem cleanup \ && rm -rf /var/cache/gem /root/.gem/specs # Python tools RUN pip install --no-cache-dir --break-system-packages ruff fastmcp ipython tasklin # Go tools ENV GOPATH=/usr/local/go ENV GOBIN=/usr/local/go/bin RUN go install golang.org/x/tools/gopls@latest \ && go install github.com/isaacphi/mcp-language-server@latest \ && go install github.com/github/github-mcp-server/cmd/github-mcp-server@latest \ && go install gitea.com/gitea/gitea-mcp@latest \ && go clean -cache -modcache # Shell completions RUN mkdir -p /etc/bash_completion.d \ && curl -fsSL https://raw.githubusercontent.com/sigoden/aichat/main/scripts/completions/aichat.bash \ > /etc/bash_completion.d/aichat \ && jj util completion bash > /etc/bash_completion.d/jj # Non-root user ARG USERNAME=devuser ARG USER_UID=1000 ARG USER_GID=1000 RUN groupadd --gid $USER_GID $USERNAME && \ useradd --uid $USER_UID --gid $USER_GID -m $USERNAME --shell /bin/bash && \ echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME && \ chmod 440 /etc/sudoers.d/$USERNAME COPY docker-entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh COPY bin/* /usr/local/bin/ RUN chmod +x /usr/local/bin/* RUN mkdir -p /home/${USERNAME}/.config \ && mkdir -p /home/${USERNAME}/.cache \ && chown -R ${USERNAME}:${USERNAME} /home/${USERNAME}/.config \ && chown -R ${USERNAME}:${USERNAME} /home/${USERNAME}/.cache COPY --chown=${USERNAME}:${USERNAME} opencode /home/${USERNAME}/.config/opencode USER $USERNAME WORKDIR /workspace ARG OCI_VERSION=latest ARG OCI_CREATED=unknown ARG OCI_REVISION=unknown LABEL org.opencontainers.image.title="PMOCrazyCoder" \ org.opencontainers.image.description="AI-powered dev container with Rust, Go, Python, Node, Jujutsu, Claude Code and opencode" \ org.opencontainers.image.url="https://niepce.petite-maison-orange.fr/public/pmocrazycoder" \ org.opencontainers.image.source="https://niepce.petite-maison-orange.fr/public/pmocrazycoder" \ org.opencontainers.image.version="${OCI_VERSION}" \ org.opencontainers.image.created="${OCI_CREATED}" \ org.opencontainers.image.revision="${OCI_REVISION}" \ org.opencontainers.image.licenses="CECILL-2.1" ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["/bin/bash"]