Docker: a Stacks section — edit a compose file, validate, deploy; fix the sideways scroll on phones
Stacks are found from container labels; the file is resolved on the host or through an orchestrator's mounts, and compose runs where the file makes sense (inside Dockhand here), so a redeploy is identical to how the stack was deployed. Save validates with compose and keeps a .hamlab-bak; Deploy / Update / Restart / Stop run as followed tasks. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
08fb9d6e38
commit
9c4f9dfa9f
@@ -103,6 +103,7 @@ export interface SmartAttr { id: number; name: string; value: number; worst: num
|
||||
export interface SmartInfo { device: string; available: boolean; supported: boolean; standby: boolean; passed: boolean | null; temp: number; power_on_hours: number; power_cycles: number; model?: string; serial?: string; firmware?: string; attrs: SmartAttr[]; nvme?: { critical_warning: number; percentage_used: number; available_spare: number; spare_threshold: number; media_errors: number; error_log_entries: number; data_read_bytes: number; data_written_bytes: number; unsafe_shutdowns: number }; mmc?: { life_a: number; life_b: number; pre_eol: number }; self_test?: string; self_test_remaining?: number; self_test_supported: boolean; self_test_note?: string; warnings: string[]; error?: string; fetched_at: number }
|
||||
export interface DockerContainer { id: string; name: string; image: string; state: string; status: string; health: string; ports: string; stack: string; service: string; created: string; mem: number }
|
||||
export interface DockerInfo { available: boolean; message?: string; tool?: string; containers: DockerContainer[]; images: Record<string, unknown>[]; volumes: Record<string, unknown>[]; networks: Record<string, unknown>[] }
|
||||
export interface Stack { name: string; containers: string[]; running: number; file: string; host_file: string; via: string; editable: boolean; note?: string; has_env: boolean }
|
||||
export interface AlertRule { id: string; name: string; sensor: string; op: string; value: number | boolean | string; for_sec: number; severity: 'info' | 'warn' | 'crit'; enabled: boolean; machines: string }
|
||||
export interface AlertChannel { type: 'ntfy' | 'webhook'; url: string }
|
||||
export interface AlertEvent { t: number; kind: 'firing' | 'resolved'; rule: string; rule_id: string; machine: string; sensor: string; value: unknown; severity: string }
|
||||
@@ -192,6 +193,10 @@ export const api = {
|
||||
dockerAction: (id: string, action: 'start' | 'stop' | 'restart') => req<void>('POST', `/api/docker/containers/${encodeURIComponent(id)}/${action}`),
|
||||
dockerLogs: (id: string, since = '') => req<{ lines: { t: string; m: string }[] }>('GET', `/api/docker/containers/${encodeURIComponent(id)}/logs${since ? `?since=${encodeURIComponent(since)}` : '?n=300'}`),
|
||||
dockerInspect: (id: string) => req<Record<string, unknown>>('GET', `/api/docker/containers/${encodeURIComponent(id)}/inspect`),
|
||||
stacks: () => req<{ stacks: Stack[] }>('GET', '/api/docker/stacks'),
|
||||
stackFile: (name: string) => req<{ stack: Stack; text: string }>('GET', `/api/docker/stacks/${encodeURIComponent(name)}`),
|
||||
saveStack: (name: string, text: string) => req<void>('PUT', `/api/docker/stacks/${encodeURIComponent(name)}`, { text }),
|
||||
stackAction: (name: string, action: 'deploy' | 'update' | 'restart' | 'stop') => req<TaskInfo>('POST', `/api/docker/stacks/${encodeURIComponent(name)}/${action}`),
|
||||
alerts: () => req<AlertsInfo>('GET', '/api/alerts', undefined, true),
|
||||
saveAlerts: (p: { rules?: AlertRule[]; channels?: AlertChannel[] }) => req<void>('PUT', '/api/alerts', p, true),
|
||||
testAlerts: () => req<void>('POST', '/api/alerts/test', undefined, true),
|
||||
|
||||
Reference in New Issue
Block a user