Files
ccs/docker/Dockerfile.integrated
T
Kai (Tam Nhu) TranandGitHub d558cd2e36 feat(docker): publish ccs:latest + ccs:full integrated images (P1 of #1251) (#1257)
* feat(docker): parameterize Dockerfile.integrated with ARG FLAVOR=minimal|full

Add FLAVOR build arg that gates the AI CLI install layer (claude-code,
gemini-cli, grok-cli, opencode) so one Dockerfile produces both the
minimal (< 350 MB) and full (< 600 MB) integrated images.

Use BuildKit cache mount for /root/.npm to speed up repeated builds.
Part of #1251 (P1 — publish integrated images).

* feat(docker): emit startup deprecation warning in legacy ccs-dashboard entrypoint

Prepend a [WARN] line to stderr on every container start so operators
running ghcr.io/kaitranntt/ccs-dashboard:latest are notified to migrate
to ghcr.io/kaitranntt/ccs:latest. Sunset window: 2 releases. See #1251.

* test(docker): add image-size.sh budget assertion + unit test suite

image-size.sh: asserts docker image inspect .Size against a byte budget.
  Usage: image-size.sh <image:tag> <max-bytes>
  Budgets: minimal=350 MB (367001600), full=600 MB (629145600)

image-size-logic.test.sh: 6 mock-docker unit tests covering pass/fail
boundaries, bad arg count, and non-integer input. All 6 pass locally.
Part of #1251 (P1).

* ci(docker): extend docker-release.yml to publish ccs:latest and ccs:full

- Add publish-integrated job with matrix flavor: [minimal, full]
  - minimal -> ghcr.io/kaitranntt/ccs:<ver> + :latest (when promoted)
  - full    -> ghcr.io/kaitranntt/ccs:full-<ver> + :full (when promoted)
  - Multi-arch: linux/amd64 + linux/arm64 via buildx
  - Scoped GHA cache per flavor to avoid cross-contamination

- Add promote_to_latest workflow_dispatch input (default false)
  - rc.1 soak: first publish only pushes immutable version tag
  - Mutable :latest/:full promoted only on release event OR explicit opt-in

- Add smoke-test job (post-publish) for each flavor
  - Pulls the just-published version tag
  - Asserts image size via tests/docker/image-size.sh
  - Boots container, waits for healthcheck, probes :3000 and :8317

- Keep publish-dashboard job unchanged (legacy 2-release sunset)
  - Updated labels to note deprecation status

All jobs run on self-hosted cliproxy runners. Part of #1251 (P1).

* docs(docker): document new image tags, add ccs-dashboard deprecation notices

docker/README.md:
- Add "Choosing an image" table (ccs:latest / ccs:full / ccs-dashboard deprecated)
- Update Quick Start section to use ccs:latest as primary example
- Add legacy image note with sunset timeline

CHANGELOG.md:
- Add Unreleased > ### Deprecated entry for ccs-dashboard:latest
  pointing to migration path and #1251

README.md:
- Add one-line deprecation banner near top routing users to ccs:latest

Part of #1251 (P1).
2026-05-16 12:33:42 -04:00

39 lines
1.1 KiB
Docker

FROM eceasy/cli-proxy-api:latest
ARG CCS_NPM_VERSION=latest
# FLAVOR=minimal installs CCS only; FLAVOR=full adds claude-code, gemini-cli, grok-cli, opencode
ARG FLAVOR=minimal
RUN apk add --no-cache \
bash \
curl \
jq \
nodejs \
npm \
supervisor
# Install CCS CLI (always present in both flavors)
RUN --mount=type=cache,target=/root/.npm \
npm install -g @kaitranntt/ccs@${CCS_NPM_VERSION} \
&& ln -sf /usr/local/lib/node_modules/@kaitranntt/ccs/dist/docker/docker-bootstrap.js /usr/local/bin/ccs-docker-bootstrap
# Install AI CLIs only in the full flavor (all 4 bundled as one layer)
RUN --mount=type=cache,target=/root/.npm \
if [ "$FLAVOR" = "full" ]; then \
npm install -g --ignore-scripts \
@anthropic-ai/claude-code \
@google/gemini-cli \
@vibe-kit/grok-cli \
&& curl -fsSL https://opencode.ai/install | sh -s -- --no-modify-path 2>/dev/null || true; \
fi
COPY supervisord.conf /etc/supervisord.conf
COPY entrypoint-integrated.sh /entrypoint-integrated.sh
RUN chmod +x /entrypoint-integrated.sh \
&& mkdir -p /var/log/ccs
EXPOSE 3000 8085 8317
ENTRYPOINT ["/entrypoint-integrated.sh"]