diff --git a/.gitignore b/.gitignore index 50003bd..dfbe639 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,8 @@ analysis_results/ prometheus_data/ grafana_data/ loki_data/ +.docker-local/ # Temporary files tmp/ -temp/ \ No newline at end of file +temp/ diff --git a/Makefile b/Makefile index 9596b44..3ebe047 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ # Claude Code Observability Stack .PHONY: help up down logs restart clean validate-config +DOCKER_COMPOSE := ./scripts/docker-compose.sh help: ## Show this help message @echo "Claude Code Observability Stack" @@ -10,7 +11,7 @@ help: ## Show this help message up: ## Start the observability stack @echo "๐Ÿš€ Starting Claude Code observability stack..." - docker compose up -d + $(DOCKER_COMPOSE) up -d @echo "โœ… Stack started!" @echo "๐Ÿ“Š Grafana: http://localhost:3000 (admin/admin)" @echo "๐Ÿ” Prometheus: http://localhost:9090" @@ -19,29 +20,29 @@ up: ## Start the observability stack down: ## Stop the observability stack @echo "๐Ÿ›‘ Stopping Claude Code observability stack..." - docker compose down + $(DOCKER_COMPOSE) down @echo "โœ… Stack stopped!" restart: ## Restart the observability stack @echo "๐Ÿ”„ Restarting Claude Code observability stack..." - docker compose restart + $(DOCKER_COMPOSE) restart @echo "โœ… Stack restarted!" logs: ## Show logs from all services - docker compose logs -f + $(DOCKER_COMPOSE) logs -f logs-collector: ## Show OpenTelemetry collector logs - docker compose logs -f otel-collector + $(DOCKER_COMPOSE) logs -f otel-collector logs-prometheus: ## Show Prometheus logs - docker compose logs -f prometheus + $(DOCKER_COMPOSE) logs -f prometheus logs-grafana: ## Show Grafana logs - docker compose logs -f grafana + $(DOCKER_COMPOSE) logs -f grafana clean: ## Clean up containers and volumes @echo "๐Ÿงน Cleaning up..." - docker compose down -v + $(DOCKER_COMPOSE) down -v docker system prune -f @echo "โœ… Cleanup complete!" @@ -52,7 +53,7 @@ clean: ## Clean up containers and volumes validate-config: ## Validate all configuration files @echo "โœ… Validating configurations..." @echo "๐Ÿ“‹ Checking docker compose.yml..." - docker compose config > /dev/null && echo "โœ… docker compose.yml is valid" + @$(DOCKER_COMPOSE) config > /dev/null && echo "โœ… docker compose.yml is valid" @echo "๐Ÿ“‹ Checking collector-config.yaml..." @if command -v otelcol-contrib >/dev/null 2>&1; then \ otelcol-contrib --config-validate --config=collector-config.yaml; \ @@ -64,7 +65,7 @@ validate-config: ## Validate all configuration files status: ## Show stack status @echo "๐Ÿ“Š Claude Code Observability Stack Status" @echo "===========================================" - @docker compose ps + @$(DOCKER_COMPOSE) ps @echo "" @echo "๐ŸŒ Service URLs:" @echo " Grafana: http://localhost:3000" @@ -94,4 +95,4 @@ setup-claude: ## Display Claude Code telemetry setup instructions demo-metrics: ## Generate demo metrics for testing @echo "๐ŸŽฏ This would generate demo metrics if Claude Code was running" @echo "๐Ÿ’ก To see real metrics, ensure Claude Code is configured with telemetry enabled" - @echo "๐Ÿ“– Run 'make setup-claude' for setup instructions" \ No newline at end of file + @echo "๐Ÿ“– Run 'make setup-claude' for setup instructions" diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..8a532b3 --- /dev/null +++ b/changelog.md @@ -0,0 +1,21 @@ +# Changelog + +## 2026-02-24 + +### Added +- `start.sh` script to: + - check Docker CLI availability + - show an English message if Docker Desktop is not running + - run `make up` + - export Claude Code telemetry variables + - launch `claude` +- `scripts/docker-compose.sh` wrapper that detects missing `docker-credential-desktop` and uses a local fallback `DOCKER_CONFIG`. + +### Changed +- `Makefile` now routes Docker Compose commands through `./scripts/docker-compose.sh` via `DOCKER_COMPOSE := ./scripts/docker-compose.sh`. +- `.gitignore` now ignores `.docker-local/` to avoid committing local Docker fallback config. + +### Notes +- Root issue fixed: `docker compose` failed with: + `error getting credentials - err: exec: "docker-credential-desktop": executable file not found in $PATH`. +- Current remaining startup risk is transient network/image pull errors (e.g. Docker Hub `504 Gateway Time-out`), unrelated to credential helper configuration. diff --git a/scripts/docker-compose.sh b/scripts/docker-compose.sh new file mode 100755 index 0000000..8bf3f11 --- /dev/null +++ b/scripts/docker-compose.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env sh +set -eu + +SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" +REPO_ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)" + +if command -v docker-credential-desktop >/dev/null 2>&1; then + exec docker compose "$@" +fi + +DOCKER_CONFIG_DIR="${DOCKER_CONFIG:-$HOME/.docker}" +DOCKER_CONFIG_FILE="$DOCKER_CONFIG_DIR/config.json" + +if [ -f "$DOCKER_CONFIG_FILE" ] && grep -Eq '"credsStore"[[:space:]]*:[[:space:]]*"desktop"' "$DOCKER_CONFIG_FILE"; then + FALLBACK_DOCKER_CONFIG="${CLAUDE_OTEL_DOCKER_CONFIG:-$REPO_ROOT/.docker-local}" + mkdir -p "$FALLBACK_DOCKER_CONFIG" + + # Keep user's Docker context/plugin setup, but remove the desktop creds helper. + sed '/"credsStore"[[:space:]]*:/d' "$DOCKER_CONFIG_FILE" > "$FALLBACK_DOCKER_CONFIG/config.json" + + for shared_dir in cli-plugins contexts; do + source_path="$DOCKER_CONFIG_DIR/$shared_dir" + target_path="$FALLBACK_DOCKER_CONFIG/$shared_dir" + if [ -e "$source_path" ] && [ ! -e "$target_path" ]; then + ln -s "$source_path" "$target_path" + fi + done + + if [ ! -f "$FALLBACK_DOCKER_CONFIG/config.json" ]; then + printf '{\n "auths": {}\n}\n' > "$FALLBACK_DOCKER_CONFIG/config.json" + fi + + printf '%s\n' "docker-credential-desktop not found. Using fallback DOCKER_CONFIG=$FALLBACK_DOCKER_CONFIG" >&2 + exec env DOCKER_CONFIG="$FALLBACK_DOCKER_CONFIG" docker compose "$@" +fi + +exec docker compose "$@" diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..fe20ba7 --- /dev/null +++ b/start.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$REPO_ROOT" + +if ! command -v docker >/dev/null 2>&1; then + echo "Docker is not installed. Please install Docker Desktop first." + exit 1 +fi + +if ! docker info >/dev/null 2>&1; then + echo "Docker Desktop is not running. Please start Docker Desktop, wait until it is fully started, then run ./start.sh again." + exit 1 +fi + +echo "Starting Claude Code observability stack..." +make up + +echo "Configuring telemetry environment variables..." +export CLAUDE_CODE_ENABLE_TELEMETRY=1 +export OTEL_METRICS_EXPORTER=otlp +export OTEL_LOGS_EXPORTER=otlp +export OTEL_EXPORTER_OTLP_PROTOCOL=grpc +export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +export OTEL_METRIC_EXPORT_INTERVAL=10000 +export OTEL_LOGS_EXPORT_INTERVAL=5000 + +echo "Starting Claude Code..." +claude