mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-15 18:21:09 +00:00
52 lines
2.8 KiB
Docker
52 lines
2.8 KiB
Docker
# Base image pinned by digest for reproducible builds.
|
|
# To refresh: docker pull eceasy/cli-proxy-api:latest && docker inspect --format='{{index .RepoDigests 0}}' eceasy/cli-proxy-api:latest
|
|
# Refresh cadence: quarterly OR on security advisory from upstream.
|
|
# TODO: pin apk packages once apk-digest pinning workflow exists in CI (apk add nodejs npm are currently unpinned;
|
|
# alpine package versions can be pinned but require per-package version discovery and maintenance).
|
|
FROM eceasy/cli-proxy-api:latest@sha256:4fa722b9ff83adfbe6e350d433b7dcb754756aa63df95a7a6349767dc13b2cb7
|
|
|
|
ARG CCS_NPM_VERSION=latest
|
|
|
|
# CCS integrated image: CCS CLI + CLIProxy + supervisord.
|
|
# Design choice (issue #1251 final scope): single-image strategy. The originally-
|
|
# proposed `:full` variant bundling claude-code/gemini-cli/grok-cli/opencode was
|
|
# DROPPED on maintainer review. Rationale: smaller surface area, fewer supply-
|
|
# chain dependencies, simpler tag taxonomy. Users needing AI CLIs run them in
|
|
# sibling containers attached to ccs-net — the public DNS contract guarantees
|
|
# http://ccs:8317 reachability. See docker/README.md#connect-your-app-to-
|
|
# cliproxy. Historical record: CHANGELOG.md "### Removed" entry.
|
|
|
|
RUN apk add --no-cache \
|
|
curl \
|
|
jq \
|
|
nodejs \
|
|
npm \
|
|
supervisor
|
|
|
|
# Install CCS CLI.
|
|
# Tradeoff: `npm install -g` does not use a lockfile — the package is already
|
|
# version-pinned via CCS_NPM_VERSION (e.g. "7.80.0"), so transitive drift is
|
|
# bounded to patch-level updates of CCS's own production dependencies between
|
|
# publish time and image build time. This is intentional: pinning an exact
|
|
# lockfile in a Docker global-install layer is fragile (lockfile format ties to
|
|
# npm/Node version in the base image). The --mount=type=cache layer ensures the
|
|
# resolved dependency tree is stable within a single build host's cache.
|
|
# Regression test: tests/docker/image-size.sh asserts the image stays within
|
|
# the size budget, which catches unexpected dep bloat.
|
|
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
|
|
|
|
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
|
|
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
|
CMD node -e "const http=require('http');const probe=(url)=>new Promise((resolve)=>{const req=http.get(url,(res)=>{res.resume();resolve(res.statusCode<400);});req.on('error',()=>resolve(false));req.setTimeout(4500,()=>{req.destroy();resolve(false);});});Promise.all([probe('http://127.0.0.1:3000/'),probe('http://127.0.0.1:8317/')]).then((results)=>process.exit(results.every(Boolean)?0:1));"
|
|
|
|
ENTRYPOINT ["/entrypoint-integrated.sh"]
|