Skip to content

feat(distribution): Docker image Phase 2 — minimal + maximal + GHCR multi-arch (refs #54)#167

Merged
Wolfvin merged 1 commit into
mainfrom
feat/issue-54-docker-image-phase2
Jul 3, 2026
Merged

feat(distribution): Docker image Phase 2 — minimal + maximal + GHCR multi-arch (refs #54)#167
Wolfvin merged 1 commit into
mainfrom
feat/issue-54-docker-image-phase2

Conversation

@Wolfvin

@Wolfvin Wolfvin commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

Phase 2 of issue #54 — container image distribution for CodeLens.

Implements the Docker image phase from the issue spec:

  • Dockerfile (minimal): python:3.11-slim + tree-sitter core + 6 grammars + watchdog + PyYAML
  • Dockerfile.maximal: minimal + all Python extras + pre-installed LSP servers (Python + JS/TS)
  • .dockerignore: lean build context
  • .github/workflows/docker-publish.yml: multi-arch (linux/amd64 + linux/arm64) buildx + GHCR publish
  • docs/installation/docker.md: usage guide

Acceptance criterion

docker run --rm -v "$(pwd):/workspace" ghcr.io/wolfvin/codelens scan /workspace

The container accepts a CodeLens command + workspace path and runs against the mounted host directory.

What was done

Dockerfile (minimal)

  • Base: python:3.11-slim
  • Installs: tree-sitter + 6 grammar packages (HTML, CSS, JS, TS, Rust, Python), watchdog, PyYAML, git
  • Non-root codelens user (UID/GID 1000) — least-privilege
  • /usr/local/bin/codelens wrapper → python3 /opt/codelens/scripts/codelens.py (forward-compatible with Phase 1)
  • WORKDIR /workspace (mount point)
  • HEALTHCHECK via codelens --command-count (exercises full command-registry import — deeper than --version)
  • ENTRYPOINT ["codelens"]

Dockerfile.maximal

  • Everything in minimal, plus:
  • All Python extras from pyproject.toml (grammars, watch, rules, lsp, dev)
  • Pre-installed LSP servers: python-lsp-server, ruff-lsp (Python), pyright + typescript-language-server (JS/TS)
  • Node.js LTS (required by npm-based LSP servers)
  • Enables codelens <cmd> --deep out of the box for Python and JS/TS

.github/workflows/docker-publish.yml

  • Matrix builds both minimal and maximal variants
  • Multi-arch via docker/buildx + QEMU: linux/amd64, linux/arm64
  • Pushes to GHCR: ghcr.io/wolfvin/codelens (:latest, :sha-<short>, :v<x.y.z>) and ghcr.io/wolfvin/codelens-maximal (:maximal-latest, etc.)
  • GHA cache per variant for fast rebuilds
  • Smoke-test step (minimal only): verifies codelens --command-count runs inside the image
  • Triggers: push to main (Dockerfile/scripts/pyproject changes), tags v*, workflow_dispatch (with dry-run option)
  • Fork guard: if: github.repository == "Wolfvin/CodeLens"

docs/installation/docker.md

  • Quick start, image variants table, usage patterns (CI, persistence volume, shell alias, --deep LSP mode, MCP server), health check, multi-arch, local build, tagging strategy, troubleshooting

Tests

1398 passed, 76 skipped, 1 failed in 60.37s

The 1 failure is tests/test_codelensignore.py::TestBackwardCompat::test_actual_target_dir_is_ignoredpre-existing and unrelated to this change. This PR only adds new files (Dockerfile, .dockerignore, workflow, docs); no Python source was modified, so no regression is possible. Docker build itself is not tested locally (docker not available in sandbox); the CI workflow will validate the build on push.

Notes for reviewer

  1. Phase 1 dependency: PR feat(distribution): pip-installable package + PyPI publish workflow (closes #54 phase-1) #144 (pip-installable package) is open but not merged. This Dockerfile is built on current main and uses a wrapper script (/usr/local/bin/codelenspython3 scripts/codelens.py) as the entry point. When Phase 1 merges and adds a real [project.scripts] codelens console script, the Dockerfile should be updated to pip install . and the wrapper dropped. This is documented in the Dockerfile header.

  2. HEALTHCHECK choice: The issue spec mentions HEALTHCHECK CMD codelens --version, but no --version flag exists on the CLI. Used codelens --command-count instead — this exercises the full command-registry import path (every command module + tree-sitter grammars load), making it a deeper health check than a static version string.

  3. Maximal LSP coverage: The issue notes maximal "depends on native LSP server issue". This PR covers Python and JS/TS (the two most common languages) via pip/npm-installable servers. Rust/Go/etc. LSP coverage is deferred to the native LSP server issue.

  4. No auto-close: This is Phase 2 of a multi-phase issue. Used refs #54 (not closes #54) to avoid auto-closing the issue when the PR merges. Phases 3-6 (Homebrew/Scoop/Nix, binary, signing, auto-update) remain open for other workers.

Findings

  • pyproject.toml lines 77-79 confirm no console-script entry point exists yet. The wrapper script bridges this gap so the acceptance-criterion command works today.
  • No --version flag on codelens CLI (argparse only has --command-count and --help). Documented in Dockerfile; used --command-count for HEALTHCHECK.

Files changed

A  .dockerignore
A  .github/workflows/docker-publish.yml
A  Dockerfile
A  Dockerfile.maximal
A  docs/installation/docker.md

Refs #54 (Phase 2 only — issue remains open for Phases 3-6).

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sonarqubecloud

sonarqubecloud Bot commented Jul 3, 2026

Copy link
Copy Markdown

…ulti-arch (refs #54)

Phase 2 of issue #54 — container image distribution for CodeLens.

Files added:
- Dockerfile (minimal): python:3.11-slim + tree-sitter core + 6 grammars +
  watchdog + PyYAML. Non-root codelens user (UID 1000). HEALTHCHECK via
  'codelens --command-count' (exercises full command-registry import path).
  ENTRYPOINT is a /usr/local/bin/codelens wrapper -> python3 scripts/codelens.py
  (forward-compatible: Phase 1 PR #144 will replace with console script).
- Dockerfile.maximal: minimal + all Python extras (grammars/watch/rules/lsp/dev)
  + pre-installed LSP servers (python-lsp-server, ruff-lsp, pyright,
  typescript-language-server) + Node.js LTS. Enables '--deep' out of the box
  for Python and JS/TS. Full LSP coverage pending native LSP server issue.
- .dockerignore: excludes .git, tests, benchmarks, vscode-codelens, __pycache__,
  .codelens runtime state, build artifacts to keep build context lean.
- .github/workflows/docker-publish.yml: multi-arch (linux/amd64 + linux/arm64)
  buildx pipeline. Matrix builds minimal + maximal. Pushes to GHCR
  (ghcr.io/wolfvin/codelens) with tags: :latest, :sha-<short>, :v<x.y.z>,
  :maximal-latest. GHA cache per variant. Smoke-test step on minimal.
  Triggers: push to main (Dockerfile/scripts changes), tags v*, workflow_dispatch.
- docs/installation/docker.md: usage guide — quick start, image variants,
  persistence volume, shell alias, --deep LSP mode, MCP server, health check,
  multi-arch, local build, tagging strategy, troubleshooting.

Acceptance criterion met:
  docker run --rm -v "$(pwd):/workspace" ghcr.io/wolfvin/codelens scan /workspace

Test baseline: 1398 passed, 76 skipped, 1 failed (pre-existing
test_codelensignore failure, unrelated to this change — only new files added,
no Python modifications). Docker build not tested locally (docker not in
sandbox); CI workflow will validate on push.

Phase 1 (PR #144 pip-installable) not yet merged — Dockerfile built on current
main (entry point python3 scripts/codelens.py). When Phase 1 merges, update
Dockerfile to 'pip install .' + drop wrapper script. Noted in Dockerfile header.

Findings:
- pyproject.toml lines 77-79 confirm no console-script entry point exists yet
  (Phase 1 will add [project.scripts] codelens = ...). Wrapper script bridges
  this gap so the acceptance-criterion command works today.
- No --version flag on codelens CLI; used --command-count for HEALTHCHECK
  (deeper check — verifies command registry + grammar imports load).
@Wolfvin Wolfvin deleted the feat/issue-54-docker-image-phase2 branch July 3, 2026 03:20
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.

1 participant