feat: 重构 Docker 配置结构,添加 compute 模块及新增文档

- 将 Dockerfile 和 docker-compose.yml 迁移至 docker/ 目录下统一管理
- 新增 compute 计算模块(API 入口、依赖配置)
- 新增 docker/app 和 docker/compute 部署配置
- 新增 demo-development-plan.md 演示开发计划文档
- 更新后端 API 设计、部署计划、架构需求等文档
- 更新 postgres 数据库 schema

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
wuyongtao
2026-07-20 14:59:31 +08:00
parent ba4059fe3b
commit 2c1e08a271
20 changed files with 1517 additions and 71 deletions

View File

@@ -1147,6 +1147,116 @@ CREATE INDEX IF NOT EXISTS idx_gpu_allocations_scope ON gpu_allocations(tenant_i
CREATE UNIQUE INDEX IF NOT EXISTS uq_gpu_allocations_active_gpu
ON gpu_allocations(gpu_device_id) WHERE released_at IS NULL;
-- Multi compute-node scheduling and local-cache metadata.
-- Each GPU server is modeled as one compute node. Nodes do not call each other;
-- the application platform schedules jobs and syncs resources through each node's File Gateway.
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS file_gateway_url text;
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS enabled boolean NOT NULL DEFAULT true;
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS scheduler_status varchar(40) NOT NULL DEFAULT 'online';
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS scheduler_weight integer NOT NULL DEFAULT 100 CHECK (scheduler_weight >= 0);
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS tags text[] NOT NULL DEFAULT '{}';
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS service_token_encrypted text;
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS data_root text NOT NULL DEFAULT '/data/yg-ft';
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS model_root text NOT NULL DEFAULT '/data/yg-ft/models';
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS log_root text NOT NULL DEFAULT '/opt/yg-ft/logs/compute';
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS max_parallel_jobs integer NOT NULL DEFAULT 1 CHECK (max_parallel_jobs >= 0);
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS current_running_jobs integer NOT NULL DEFAULT 0 CHECK (current_running_jobs >= 0);
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS last_health_check_at timestamptz;
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS health_detail jsonb NOT NULL DEFAULT '{}'::jsonb;
ALTER TABLE compute_nodes ADD COLUMN IF NOT EXISTS drain_reason text;
CREATE INDEX IF NOT EXISTS idx_compute_nodes_scheduler
ON compute_nodes(enabled, scheduler_status, scheduler_weight DESC, last_health_check_at DESC);
CREATE INDEX IF NOT EXISTS idx_compute_nodes_tags_gin
ON compute_nodes USING gin(tags);
ALTER TABLE compute_jobs ADD COLUMN IF NOT EXISTS scheduler_mode varchar(40) NOT NULL DEFAULT 'auto';
ALTER TABLE compute_jobs ADD COLUMN IF NOT EXISTS requested_node_id uuid REFERENCES compute_nodes(id) ON DELETE SET NULL;
ALTER TABLE compute_jobs ADD COLUMN IF NOT EXISTS assigned_at timestamptz;
ALTER TABLE compute_jobs ADD COLUMN IF NOT EXISTS scheduler_reason text;
CREATE INDEX IF NOT EXISTS idx_compute_jobs_requested_node
ON compute_jobs(requested_node_id, status, created_at DESC);
CREATE TABLE IF NOT EXISTS compute_node_engines (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
compute_node_id uuid NOT NULL REFERENCES compute_nodes(id) ON DELETE CASCADE,
engine_id uuid REFERENCES training_engines(id) ON DELETE SET NULL,
engine_code varchar(80) NOT NULL,
engine_version varchar(80),
home_path text,
status varchar(40) NOT NULL DEFAULT 'available',
capability jsonb NOT NULL DEFAULT '{}'::jsonb,
last_health_check_at timestamptz,
health_detail jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (compute_node_id, engine_code)
);
SELECT touch_updated_at('compute_node_engines');
CREATE INDEX IF NOT EXISTS idx_compute_node_engines_node_status
ON compute_node_engines(compute_node_id, status, engine_code);
CREATE TABLE IF NOT EXISTS resource_replicas (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id uuid REFERENCES tenants(id) ON DELETE SET NULL,
project_id uuid REFERENCES projects(id) ON DELETE SET NULL,
resource_type varchar(80) NOT NULL,
resource_id uuid NOT NULL,
storage_object_id uuid REFERENCES storage_objects(id) ON DELETE SET NULL,
compute_node_id uuid NOT NULL REFERENCES compute_nodes(id) ON DELETE CASCADE,
local_path text NOT NULL,
status varchar(40) NOT NULL DEFAULT 'available',
sync_status varchar(40) NOT NULL DEFAULT 'synced',
checksum_sha256 char(64),
byte_size bigint NOT NULL DEFAULT 0 CHECK (byte_size >= 0),
version varchar(120),
pinned boolean NOT NULL DEFAULT false,
last_verified_at timestamptz,
expires_at timestamptz,
failure_reason text,
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (resource_type, resource_id, compute_node_id)
);
SELECT touch_updated_at('resource_replicas');
CREATE INDEX IF NOT EXISTS idx_resource_replicas_resource
ON resource_replicas(resource_type, resource_id, status);
CREATE INDEX IF NOT EXISTS idx_resource_replicas_node_status
ON resource_replicas(compute_node_id, status, sync_status, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_resource_replicas_scope
ON resource_replicas(tenant_id, project_id, resource_type, updated_at DESC);
CREATE TABLE IF NOT EXISTS resource_sync_jobs (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id uuid REFERENCES tenants(id) ON DELETE SET NULL,
project_id uuid REFERENCES projects(id) ON DELETE SET NULL,
target_compute_node_id uuid NOT NULL REFERENCES compute_nodes(id) ON DELETE CASCADE,
source_compute_node_id uuid REFERENCES compute_nodes(id) ON DELETE SET NULL,
resource_type varchar(80) NOT NULL,
resource_id uuid NOT NULL,
storage_object_id uuid REFERENCES storage_objects(id) ON DELETE SET NULL,
status task_status NOT NULL DEFAULT 'pending',
transfer_mode varchar(40) NOT NULL DEFAULT 'app_proxy',
source_uri text,
target_path text NOT NULL,
byte_size bigint NOT NULL DEFAULT 0 CHECK (byte_size >= 0),
checksum_sha256 char(64),
progress numeric(5,2) NOT NULL DEFAULT 0 CHECK (progress >= 0 AND progress <= 100),
failure_reason text,
requested_by uuid REFERENCES users(id) ON DELETE SET NULL,
started_at timestamptz,
completed_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
SELECT touch_updated_at('resource_sync_jobs');
CREATE INDEX IF NOT EXISTS idx_resource_sync_jobs_status
ON resource_sync_jobs(status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_resource_sync_jobs_target
ON resource_sync_jobs(target_compute_node_id, status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_resource_sync_jobs_resource
ON resource_sync_jobs(resource_type, resource_id, status);
CREATE TABLE IF NOT EXISTS resource_acl (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id uuid REFERENCES tenants(id) ON DELETE CASCADE,