diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..fd2c42f47 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,29 @@ +ARG RUST_VERSION=1.88 +FROM rust:${RUST_VERSION}-slim-bookworm + +# Native DBus headers and pkg-config are required by libdbus-sys during +# `cargo build`. Keep these development dependencies in the Dev Container, +# rather than adding them to the production runtime image. +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + git \ + libdbus-1-dev \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* + +# The official Rust image keeps its toolchain here. Preserve it after switching +# from the image's root user to the non-root development user below. +ENV PATH=/usr/local/cargo/bin:${PATH} +RUN printf '%s\n' 'export PATH=/usr/local/cargo/bin:$PATH' \ + > /etc/profile.d/codewhale-rust.sh +RUN rustup component add rustfmt + +RUN groupadd --gid 1000 codewhale \ + && useradd --create-home --shell /bin/bash --uid 1000 --gid 1000 codewhale \ + && install -d -m 0700 -o codewhale -g codewhale /home/codewhale/.codewhale \ + && install -d -m 0755 -o codewhale -g codewhale /home/codewhale/.cargo \ + && install -d -m 0755 -o codewhale -g codewhale /home/codewhale/.cargo/target + +USER codewhale +WORKDIR /workspaces/CodeWhale diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b80a20cd9..8d59e2f0f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,7 +1,8 @@ { "name": "CodeWhale", - "dockerFile": "../Dockerfile", "build": { + "context": "..", + "dockerfile": "Dockerfile", "args": { "RUST_VERSION": "1.88" } @@ -20,15 +21,13 @@ } }, "remoteEnv": { - "DEEPSEEK_API_KEY": "${localEnv:DEEPSEEK_API_KEY}" + "DEEPSEEK_API_KEY": "${localEnv:DEEPSEEK_API_KEY}", + "CARGO_TARGET_DIR": "/home/codewhale/.cargo/target" }, "mounts": [ - "source=${localEnv:HOME}/.codewhale,target=/home/codewhale/.codewhale,type=bind,consistency=cached" + "source=codewhale-state,target=/home/codewhale/.codewhale,type=volume", + "source=codewhale-cargo-target,target=/home/codewhale/.cargo/target,type=volume" ], - "features": { - "ghcr.io/devcontainers/features/rust:1": {}, - "ghcr.io/devcontainers/features/git:1": {} - }, - "postCreateCommand": "cargo build", + "postCreateCommand": "cargo build --locked", "remoteUser": "codewhale" } diff --git a/docs/DOCKER.md b/docs/DOCKER.md index 5643c7d9d..8735b1c42 100644 --- a/docs/DOCKER.md +++ b/docs/DOCKER.md @@ -281,9 +281,16 @@ docker buildx build --platform linux/amd64,linux/arm64 -t codewhale . ## Devcontainer The repository includes a [`.devcontainer/devcontainer.json`](../.devcontainer/devcontainer.json) -configuration for VS Code / GitHub Codespaces. It pre-installs the Rust toolchain, -rust-analyzer, and the `codewhale` binary. Open the repo in a devcontainer to get a -ready-to-use development environment. +configuration for VS Code / GitHub Codespaces. It builds a dedicated development +image with the Rust toolchain, Git, `pkg-config`, and the DBus development headers +required by the workspace. The first open runs `cargo build --locked` and installs +rust-analyzer and the other editor extensions. + +The source checkout remains mounted from the host. CodeWhale state and Cargo build +artifacts use Docker named volumes instead, so the configuration works when VS Code +cannot provide a POSIX-style `HOME` variable (notably on Windows), and builds do not +write thousands of small files through a Windows bind mount. Rebuild the container +after changing the Dev Container configuration. ## Release status