Add complete Docker setup and comprehensive documentation#1
Conversation
Summarizes project overview, repository structure, planned implementation files, architecture decisions, build commands, and key gotchas from the existing documentation in docs/. https://claude.ai/code/session_01RKiQewfP7TdA9SFkuwEVMY
Add all implementation files per the specs in docs/: - Dockerfile: multi-layer build from codercom/code-server with PHP 8.3, Node.js 22, Python 3, Composer, Drush, and VS Code extensions - docker-compose.yml: service config with volume mounts, SSH forwarding, and environment variable injection - docker-compose.override.yml.example: optional Docker socket access - .env.example: documented environment variable template - .dockerignore: lean build context - entrypoint.sh: git config, SSH validation, exec handoff - extensions.txt: curated extension list for PHP/Drupal development - config/settings.json: VS Code defaults (format on save, 2-space tabs) - Updated .gitignore, README.md (full setup docs), and CLAUDE.md https://claude.ai/code/session_01RKiQewfP7TdA9SFkuwEVMY
There was a problem hiding this comment.
Pull request overview
Adds a Docker-based dev environment for anydev centered on code-server, including container build/run configuration plus onboarding and workflow documentation.
Changes:
- Introduces a
codercom/code-server-based Docker image with PHP/Node/Python tooling, Drush, and build-time VS Code extension installation. - Adds Compose configuration, environment templates, and an entrypoint that configures git identity and checks SSH agent forwarding.
- Expands project documentation (setup, daily usage, troubleshooting) and adds a project guide.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
Dockerfile |
Builds the dev image (PHP/Node/Python/Composer/Drush) and installs extensions; sets entrypoint |
docker-compose.yml |
Defines the code-server service (build args, ports, env vars, volumes) |
docker-compose.override.yml.example |
Optional override template for mounting Docker socket (with warnings) |
entrypoint.sh |
Configures git identity from env and validates SSH agent socket, then execs CMD |
.env.example |
Template for required env vars (port/password/paths/UID/GID/git/SSH) |
extensions.txt |
Declarative list of VS Code extensions to preinstall in the image |
config/settings.json |
Default VS Code settings bind-mounted into the container |
.dockerignore |
Excludes secrets and non-build artifacts from Docker build context |
README.md |
Adds detailed prerequisites, setup, workflows, rebuild steps, and troubleshooting |
CLAUDE.md |
New project guide (architecture decisions, gotchas, conventions) |
.gitignore |
Ignores .env, local override compose file, and OS-specific files |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| --install-dir=/usr/local/bin --filename=composer | ||
|
|
||
| # Add NodeSource repository | ||
| RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - |
There was a problem hiding this comment.
Fetching and executing the NodeSource setup script via curl ... | bash - increases supply-chain risk. Prefer adding the repository via signed APT keyring + sources.list entry (similar to the Sury PHP repo) so the install path is auditable and avoids piping remote scripts into a shell.
| RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - | |
| RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /usr/share/keyrings/nodesource.gpg \ | |
| && echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" \ | |
| > /etc/apt/sources.list.d/nodesource.list |
docker-compose.yml
Outdated
| - SSH_AUTH_SOCK=${SSH_AUTH_SOCK} | ||
| volumes: | ||
| - ${HOST_CODE_DIR}:/home/coder/code | ||
| - code-server-extensions:/home/coder/.local/share/code-server/extensions | ||
| - ./config/settings.json:/home/coder/.local/share/code-server/User/settings.json | ||
| - ${SSH_AUTH_SOCK}:${SSH_AUTH_SOCK} |
There was a problem hiding this comment.
The SSH agent socket bind mount will make docker compose up fail if SSH_AUTH_SOCK is empty (the default in .env.example) because the resulting volume spec becomes :/. Consider moving this mount to an optional override/profile (similar to the Docker socket override) or otherwise making the socket mount conditional so the base setup works without SSH forwarding.
| - SSH_AUTH_SOCK=${SSH_AUTH_SOCK} | |
| volumes: | |
| - ${HOST_CODE_DIR}:/home/coder/code | |
| - code-server-extensions:/home/coder/.local/share/code-server/extensions | |
| - ./config/settings.json:/home/coder/.local/share/code-server/User/settings.json | |
| - ${SSH_AUTH_SOCK}:${SSH_AUTH_SOCK} | |
| - SSH_AUTH_SOCK=${SSH_AUTH_SOCK:-/tmp/ssh_auth_sock} | |
| volumes: | |
| - ${HOST_CODE_DIR}:/home/coder/code | |
| - code-server-extensions:/home/coder/.local/share/code-server/extensions | |
| - ./config/settings.json:/home/coder/.local/share/code-server/User/settings.json | |
| - ${SSH_AUTH_SOCK:-/dev/null}:/tmp/ssh_auth_sock |
| @@ -0,0 +1,93 @@ | |||
| FROM codercom/code-server:latest | |||
There was a problem hiding this comment.
Using codercom/code-server:latest makes builds non-reproducible and can introduce breaking changes unexpectedly. Pin the base image to a specific version/tag (or digest) and update intentionally.
| FROM codercom/code-server:latest | |
| FROM codercom/code-server:4.91.1 |
|
|
||
| WORKDIR /home/coder/code | ||
|
|
||
| ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] |
There was a problem hiding this comment.
This Dockerfile sets a new ENTRYPOINT but does not set an explicit CMD, so runtime behavior depends entirely on whatever CMD the upstream codercom/code-server image happens to define. To make the image self-contained (and resilient to upstream changes), set an explicit CMD for starting code-server (or have the entrypoint invoke code-server directly and treat inherited CMD as args).
| ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] | |
| ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] | |
| CMD ["code-server"] |
| RUN curl -fsSL https://getcomposer.org/installer | php -- \ | ||
| --install-dir=/usr/local/bin --filename=composer |
There was a problem hiding this comment.
This RUN command downloads and executes the Composer installer directly from https://getcomposer.org/installer without any checksum or signature verification, which means a compromise of the Composer download endpoint or a TLS MITM could execute arbitrary code as root during image build. An attacker controlling this script can modify your image, inject backdoors, or exfiltrate secrets available in the build environment. To mitigate, pin a specific installer version and verify its published checksum or signature before execution, or install Composer from a distribution package manager that provides integrity verification.
| RUN curl -fsSL https://github.com/drush-ops/drush-launcher/releases/latest/download/drush.phar \ | ||
| -o /usr/local/bin/drush \ | ||
| && chmod +x /usr/local/bin/drush |
There was a problem hiding this comment.
This RUN step downloads drush.phar from https://github.com/drush-ops/drush-launcher/releases/latest/download/drush.phar and makes it executable without pinning a specific release or verifying its integrity, so a compromised GitHub account, release artifact, or TLS MITM could replace it with arbitrary code. Because drush runs inside the container with your user privileges (and access to your code and forwarded SSH agent), a malicious binary here would enable full compromise of the development environment. To reduce this risk, pin to a specific release URL and verify a known checksum or signature before installing the PHAR, or use a package source that provides built-in integrity verification.
- Configure npm global prefix at ~/.npm-global so coder user can npm install -g without root - Install Claude Code globally in the image - Add named volume for ~/.npm to persist npm cache across restarts - Pass ANTHROPIC_API_KEY through to the container via .env https://claude.ai/code/session_01RKiQewfP7TdA9SFkuwEVMY
Claude Max uses browser-based OAuth, not an API key. Replace the ANTHROPIC_API_KEY env var with bind-mounts of ~/.claude/ and ~/.claude.json from the host, so the container picks up credentials from a prior `claude` login on the host machine. - Bind-mount ~/.claude (config/state) and ~/.claude.json (OAuth token) - Pre-create both in Dockerfile to prevent directory-for-file issues - Update .env.example with new variables and setup instructions - Remove ANTHROPIC_API_KEY passthrough https://claude.ai/code/session_01RKiQewfP7TdA9SFkuwEVMY
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Summary
This PR adds the complete Docker-based development environment implementation for anydev, including the Dockerfile, docker-compose configuration, entrypoint script, and comprehensive setup documentation.
Key Changes
codercom/code-serverwith PHP 8.3, Node.js 22 LTS, Python 3, Composer, Drush Launcher, and declarative VS Code extension management.env,docker-compose.override.yml, and OS-specific filesNotable Implementation Details
coderuser to match host UID/GID via build args, preventing file permission issuesextensions.txt+ named volume for session-persistent additionsconfig/settings.jsonbind-mounted so VS Code changes persist to the repositorycoderuser except system package installationhttps://claude.ai/code/session_01RKiQewfP7TdA9SFkuwEVMY