Skip to content

feat: add docker setup for root cms projects - #1373

Open
stevenle wants to merge 7 commits into
mainfrom
claude/root-cms-dockerfile-gcloud-1bt96i
Open

stevenle wants to merge 7 commits into
mainfrom
claude/root-cms-dockerfile-gcloud-1bt96i

Conversation

@stevenle

Copy link
Copy Markdown
Member

Adds a complete Docker-based development environment for Root.js CMS projects, enabling local development against real Firebase/Firestore backends without manual toolchain setup.

Changes

  • docker/Dockerfile — Ubuntu 24.04 base image with Node.js 24.16.0, pnpm 11.17.0, and Google Cloud CLI pre-installed. Runs as a non-root user (uid/gid 1000 by default) so mounted project files retain host ownership. Includes an entrypoint script that auto-installs dependencies and validates credentials.

  • docker/entrypoint.sh — Container startup script that:

    • Automatically installs project dependencies via pnpm when node_modules is missing (controlled by ROOT_DOCKER_INSTALL env var)
    • Validates Google Cloud credentials are available (either via ADC file or GOOGLE_APPLICATION_CREDENTIALS)
    • Allows setup commands (gcloud auth, interactive shells) to run without pre-existing credentials
  • docker/Dockerfile.claude — Child image that adds Claude Code CLI on top of the base image, enabling AI agent sessions (via Remote Control) to run against the project with the same Node/pnpm/gcloud environment.

  • docker/docker-compose.yml — Declarative compose configuration that:

    • Wires up volumes for gcloud credentials, pnpm store, and Claude config
    • Supports ROOT_PROJECT_DIR and ROOT_PROJECT_SUBDIR for flexible project mounting
    • Includes a claude service behind a profile so agent sessions don't start unexpectedly
    • Loads .env from the project automatically
  • docker/README.md — Comprehensive documentation covering:

    • Quick start workflow (build, create volumes, sign in, run)
    • Authentication options (gcloud volume, host config bind-mount, service account key, workload identity)
    • Running commands other than the dev server
    • Claude Code Remote Control setup and security considerations
    • Baking projects into deployable images
    • Troubleshooting guide
  • AGENTS.md — Updated to reference the new Docker setup in the project structure section.

Implementation Details

  • Credentials are persisted in named volumes (root-gcloud, root-ai-claude-config) so users sign in once and reuse credentials across container runs.
  • The base image is deliberately separate from the Claude image to keep the base suitable for deployable images without carrying the agent credential surface.
  • Build args (UID, GID, USERNAME) allow the container to match the host user's ownership, preventing permission issues on mounted files.
  • The entrypoint distinguishes between setup commands (that create credentials) and regular commands (that require credentials), avoiding false failures during initial auth.

https://claude.ai/code/session_01Q3fsygkHJZtnYPN64syuvy

claude added 3 commits August 15, 2026 11:47
Adds an Ubuntu 24.04 image with Node, pnpm (via corepack) and the Google
Cloud CLI for running a Root CMS project against a real Firestore project.
The project is mounted at /workspace rather than baked in, and gcloud
credentials live in $HOME/.config/gcloud so a named volume persists both
`gcloud auth login` and `gcloud auth application-default login` across runs.

Includes an entrypoint that installs dependencies on first start and warns
when ADC is missing, a compose file wiring up the volumes, and a README
covering first-time sign-in, service-account keys and baking a project in.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3fsygkHJZtnYPN64syuvy
Adds docker/Dockerfile.claude, a child image (FROM root-cms) that installs the
Claude Code CLI and defaults to `claude remote-control`, so a session running
against the mounted project can be driven from claude.ai or the Claude app.

Keeping it separate from the base image avoids shipping an agent CLI into
images built FROM root-cms for deployment, and keeps the claude.ai token and
the project's Google Cloud credentials on separate volumes so each can be
granted independently.

CLAUDE_CONFIG_DIR points at ~/.claude so the volume mounted there persists
.claude.json (OAuth account and workspace trust) along with the token. The CLI
installs into a user-owned npm prefix so its self-updater can write to it. The
compose service sits behind a `claude` profile so `up` doesn't start an agent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3fsygkHJZtnYPN64syuvy
Matches the image name to the `root` CLI command. The base image, its compose
service and the compose project are now `root`, and the Claude Code child image
is `root-ai-claude`. Example volume names follow (`root-gcloud`,
`root-pnpm-store`, `root-ai-claude-config`).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3fsygkHJZtnYPN64syuvy
@stevenle stevenle changed the title Add Docker setup for Root.js CMS projects feat: add docker setup for root cms projects Aug 15, 2026
stevenle and others added 4 commits August 15, 2026 10:07
Prepares the images for Claude Code Remote Control sessions that create
branches and worktrees:

- Install the GitHub CLI in the Claude image, which Claude reaches for to open
  pull requests and read CI results.
- Mirror GIT_AUTHOR_* to GIT_COMMITTER_* in the entrypoint and drop empty
  GIT_* values, since git rejects an empty ident more loudly than a missing
  one. Warn at startup when a repository has no identity available at all.
- Group-own $HOME and /workspace by gid 0 with the owner's permissions, so a
  pulled image still works via `--user "$(id -u):0"` when the host user isn't
  1000, and set safe.directory=* so git doesn't refuse the bind-mounted repo
  as dubiously owned.
- Give the compose claude service `--spawn worktree` and publish 4008-4013,
  because `root dev` scans upward from 4007 and a second concurrent session's
  dev server would otherwise be unreachable.

Pushing still has no credentials; the README says so explicitly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3fsygkHJZtnYPN64syuvy
The entrypoint now runs `gh auth setup-git` when it finds a credential, so
`git push`, `git fetch` and `gh pr create` work from the container. A
credential is either GH_TOKEN/GITHUB_TOKEN in the environment or a `gh auth
login` persisted in a volume at ~/.config/gh, which the compose claude service
now declares alongside the token passthrough.

Details worth noting:

- Some gh versions refuse `auth setup-git` when the only credential is an
  environment token, so the helper it would have written is set directly as a
  fallback.
- A token only authenticates https remotes, so an `insteadOf` rewrite is added
  for ssh remotes when a token is present — a checkout cloned over ssh would
  otherwise fail to push with no key in the container.
- Existing logins are detected by reading gh's hosts.yml rather than calling
  `gh auth status`, which would validate the token over the network on every
  container start.
- The config is written to the container's own ~/.gitconfig in the writable
  layer, so no token is persisted to a volume or to the host.

Empty GH_TOKEN/GITHUB_TOKEN/GH_HOST values are dropped, as with the GIT_*
identity variables.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3fsygkHJZtnYPN64syuvy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants