diff --git a/.env.dev-corp.example b/.env.dev-corp.example index 4595a00..f9aab3f 100644 --- a/.env.dev-corp.example +++ b/.env.dev-corp.example @@ -10,6 +10,7 @@ IOP_EDGE_NODE_PORT=19006 IOP_EDGE_METRICS_PORT=19102 IOP_WEB_PORT=13002 IOP_PROMETHEUS_PORT=19112 +IOP_PROMETHEUS_CONFIG=./configs/prometheus/prometheus.dev-corp.yml IOP_GRAFANA_BIND=127.0.0.1 IOP_GRAFANA_PORT=19122 IOP_GRAFANA_ADMIN_USER=admin diff --git a/agent-test/dev-corp/HANDOFF.md b/agent-test/dev-corp/HANDOFF.md deleted file mode 100644 index 41366ba..0000000 --- a/agent-test/dev-corp/HANDOFF.md +++ /dev/null @@ -1,114 +0,0 @@ -# dev-corp Control Plane Observability Handoff - -last_updated_at: 2026-07-13 - -## Target - -- Environment: dev-corp -- Scope: Control Plane compose group and observability ports -- First entry points: - - `agent-test/dev-corp/inventory.yaml` - - `agent-test/dev-corp/rules.md` - - `.env.dev-corp.example` - - `docker-compose.yml` -- Do not rely on `../.workspace-ops` on the dev-corp runner. The dev-corp setup environment is expected to have only the project checkout, so all required handoff and inventory details must be available inside this repo. - -## Current State - -- dev environment was deployed and verified in this session. -- dev-corp environment was not deployed in this session because the dev-corp runner was not reachable from the current workspace. -- dev-corp compose settings are documented only. In `agent-test/dev-corp/inventory.yaml`, `compose.setup_status` is `documented_only_current_session_not_deployed`. -- Existing dev-corp public Edge path is still the active user path: - - artifact/bootstrap: `iop.ai.kr:18085` - - OpenAI-compatible: `digitalplatform.iop.ai.kr:18086` - - native Edge TCP: `iop.ai.kr:18087` - - Edge metrics: `iop.ai.kr:19102` -- Do not expose PostgreSQL, Redis, Prometheus, Grafana, or Control Plane metrics to the public internet. Assume operator access through VPN or runner-local access. - -## Intended dev-corp Compose Profile - -- compose project: `iop-dev-corp-agent` -- compose network: `iop-dev-corp-agent-net` -- compose subnet: `10.89.2.0/24` -- env file: `.env.dev-corp.example` -- core services: - - `postgres` - - `redis` - - `control-plane` - - `web` - - `prometheus` - - `grafana` - -Host ports: - -- web: `13002` -- Control Plane HTTP: `18002` -- Client WS: `19004` -- CP-Edge wire: `19005` -- compose Edge-Node TCP: `19006` -- PostgreSQL: `15402` -- Redis: `16302` -- Edge metrics: `19102` -- Control Plane metrics: `19104` -- Prometheus: `19112` -- Grafana: `19122` - -## Public Port Policy - -Only open additional public ports if dev-corp Control Plane UI must be tested from an external browser: - -- `13002/tcp` -- `18002/tcp` -- `19004/tcp` - -Keep these internal/VPN-only: - -- `15402/tcp` -- `16302/tcp` -- `19104/tcp` -- `19112/tcp` -- `19122/tcp` - -`19005` and `19006` are not required for ordinary browser UI access. Open them only for explicit external Edge/Node connection validation. - -## Next Steps - -1. Restore access to the dev-corp runner (`fe@172.24.63.178`) or confirm the current replacement runner. -2. Sync `/Users/fe/agent-work/iop-dev-corp` to the intended ref. -3. Run `docker compose --env-file .env.dev-corp.example config` and confirm published ports match `agent-test/dev-corp/inventory.yaml`. -4. Check port occupancy before starting services. -5. Start the core group only: - - ```bash - docker compose --env-file .env.dev-corp.example up -d postgres redis control-plane web prometheus grafana - ``` - -6. Do not start compose `edge` unless the validation explicitly requires it. -7. Validate: - - `curl -fsS http://127.0.0.1:18002/healthz` - - `curl -fsS http://127.0.0.1:18002/readyz` - - WebSocket upgrade on `ws://:19004/client` if UI is public. - - Prometheus readiness on runner-local `127.0.0.1:19112`. - - Grafana health on runner-local `127.0.0.1:19122/api/health`. - -## Open Decision - -The generic Prometheus compose config scrapes `control-plane:9093` and compose `edge:9092`. If dev-corp keeps using the native public Edge instead of compose Edge, decide whether to add a dev-corp-specific Prometheus config that scrapes the native Edge metrics endpoint via a runner-reachable address. - -## Evidence From This Session - -- dev Control Plane/UI stack was deployed with `postgres`, `redis`, `control-plane`, `web`, `prometheus`, and `grafana`. -- dev external checks passed for: - - `http://toki-labs.com:13001` - - `http://toki-labs.com:18001/healthz` - - `ws://toki-labs.com:19001/client` -- dev Prometheus targets were `up` for: - - `control-plane:9093` - - `host.docker.internal:19101` - - `prometheus:9090` -- dev-corp public checks showed existing Edge paths open (`18085`, `18086`, `18087`, `19102`) and Control Plane UI path closed (`13002`, `18002`, `19004`) before any dev-corp compose deployment. - -## Notes - -- Do not record API keys, tokens, DB passwords, or private credentials in tracked docs. -- `source.remote_runner.setup_status` in `inventory.yaml` refers to the existing source/build/provider runner context. The compose-specific deployment status is tracked separately under `compose.setup_status`. diff --git a/agent-test/dev-corp/control-plane-smoke.md b/agent-test/dev-corp/control-plane-smoke.md index 4bdddd9..e20edd0 100644 --- a/agent-test/dev-corp/control-plane-smoke.md +++ b/agent-test/dev-corp/control-plane-smoke.md @@ -36,12 +36,13 @@ last_rule_updated_at: 2026-07-02 - docker: compose 검증은 mac-mini에서 `.env.dev-corp.example` 기준으로 수행한다. provider-pool native runtime 검증은 `build/dev-corp-runtime/bin/control-plane`과 env override를 사용할 수 있다. - external service: postgres host publish `15402`, redis host publish `16302` - model endpoint: -- operator notice: 기존 dev-corp Control Plane/UI/Edge 접속 포트는 유지하고 Control Plane metrics `19104`, Prometheus `19112`, Grafana `19122`는 관측용 정의로만 추가한다. 현재 세션에서는 dev-corp 실제 세팅을 수행하지 않는다. +- operator notice: 기존 dev-corp Control Plane/UI/Edge 접속 포트는 유지한다. 2026-07-13 기준 compose Control Plane/observability 그룹은 mac-mini runner에 배포되어 있고, Control Plane metrics `19104`, Prometheus `19112`, Grafana `19122`는 runner-local 관측 포트로 유지한다. public `13002`/`18002`/`19004`는 별도 외부 UI 테스트 요청 전까지 열지 않는다. - credential: DB/Redis credential 원문은 문서에 기록하지 않는다. ## 명령 -- setup: mac-mini 환경에서 `IOP_EDGE_NODE_TOKEN`을 안전하게 주입한 뒤 `docker compose --env-file .env.dev-corp.example up -d postgres redis control-plane web prometheus grafana` +- setup: mac-mini 환경에서 `docker compose --env-file .env.dev-corp.example up -d postgres redis control-plane prometheus grafana` +- setup-web: `web`은 Flutter/Dart SDK와 sibling path dependencies(`agent-shell`, `nexo`, `proto-socket`)가 준비된 runner에서만 `docker compose --env-file .env.dev-corp.example up -d web`으로 별도 기동한다. - setup-native: mac-mini `/Users/fe/agent-work/iop-dev-corp`에서 `IOP_LISTEN=0.0.0.0:18002 IOP_WIRE_LISTEN=0.0.0.0:19004 IOP_EDGE_WIRE_LISTEN=0.0.0.0:19005 build/dev-corp-runtime/bin/control-plane serve --config configs/control-plane.yaml` - lint: - unit: `go test ./apps/control-plane/...` @@ -70,10 +71,19 @@ last_rule_updated_at: 2026-07-02 - `/edges/dev-corp-edge/status`는 Edge-owned snapshot을 반환하며 3개 provider node의 `provider_snapshots`를 포함한다. 이 status는 provider capacity smoke의 `in_flight`/`queued` evidence 기준이다. - 2026-07-02 mac-mini runtime capacity smoke에서 `/v1/responses`와 `/v1/chat/completions` 모두 peak total `in_flight=13`, `queued=3`, 완료 후 provider별 `in_flight=0`, `queued=0` 회복을 확인했다. 이 기록은 historical evidence이며, current public Edge provider-pool 표준 smoke는 `/v1/chat/completions`에서 model-specific `ornith:35b` 9/6, `gemma4:26b` 9/6 동시 요청만 사용한다. +## 2026-07-13 compose Control Plane/observability 상태 + +- mac-mini runner에서 compose project `iop-dev-corp-agent`로 `postgres`, `redis`, `control-plane`, `prometheus`, `grafana`가 기동됐다. +- Control Plane은 host `18002/19004/19005`를 container `18000/19080/19081`로 publish하고, `/healthz`, `/readyz`, Client WebSocket upgrade가 통과했다. +- Prometheus는 `configs/prometheus/prometheus.dev-corp.yml`을 사용하며 `control-plane:9093`, `host.docker.internal:19102`, `prometheus:9090` target이 `up`이다. +- Grafana health는 runner-local `127.0.0.1:19122/api/health`에서 통과했다. +- `web` service는 runner Flutter가 Dart `3.10.0`이고 앱 요구 조건이 `^3.11.3`인 점, `agent-shell`/`nexo` sibling path dependency가 없는 점 때문에 별도 차단 상태다. +- 외부 public `13002`, `18002`, `19004`는 연결 거부 상태로 유지한다. + ## 판정 기준 - control-plane service가 dev-corp stack으로 기동되고 health endpoint가 성공 응답을 반환한다. -- Prometheus와 Grafana가 같은 dev-corp compose project에서 올라오며, Prometheus는 compose 내부 DNS로 `control-plane:9093`과 필요 시 `edge:9092`를 scrape한다. +- Prometheus와 Grafana가 같은 dev-corp compose project에서 올라오며, Prometheus는 dev-corp 설정에서 `control-plane:9093`과 native Edge metrics `host.docker.internal:19102`를 scrape한다. - wire endpoint는 Control Plane 브라우저/앱 경계로 유지되고 Node 직접 연결/스케줄링 경로로 확장되지 않는다. - dev-corp stack은 local/test/dev stack의 host publish 포트를 점유하지 않는다. diff --git a/agent-test/dev-corp/inventory.yaml b/agent-test/dev-corp/inventory.yaml index 870a421..ca2ddd1 100644 --- a/agent-test/dev-corp/inventory.yaml +++ b/agent-test/dev-corp/inventory.yaml @@ -21,7 +21,10 @@ compose: subnet: 10.89.2.0/24 env_file: .env.dev-corp.example runtime_root: /Users/fe/agent-work/iop-dev-corp - setup_status: documented_only_current_session_not_deployed + setup_status: deployed_control_plane_observability_web_blocked + deployed_at: "2026-07-13T15:32:00+09:00" + prometheus_config: ./configs/prometheus/prometheus.dev-corp.yml + deployment_note: Control Plane, PostgreSQL, Redis, Prometheus, and Grafana are running in the dev-corp compose project on the mac-mini runner. The compose web service is not started because the runner Flutter/Dart SDK is below the app SDK constraint and required sibling path dependencies are absent. services: - postgres - redis @@ -41,6 +44,36 @@ compose: control_plane_metrics: 19104 prometheus: 19112 grafana: 19122 + active_services: + - postgres + - redis + - control-plane + - prometheus + - grafana + blocked_services: + web: + status: not_started + reason: runner Flutter uses Dart 3.10.0 while apps/client requires ^3.11.3, and sibling path dependencies agent-shell/nexo are not present under /Users/fe/agent-work. + latest_verification: + observed_at: "2026-07-13T15:32:00+09:00" + control_plane_healthz: passed + control_plane_readyz: passed + client_ws_upgrade_runner: passed + edge_wire_hello: passed + edge_status_nodes: 0 + prometheus_ready: passed + prometheus_targets: + iop-control-plane: up + iop-edge-native: up + prometheus: up + grafana_health: passed + public_control_plane_ports: + 13002: closed + 18002: closed + 19004: closed + public_edge_openai_models: + - gemma4:26b + - ornith:35b edge: id: dev-corp-edge diff --git a/agent-test/dev-corp/rules.md b/agent-test/dev-corp/rules.md index b0f18f1..5e35cd2 100644 --- a/agent-test/dev-corp/rules.md +++ b/agent-test/dev-corp/rules.md @@ -35,7 +35,7 @@ last_rule_updated_at: 2026-07-13 - env file: compose stack을 만들면 `.env.dev-corp.example`로 분리한다. 파일 생성 전에는 native/provider-pool profile만 기준으로 삼는다. - compose identity: `COMPOSE_PROJECT_NAME=iop-dev-corp-agent`, `IOP_COMPOSE_NETWORK=iop-dev-corp-agent-net`, `IOP_COMPOSE_SUBNET=10.89.2.0/24`. - port: web/dev preview `13002`, Control Plane HTTP `18002`, Client WS `19004`, CP-Edge wire `19005`, compose Edge-Node TCP `19006`, native Edge-Node TCP 후보 `18087`, Edge admin 후보 `19094`, Control Plane metrics `19104`, Prometheus `19112`, Grafana `19122`. -- operator notice: 기존 dev-corp 사용자-facing 접속점(`13002`, `18002`, Edge OpenAI-compatible 후보 `18086`, native Edge 후보 `18087`)은 변경하지 않는다. 현재 세션에서는 dev-corp 원격 접근이 불가하므로 compose/port 문서 정의만 갱신하고 실제 세팅은 수행하지 않는다. +- operator notice: 기존 dev-corp 사용자-facing 접속점(`13002`, `18002`, Edge OpenAI-compatible 후보 `18086`, native Edge 후보 `18087`)은 변경하지 않는다. 2026-07-13 기준 mac-mini runner에는 compose Control Plane/observability 그룹이 배포되어 있으나 public `13002`/`18002`/`19004`는 외부에서 닫힌 상태로 유지한다. - optional field ports: artifact/bootstrap HTTP `18085`, Edge OpenAI-compatible HTTP `18086`, Edge metrics `19102`. - runtime: Go quick check는 local toolchain을 우선한다. Docker/Flutter/client/field/bootstrap/provider-pool evidence는 mac-mini와 내부 provider nodes를 사용한다. - package manager: Go modules / Makefile / Flutter pub @@ -70,7 +70,7 @@ dev-corp native/provider-pool profile은 compose Edge-Node TCP `19006`이 아니 - remote runner: source sync/build/provider SSH 조작은 `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` 기준으로 수행할 수 있다. - public Edge evidence: Edge runtime evidence와 OpenAI-compatible smoke는 public `iop.ai.kr` 경로로 판정한다. - compose dev-corp stack: `.env.dev-corp.example`, `COMPOSE_PROJECT_NAME=iop-dev-corp-agent`, `IOP_COMPOSE_NETWORK=iop-dev-corp-agent-net`, `IOP_COMPOSE_SUBNET=10.89.2.0/24`, Edge-Node TCP `19006`, Control Plane metrics `19104`, Prometheus `19112`, Grafana `19122`를 사용한다. -- compose observability: dev-corp Control Plane 관측 그룹 정의는 문서 기준으로만 유지한다. 접근 가능한 mac-mini runner에서 별도 요청이 있을 때 실제 compose 세팅/검증을 수행한다. +- compose observability: dev-corp Control Plane 관측 그룹은 mac-mini runner의 compose project `iop-dev-corp-agent` 기준으로 검증한다. Prometheus는 dev-corp 전용 설정 `configs/prometheus/prometheus.dev-corp.yml`로 compose Control Plane metrics와 native Edge metrics를 함께 scrape한다. - Edge direct dev-corp profile: artifact/bootstrap `18085`, OpenAI-compatible `18086`, metrics `19102`, admin `19094`를 사용한다. - dev-corp provider pool: 기본 public Edge-Node TCP `iop.ai.kr:18087`을 기준으로 한다. `/Users/fe/agent-work/iop-dev-corp/build/dev-corp-runtime/edge.yaml`은 mac-mini runner의 보조 산출물일 뿐 dev-corp Edge source of truth로 판정하지 않는다. retired reverse tunnel route는 Edge addr로 사용하지 않는다. 3-node/provider 세부는 `agent-test/dev-corp/edge-smoke.md`와 `agent-test/dev-corp/node-smoke.md`를 따른다. - current native Control Plane: 2026-07-02 기준 provider-pool runtime에서 `build/dev-corp-runtime/bin/control-plane`이 `18002/19004/19005`를 listen하고, Edge id `dev-corp-edge`가 `127.0.0.1:19005`로 연결된다. provider snapshot status 기준은 `http://127.0.0.1:18002/edges/dev-corp-edge/status`다. diff --git a/apps/control-plane/Dockerfile b/apps/control-plane/Dockerfile index 85b0571..1311511 100644 --- a/apps/control-plane/Dockerfile +++ b/apps/control-plane/Dockerfile @@ -3,7 +3,6 @@ FROM golang:1.24-alpine AS builder WORKDIR /workspace/iop -RUN apk add --no-cache git # docker-compose builds this Dockerfile with /config/workspace as context so # the local ../proto-socket/go replace in go.mod is available. @@ -12,7 +11,7 @@ COPY proto-socket/go /workspace/proto-socket/go RUN go mod download COPY iop/ ./ -RUN CGO_ENABLED=0 GOFLAGS=-trimpath go build -o /out/control-plane ./apps/control-plane/cmd/control-plane +RUN CGO_ENABLED=0 GOFLAGS="-trimpath -buildvcs=false" go build -o /out/control-plane ./apps/control-plane/cmd/control-plane FROM alpine:3.22 diff --git a/apps/control-plane/Dockerfile.runtime b/apps/control-plane/Dockerfile.runtime new file mode 100644 index 0000000..72121b1 --- /dev/null +++ b/apps/control-plane/Dockerfile.runtime @@ -0,0 +1,15 @@ +# syntax=docker/dockerfile:1 + +FROM alpine:3.22 + +RUN addgroup -S iop && adduser -S iop -G iop +WORKDIR /app + +COPY build/dev-corp-compose/control-plane /usr/local/bin/control-plane +COPY configs/control-plane.yaml /app/configs/control-plane.yaml + +EXPOSE 18000 19080 19081 + +USER iop +ENTRYPOINT ["control-plane"] +CMD ["serve", "--config", "/app/configs/control-plane.yaml"] diff --git a/configs/prometheus/prometheus.dev-corp.yml b/configs/prometheus/prometheus.dev-corp.yml new file mode 100644 index 0000000..8925a54 --- /dev/null +++ b/configs/prometheus/prometheus.dev-corp.yml @@ -0,0 +1,26 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: prometheus + static_configs: + - targets: + - prometheus:9090 + + - job_name: iop-control-plane + metrics_path: /metrics + static_configs: + - targets: + - control-plane:9093 + labels: + component: control-plane + + - job_name: iop-edge-native + metrics_path: /metrics + static_configs: + - targets: + - host.docker.internal:19102 + labels: + component: edge + runtime: native-dev-corp