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,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