Add docker-compose for running all components together
control-api was the only component deployable via a bare Dockerfile alone (no entrypoint/template, no default mountable config), and there was no compose file wiring the four services' network, healthcheck ordering, or DB volume together. Adds a base docker-compose.yml plus dev (override, auto-loaded) and prod overlays, split by Compose profiles matching the real deployment topology (control-plane/dashboard/prober/validator), a ready-to-copy mock config for control-api so `docker compose up` works out of the box, and the repo's first .gitignore for the local env/config copies developers create from the committed examples. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NeVbMVEiE7XQAkBd7HQgj6
This commit is contained in:
1 parent
200760f390
commit
cf5c7fa0e8
9 files changed
+354
No files matched your search
@@ -0,0 +1,7 @@
|
||||
# Docker Compose local/real environment and config files.
|
||||
# Copy from the committed *.example counterparts in deploy/docker/.
|
||||
/deploy/docker/.env
|
||||
/deploy/docker/.env.*
|
||||
!/deploy/docker/.env.example
|
||||
!/deploy/docker/.env.prod.example
|
||||
/deploy/docker/control-api/control-api.docker.yaml
|
||||
@@ -26,6 +26,7 @@ HTTP API control-api.
|
||||
| [docs/DASHBOARD.md](docs/DASHBOARD.md) | Браузерная админ-панель (`admin-dashboard`) — то же самое API, но графически |
|
||||
| [docs/DIAGRAMS.md](docs/DIAGRAMS.md) | Диаграммы потоков данных: control plane, поток проверки до целевого сервера, поток телеметрии |
|
||||
| [docs/LOCAL_E2E.md](docs/LOCAL_E2E.md) | Полностью офлайн-прогон всей системы одним скриптом — без реального облака и интернета |
|
||||
| [deploy/docker/RUN.txt](deploy/docker/RUN.txt) | Сборка и запуск каждого компонента в Docker: команды `docker build`/`docker run`, переменные окружения |
|
||||
|
||||
## Быстрый старт (60 секунд, без OpenStack)
|
||||
|
||||
@@ -55,3 +56,55 @@ scripts/run-local-e2e.sh
|
||||
```bash
|
||||
curl -s http://<control-api>:8080/api/v1/admin/status | python3 -m json.tool
|
||||
```
|
||||
|
||||
## Развёртывание в Docker
|
||||
|
||||
Все четыре компонента можно собрать и запустить как отдельные Docker-образы
|
||||
вместо systemd-юнитов — Dockerfile'ы лежат в `deploy/docker/<компонент>/`,
|
||||
полные команды сборки/запуска и список переменных окружения — в
|
||||
[deploy/docker/RUN.txt](deploy/docker/RUN.txt).
|
||||
|
||||
- `prober`, `validator-agent`, `admin-dashboard` — конфиг генерируется
|
||||
внутри контейнера из переменных окружения (`docker-entrypoint.sh` +
|
||||
`envsubst`), готовых образов для монтирования не требуется.
|
||||
- `control-api` — конфиг содержит списки (validators/sites/targets/
|
||||
ip_addresses) и имена env-переменных для OpenStack-креденшлов, поэтому
|
||||
монтируется файлом (`-v .../control-api.yaml:/etc/cloud-ip-validator/control-api.yaml:ro`),
|
||||
а база данных — отдельным volume для персистентности.
|
||||
|
||||
Пример для `prober`:
|
||||
|
||||
```bash
|
||||
docker build --platform linux/amd64 -t cloud-ip-validator-prober -f deploy/docker/prober/Dockerfile .
|
||||
docker run -d --platform linux/amd64 --cap-add NET_RAW --name prober \
|
||||
-e PROBER_SITE_ID=<site_id> \
|
||||
-e PROBER_CONTROL_API_URL=<http://control-api-host:port> \
|
||||
cloud-ip-validator-prober
|
||||
```
|
||||
|
||||
`site_id` должен быть заранее зарегистрирован на control-api
|
||||
(`PUT /api/v1/admin/config/sites/{index}`) — иначе контейнер завершится с
|
||||
ошибкой регистрации. Аналогичные команды для остальных трёх компонентов —
|
||||
в [deploy/docker/RUN.txt](deploy/docker/RUN.txt).
|
||||
|
||||
### Запуск всех компонентов через docker-compose
|
||||
|
||||
Для совместного запуска (сеть, healthcheck, volume для базы данных) есть
|
||||
`docker-compose.yml` в `deploy/docker/` — разбит на базовый файл и
|
||||
окружения: `docker-compose.override.yml` (dev, подхватывается автоматически)
|
||||
и `docker-compose.prod.yml` (прод). Набор запускаемых сервисов на каждом
|
||||
хосте задаётся через `COMPOSE_PROFILES` в `.env`-файле (`control-plane`,
|
||||
`dashboard`, `prober`, `validator`) — так один и тот же compose можно
|
||||
поднять целиком локально или по частям на разных хостах (управляющая
|
||||
машина / внешняя площадка с `prober` / ВМ-валидатор), как в реальной
|
||||
топологии.
|
||||
|
||||
```bash
|
||||
cd deploy/docker
|
||||
cp .env.example .env
|
||||
cp control-api/control-api.docker.example.yaml control-api/control-api.docker.yaml
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Для прода: `docker compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.prod up -d --build`
|
||||
(см. комментарии в `.env.prod.example`).
|
||||
@@ -0,0 +1,19 @@
|
||||
# Copy to .env and edit if needed — defaults below work out of the box
|
||||
# with control-api/control-api.docker.example.yaml (openstack.mode: mock,
|
||||
# no OpenStack credentials needed).
|
||||
#
|
||||
# cp .env.example .env
|
||||
# cp control-api/control-api.docker.example.yaml control-api/control-api.docker.yaml
|
||||
# docker compose up -d --build
|
||||
|
||||
COMPOSE_PROFILES=control-plane,dashboard,prober,validator
|
||||
|
||||
# --- prober (must match a site_id in the mounted control-api config) ---
|
||||
PROBER_SITE_ID=site-1
|
||||
|
||||
# --- validator-agent (must match a validator_id in the mounted control-api config) ---
|
||||
VALIDATOR_AGENT_VALIDATOR_ID=validator_01
|
||||
|
||||
# ADMIN_DASHBOARD_CONTROL_API_URL / PROBER_CONTROL_API_URL /
|
||||
# VALIDATOR_AGENT_CONTROL_API_URL default to http://control-api:8080 in
|
||||
# docker-compose.yml (same Docker network) — only set here to override.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Copy to .env.prod per host and fill in only what that host needs.
|
||||
#
|
||||
# docker compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.prod up -d --build
|
||||
#
|
||||
# COMPOSE_PROFILES controls which services THIS host runs — pick one:
|
||||
# control-plane host: control-plane,dashboard
|
||||
# external prober site: prober
|
||||
# OpenStack validator VM: validator
|
||||
# single all-in-one host: control-plane,dashboard,prober,validator
|
||||
COMPOSE_PROFILES=control-plane,dashboard
|
||||
|
||||
# --- control-api (only needed when this host runs the control-plane profile) ---
|
||||
# Real config with validators/sites/targets/ip_addresses — see
|
||||
# configs/control-api.example.yaml and docs/SETUP.md. Required.
|
||||
CONTROL_API_CONFIG_PATH=/etc/cloud-ip-validator/control-api.yaml
|
||||
|
||||
# OpenStack creds — only read when the mounted control-api.yaml has
|
||||
# openstack.mode: real. Leave blank in mock mode.
|
||||
OS_AUTH_URL=
|
||||
OS_PROJECT_ID=
|
||||
OS_REGION_NAME=
|
||||
OS_INTERFACE=
|
||||
OS_TOKEN=
|
||||
# auth_method: password instead of token:
|
||||
# OS_USERNAME=
|
||||
# OS_USER_DOMAIN_NAME=
|
||||
# OS_PASSWORD=
|
||||
|
||||
# --- prober (only needed on a prober-profile host) ---
|
||||
PROBER_SITE_ID=
|
||||
# Real, network-reachable control-api URL — NOT http://control-api:8080
|
||||
# unless this host also runs the control-plane profile in the same
|
||||
# compose invocation.
|
||||
PROBER_CONTROL_API_URL=https://control-api.internal.example.com
|
||||
|
||||
# --- validator-agent (only needed on a validator-profile host) ---
|
||||
VALIDATOR_AGENT_VALIDATOR_ID=
|
||||
VALIDATOR_AGENT_CONTROL_API_URL=https://control-api.internal.example.com
|
||||
|
||||
# --- admin-dashboard (only needed on a dashboard-profile host) ---
|
||||
ADMIN_DASHBOARD_CONTROL_API_URL=http://control-api:8080
|
||||
@@ -1,3 +1,17 @@
|
||||
Для совместного запуска всех компонентов теперь есть docker-compose:
|
||||
docker-compose.yml (база) + docker-compose.override.yml (dev, подхватывается
|
||||
автоматически) + docker-compose.prod.yml (прод). Быстрый старт:
|
||||
|
||||
cp .env.example .env
|
||||
cp control-api/control-api.docker.example.yaml control-api/control-api.docker.yaml
|
||||
docker compose up -d --build
|
||||
|
||||
Подробности — в README.md, раздел "Развёртывание в Docker". Команды ниже
|
||||
документируют то же самое на уровне отдельного docker build/docker run —
|
||||
пригодятся для точечной отладки одного компонента без compose.
|
||||
|
||||
===============================================================================
|
||||
|
||||
Сборка образа (из корня репозитория):
|
||||
|
||||
docker build --platform linux/amd64 -t cloud-ip-validator-prober -f deploy/docker/prober/Dockerfile .
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
# Ready-to-copy control-api config for `docker compose` dev use — mock
|
||||
# OpenStack mode (no credentials needed) with minimal seed data matching
|
||||
# deploy/docker/.env.example's PROBER_SITE_ID / VALIDATOR_AGENT_VALIDATOR_ID
|
||||
# defaults, so `docker compose up` works out of the box after:
|
||||
#
|
||||
# cp control-api.docker.example.yaml control-api.docker.yaml
|
||||
#
|
||||
# For a real deployment, start from configs/control-api.example.yaml
|
||||
# instead (full schema reference, openstack.mode: real).
|
||||
|
||||
server:
|
||||
listen_addr: ":8080"
|
||||
|
||||
database:
|
||||
path: "/var/lib/cloud-ip-validator/control-api.db"
|
||||
|
||||
openstack:
|
||||
mode: "mock"
|
||||
|
||||
orchestrator:
|
||||
poll_interval_seconds: 5
|
||||
self_check_timeout_seconds: 60
|
||||
max_self_check_retries: 3
|
||||
checking_window_seconds: 120
|
||||
max_retries: 3
|
||||
lease_ttl_seconds: 180
|
||||
heartbeat_timeout_seconds: 30
|
||||
fip_settle_seconds: 0
|
||||
|
||||
aggregation:
|
||||
missing_counts_as_fail: true
|
||||
|
||||
validators:
|
||||
- validator_id: "validator_01"
|
||||
os_port_id: "mock-port-1"
|
||||
|
||||
sites:
|
||||
- site_id: "site-1"
|
||||
index: 1
|
||||
|
||||
check_types:
|
||||
- name: "https"
|
||||
enabled: true
|
||||
targets: ["default-targets"]
|
||||
- name: "icmp"
|
||||
enabled: true
|
||||
targets: ["default-targets"]
|
||||
- name: "ssh"
|
||||
enabled: false
|
||||
targets: []
|
||||
|
||||
targets:
|
||||
default-targets:
|
||||
- "https://hub.docker.com"
|
||||
- "https://github.com"
|
||||
- "https://packages.ubuntu.com"
|
||||
|
||||
inbound_checks:
|
||||
ports: [22, 80, 443, 8080]
|
||||
icmp: true
|
||||
|
||||
ip_addresses:
|
||||
- "203.0.113.10"
|
||||
- "203.0.113.11"
|
||||
- "203.0.113.12"
|
||||
@@ -0,0 +1,26 @@
|
||||
# Dev overlay — auto-loaded by `docker compose up` alongside docker-compose.yml.
|
||||
# Not used in prod (docker-compose.prod.yml is loaded explicitly instead).
|
||||
|
||||
services:
|
||||
control-api:
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./control-api/control-api.docker.yaml:/etc/cloud-ip-validator/control-api.yaml:ro
|
||||
|
||||
admin-dashboard:
|
||||
ports:
|
||||
- "8090:8090"
|
||||
depends_on:
|
||||
control-api:
|
||||
condition: service_healthy
|
||||
|
||||
prober:
|
||||
depends_on:
|
||||
control-api:
|
||||
condition: service_healthy
|
||||
|
||||
validator-agent:
|
||||
depends_on:
|
||||
control-api:
|
||||
condition: service_healthy
|
||||
@@ -0,0 +1,35 @@
|
||||
# Prod overlay — load explicitly:
|
||||
# docker compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.prod up -d --build
|
||||
#
|
||||
# No ports: (prod is expected to sit behind a reverse proxy / firewalled
|
||||
# network) and no depends_on: — on a split deployment (control-api on one
|
||||
# host, prober/validator-agent on others) control-api's profile is not even
|
||||
# part of that host's compose invocation, and depends_on on an inactive
|
||||
# profile is a hard `docker compose config` error. restart: unless-stopped
|
||||
# is the substitute safety net for the startup-order race (see RUN.txt /
|
||||
# README): prober and validator-agent exit on a failed one-shot
|
||||
# registration, so they get restarted until control-api is reachable.
|
||||
|
||||
services:
|
||||
control-api:
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${CONTROL_API_CONFIG_PATH:-/etc/cloud-ip-validator/UNCONFIGURED-control-api.yaml}:/etc/cloud-ip-validator/control-api.yaml:ro
|
||||
environment:
|
||||
OS_AUTH_URL: "${OS_AUTH_URL:-}"
|
||||
OS_PROJECT_ID: "${OS_PROJECT_ID:-}"
|
||||
OS_REGION_NAME: "${OS_REGION_NAME:-}"
|
||||
OS_INTERFACE: "${OS_INTERFACE:-}"
|
||||
OS_TOKEN: "${OS_TOKEN:-}"
|
||||
OS_USERNAME: "${OS_USERNAME:-}"
|
||||
OS_USER_DOMAIN_NAME: "${OS_USER_DOMAIN_NAME:-}"
|
||||
OS_PASSWORD: "${OS_PASSWORD:-}"
|
||||
|
||||
admin-dashboard:
|
||||
restart: unless-stopped
|
||||
|
||||
prober:
|
||||
restart: unless-stopped
|
||||
|
||||
validator-agent:
|
||||
restart: unless-stopped
|
||||
@@ -0,0 +1,94 @@
|
||||
name: cloud-ip-validator
|
||||
|
||||
# Base service definitions shared by every environment. Combine with
|
||||
# docker-compose.override.yml (auto-loaded, dev) or docker-compose.prod.yml
|
||||
# (prod) — see deploy/docker/RUN.txt for the exact invocations.
|
||||
#
|
||||
# Which services actually start is controlled per host via COMPOSE_PROFILES
|
||||
# in the active .env file, matching the real deployment topology:
|
||||
# control-plane control-api (one management host)
|
||||
# dashboard admin-dashboard (optional, anywhere with network access
|
||||
# to control-api)
|
||||
# prober prober (one per external test site)
|
||||
# validator validator-agent (one per validator VM in the cloud)
|
||||
|
||||
networks:
|
||||
backend:
|
||||
name: cloud-ip-validator
|
||||
|
||||
volumes:
|
||||
control-api-db:
|
||||
# Same volume name deploy/docker/RUN.txt's manual `docker run -v
|
||||
# cloud-ip-validator-db:...` already uses, so a manual-Docker deployment
|
||||
# can adopt compose without losing existing data.
|
||||
name: cloud-ip-validator-db
|
||||
|
||||
services:
|
||||
control-api:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/control-api/Dockerfile
|
||||
image: cloud-ip-validator-control-api
|
||||
platform: linux/amd64
|
||||
profiles: ["control-plane"]
|
||||
networks: [backend]
|
||||
volumes:
|
||||
- control-api-db:/var/lib/cloud-ip-validator
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://127.0.0.1:8080/healthz"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 10
|
||||
start_period: 5s
|
||||
|
||||
admin-dashboard:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/admin-dashboard/Dockerfile
|
||||
image: cloud-ip-validator-admin-dashboard
|
||||
platform: linux/amd64
|
||||
profiles: ["dashboard"]
|
||||
networks: [backend]
|
||||
environment:
|
||||
ADMIN_DASHBOARD_CONTROL_API_URL: "${ADMIN_DASHBOARD_CONTROL_API_URL:-http://control-api:8080}"
|
||||
ADMIN_DASHBOARD_LISTEN_ADDR: "${ADMIN_DASHBOARD_LISTEN_ADDR:-:8090}"
|
||||
ADMIN_DASHBOARD_CONTROL_API_TIMEOUT_SECONDS: "${ADMIN_DASHBOARD_CONTROL_API_TIMEOUT_SECONDS:-10}"
|
||||
ADMIN_DASHBOARD_LAST_COMPLETED_COUNT: "${ADMIN_DASHBOARD_LAST_COMPLETED_COUNT:-20}"
|
||||
ADMIN_DASHBOARD_POLL_INTERVAL_SECONDS: "${ADMIN_DASHBOARD_POLL_INTERVAL_SECONDS:-5}"
|
||||
|
||||
prober:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/prober/Dockerfile
|
||||
image: cloud-ip-validator-prober
|
||||
platform: linux/amd64
|
||||
profiles: ["prober"]
|
||||
networks: [backend]
|
||||
cap_add: [NET_RAW]
|
||||
environment:
|
||||
PROBER_SITE_ID: "${PROBER_SITE_ID:-}"
|
||||
PROBER_CONTROL_API_URL: "${PROBER_CONTROL_API_URL:-http://control-api:8080}"
|
||||
PROBER_POLL_INTERVAL_SECONDS: "${PROBER_POLL_INTERVAL_SECONDS:-5}"
|
||||
PROBER_TCP_TIMEOUT_SECONDS: "${PROBER_TCP_TIMEOUT_SECONDS:-5}"
|
||||
PROBER_ICMP_TIMEOUT_SECONDS: "${PROBER_ICMP_TIMEOUT_SECONDS:-5}"
|
||||
PROBER_ICMP_COUNT: "${PROBER_ICMP_COUNT:-3}"
|
||||
|
||||
validator-agent:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/validator-agent/Dockerfile
|
||||
image: cloud-ip-validator-validator-agent
|
||||
platform: linux/amd64
|
||||
profiles: ["validator"]
|
||||
networks: [backend]
|
||||
cap_add: [NET_RAW]
|
||||
environment:
|
||||
VALIDATOR_AGENT_VALIDATOR_ID: "${VALIDATOR_AGENT_VALIDATOR_ID:-}"
|
||||
VALIDATOR_AGENT_CONTROL_API_URL: "${VALIDATOR_AGENT_CONTROL_API_URL:-http://control-api:8080}"
|
||||
VALIDATOR_AGENT_POLL_INTERVAL_SECONDS: "${VALIDATOR_AGENT_POLL_INTERVAL_SECONDS:-5}"
|
||||
VALIDATOR_AGENT_SELF_CHECK_TIMEOUT_SECONDS: "${VALIDATOR_AGENT_SELF_CHECK_TIMEOUT_SECONDS:-10}"
|
||||
VALIDATOR_AGENT_HTTPS_TIMEOUT_SECONDS: "${VALIDATOR_AGENT_HTTPS_TIMEOUT_SECONDS:-10}"
|
||||
VALIDATOR_AGENT_ICMP_TIMEOUT_SECONDS: "${VALIDATOR_AGENT_ICMP_TIMEOUT_SECONDS:-5}"
|
||||
VALIDATOR_AGENT_ICMP_COUNT: "${VALIDATOR_AGENT_ICMP_COUNT:-3}"
|
||||
VALIDATOR_AGENT_SSH_ENABLED: "${VALIDATOR_AGENT_SSH_ENABLED:-false}"
|
||||
VALIDATOR_AGENT_SSH_TIMEOUT_SECONDS: "${VALIDATOR_AGENT_SSH_TIMEOUT_SECONDS:-5}"
|
||||
Reference in new issue
Block a user