mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 10:15:40 +00:00
feat(docker): add Docker/Compose setup for CCS dashboard
This commit is contained in:
1 parent
ca86772208
commit
a14c7f3f6b
6 files changed
+271
No files matched your search
@@ -0,0 +1,17 @@
|
|||||||
|
.git
|
||||||
|
.github
|
||||||
|
.husky
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
ui/node_modules
|
||||||
|
|
||||||
|
dist
|
||||||
|
ui/dist
|
||||||
|
ui/.vite
|
||||||
|
|
||||||
|
coverage
|
||||||
|
ui/coverage
|
||||||
|
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
@@ -53,6 +53,8 @@ ccs config
|
|||||||
# Opens http://localhost:3000
|
# Opens http://localhost:3000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Want to run the dashboard in Docker? See `docker/README.md`.
|
||||||
|
|
||||||
### 3. Configure Your Accounts
|
### 3. Configure Your Accounts
|
||||||
|
|
||||||
The dashboard provides visual management for all account types:
|
The dashboard provides visual management for all account types:
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
FROM node:20-bookworm-slim AS build
|
||||||
|
|
||||||
|
SHELL ["/bin/bash", "-lc"]
|
||||||
|
|
||||||
|
ENV BUN_INSTALL=/usr/local/bun
|
||||||
|
ENV PATH="$BUN_INSTALL/bin:$PATH"
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends curl ca-certificates unzip \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN curl -fsSL https://bun.sh/install | bash
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Dependency install layer (avoid running install scripts inside the image build)
|
||||||
|
COPY package.json bun.lock bunfig.toml ./
|
||||||
|
COPY ui/package.json ui/bun.lock ./ui/
|
||||||
|
|
||||||
|
RUN bun install --frozen-lockfile --ignore-scripts \
|
||||||
|
&& (cd ui && bun install --frozen-lockfile --ignore-scripts)
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN bun run build:all
|
||||||
|
|
||||||
|
|
||||||
|
FROM node:20-bookworm-slim AS runtime
|
||||||
|
|
||||||
|
SHELL ["/bin/bash", "-lc"]
|
||||||
|
|
||||||
|
ENV BUN_INSTALL=/usr/local/bun
|
||||||
|
ENV PATH="$BUN_INSTALL/bin:/home/node/.opencode/bin:$PATH"
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends curl ca-certificates unzip \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN curl -fsSL https://bun.sh/install | bash
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json bun.lock ./
|
||||||
|
RUN bun install --frozen-lockfile --production --ignore-scripts
|
||||||
|
|
||||||
|
COPY docker/entrypoint.sh /usr/local/bin/ccs-entrypoint
|
||||||
|
RUN chmod +x /usr/local/bin/ccs-entrypoint
|
||||||
|
|
||||||
|
COPY --from=build /app/dist ./dist
|
||||||
|
COPY --from=build /app/lib ./lib
|
||||||
|
COPY --from=build /app/config ./config
|
||||||
|
COPY --from=build /app/scripts ./scripts
|
||||||
|
COPY --from=build /app/README.md ./README.md
|
||||||
|
COPY --from=build /app/LICENSE ./LICENSE
|
||||||
|
|
||||||
|
RUN npm install -g @google/gemini-cli @vibe-kit/grok-cli @anthropic-ai/claude-code \
|
||||||
|
&& npm install -g @kaitranntt/ccs --force \
|
||||||
|
&& su -s /bin/bash node -c 'curl -fsSL https://opencode.ai/install | bash -s -- --no-modify-path' \
|
||||||
|
&& ln -sf /app/dist/ccs.js /usr/local/bin/ccs
|
||||||
|
|
||||||
|
ENV CCS_PORT=3000
|
||||||
|
EXPOSE 3000 8317
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/ccs-entrypoint"]
|
||||||
|
|
||||||
|
CMD ["bash", "-c", "node dist/ccs.js config --port ${CCS_PORT}"]
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
|
# CCS Dashboard - Docker
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Run the CCS Config Dashboard in Docker.
|
||||||
|
Persistent config, restart on reboot.
|
||||||
|
|
||||||
|
**[Back to README](../README.md)**
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Quick Start (Docker Run)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -f docker/Dockerfile -t ccs-dashboard:latest .
|
||||||
|
docker run -d \
|
||||||
|
--name ccs-dashboard \
|
||||||
|
--restart unless-stopped \
|
||||||
|
-p 3000:3000 \
|
||||||
|
-p 8317:8317 \
|
||||||
|
-e CCS_PORT=3000 \
|
||||||
|
-v ccs_home:/home/node/.ccs \
|
||||||
|
ccs-dashboard:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `http://localhost:3000` (Dashboard).
|
||||||
|
|
||||||
|
CCS also starts CLIProxy on `http://localhost:8317` (used by Dashboard features and OAuth providers).
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
Common CCS environment variables (from the docs):
|
||||||
|
|
||||||
|
- Docs: [Environment variables](https://docs.ccs.kaitran.ca/getting-started/configuration#environment-variables)
|
||||||
|
|
||||||
|
- `CCS_CONFIG`: override config file path
|
||||||
|
- `CCS_UNIFIED_CONFIG=1`: force unified YAML config loader
|
||||||
|
- `CCS_MIGRATE=1`: trigger config migration
|
||||||
|
- `CCS_SKIP_MIGRATION=1`: skip migrations
|
||||||
|
- `CCS_DEBUG=1`: enable verbose logs
|
||||||
|
- `NO_COLOR=1`: disable ANSI colors
|
||||||
|
- `CCS_SKIP_PREFLIGHT=1`: skip API key validation checks
|
||||||
|
- `CCS_WEBSEARCH_SKIP=1`: skip WebSearch hook integration
|
||||||
|
- Proxy: `CCS_PROXY_HOST`, `CCS_PROXY_PORT`, `CCS_PROXY_PROTOCOL`, `CCS_PROXY_AUTH_TOKEN`, `CCS_PROXY_TIMEOUT`, `CCS_PROXY_FALLBACK_ENABLED`, `CCS_ALLOW_SELF_SIGNED`
|
||||||
|
|
||||||
|
Example (passing env vars to the running container):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name ccs-dashboard \
|
||||||
|
--restart unless-stopped \
|
||||||
|
-p 3000:3000 \
|
||||||
|
-p 8317:8317 \
|
||||||
|
-e CCS_PORT=3000 \
|
||||||
|
-e CCS_DEBUG=1 \
|
||||||
|
-e NO_COLOR=1 \
|
||||||
|
-e CCS_PROXY_HOST="proxy.example.com" \
|
||||||
|
-e CCS_PROXY_PORT=443 \
|
||||||
|
-e CCS_PROXY_PROTOCOL="https" \
|
||||||
|
-v ccs_home:/home/node/.ccs \
|
||||||
|
ccs-dashboard:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Useful Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs -f ccs-dashboard
|
||||||
|
docker stop ccs-dashboard
|
||||||
|
docker start ccs-dashboard
|
||||||
|
docker rm -f ccs-dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Compose (Optional)
|
||||||
|
|
||||||
|
Using the included `docker/docker-compose.yml`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker/docker-compose.yml up --build -d
|
||||||
|
docker-compose -f docker/docker-compose.yml logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Stop:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker/docker-compose.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
## Persistence
|
||||||
|
|
||||||
|
- CCS stores data in `/home/node/.ccs` inside the container.
|
||||||
|
- The examples use a named volume (`ccs_home`) to persist that data.
|
||||||
|
- Compose also persists `/home/node/.claude` and `/home/node/.opencode` via named volumes.
|
||||||
|
|
||||||
|
## Examples: Claude + Gemini inside Docker
|
||||||
|
|
||||||
|
Open a shell inside the running container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it ccs-dashboard bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Claude (non-interactive / print mode):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it ccs-dashboard claude -p "Hello from Docker"
|
||||||
|
```
|
||||||
|
|
||||||
|
Gemini (one-shot prompt):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it ccs-dashboard gemini "Hello from Docker"
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need to configure credentials, do it according to each CLI's docs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it ccs-dashboard claude --help
|
||||||
|
docker exec -it ccs-dashboard gemini --help
|
||||||
|
```
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
services:
|
||||||
|
ccs-dashboard:
|
||||||
|
image: ccs-dashboard:latest
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: docker/Dockerfile
|
||||||
|
restart: unless-stopped
|
||||||
|
init: true
|
||||||
|
ports:
|
||||||
|
- "${CCS_DASHBOARD_PORT:-3000}:3000"
|
||||||
|
- "${CCS_CLIPROXY_PORT:-8317}:8317"
|
||||||
|
environment:
|
||||||
|
CCS_PORT: 3000
|
||||||
|
CCS_DEBUG: "${CCS_DEBUG:-}"
|
||||||
|
NO_COLOR: "${NO_COLOR:-}"
|
||||||
|
CCS_SKIP_PREFLIGHT: "${CCS_SKIP_PREFLIGHT:-}"
|
||||||
|
CCS_WEBSEARCH_SKIP: "${CCS_WEBSEARCH_SKIP:-}"
|
||||||
|
CCS_PROXY_HOST: "${CCS_PROXY_HOST:-}"
|
||||||
|
CCS_PROXY_PORT: "${CCS_PROXY_PORT:-}"
|
||||||
|
CCS_PROXY_PROTOCOL: "${CCS_PROXY_PROTOCOL:-}"
|
||||||
|
CCS_PROXY_AUTH_TOKEN: "${CCS_PROXY_AUTH_TOKEN:-}"
|
||||||
|
CCS_PROXY_TIMEOUT: "${CCS_PROXY_TIMEOUT:-}"
|
||||||
|
CCS_PROXY_FALLBACK_ENABLED: "${CCS_PROXY_FALLBACK_ENABLED:-}"
|
||||||
|
CCS_ALLOW_SELF_SIGNED: "${CCS_ALLOW_SELF_SIGNED:-}"
|
||||||
|
volumes:
|
||||||
|
- ccs_home:/home/node/.ccs
|
||||||
|
- claude_home:/home/node/.claude
|
||||||
|
- opencode_home:/home/node/.opencode
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -fsS --max-time 2 http://localhost:3000/ >/dev/null && curl -sS --max-time 2 http://127.0.0.1:8317/ >/dev/null"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 12
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
ccs_home:
|
||||||
|
claude_home:
|
||||||
|
opencode_home:
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ccs_home_dir="${CCS_HOME_DIR:-/home/node/.ccs}"
|
||||||
|
|
||||||
|
mkdir -p "$ccs_home_dir"
|
||||||
|
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
chown -R node:node "$ccs_home_dir" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ]; then
|
||||||
|
echo "[X] No command provided" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
cmd="$(printf '%q ' "$@")"
|
||||||
|
exec su -s /bin/bash node -c "exec ${cmd}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$@"
|
||||||
|
|
||||||
Reference in new issue
Block a user