b0816502bf
- Add image_prune_threshold_mb setting (default 1024 MB) - Add GET /api/docker/unused-images endpoint returning unused image count, size, and threshold status - Dashboard shows amber warning banner when unused project images exceed threshold - Banner links to settings page for pruning, shows count and human-readable size (MB/GB) - Threshold configurable in Docker Image Cleanup section of settings - DB migration + schema for image_prune_threshold_mb
208 lines
7.8 KiB
Go
208 lines
7.8 KiB
Go
package store
|
|
|
|
// Project represents a deployable application.
|
|
type Project struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Registry string `json:"registry"`
|
|
Image string `json:"image"`
|
|
Port int `json:"port"`
|
|
Healthcheck string `json:"healthcheck"`
|
|
Env string `json:"env"` // JSON-encoded map
|
|
Volumes string `json:"volumes"` // JSON-encoded map
|
|
NpmAccessListID int `json:"npm_access_list_id"` // per-project override, 0 = use global
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
// Stage represents a deployment stage within a project (e.g. dev, rel, prod).
|
|
type Stage struct {
|
|
ID string `json:"id"`
|
|
ProjectID string `json:"project_id"`
|
|
Name string `json:"name"`
|
|
TagPattern string `json:"tag_pattern"`
|
|
AutoDeploy bool `json:"auto_deploy"`
|
|
MaxInstances int `json:"max_instances"`
|
|
Confirm bool `json:"confirm"`
|
|
EnableProxy bool `json:"enable_proxy"`
|
|
PromoteFrom string `json:"promote_from"`
|
|
Subdomain string `json:"subdomain"`
|
|
NotificationURL string `json:"notification_url"`
|
|
CpuLimit float64 `json:"cpu_limit"` // CPU cores (e.g., 0.5, 1, 2), 0 = unlimited
|
|
MemoryLimit int `json:"memory_limit"` // megabytes, 0 = unlimited
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
// Registry represents a container image registry.
|
|
type Registry struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
URL string `json:"url"`
|
|
Type string `json:"type"`
|
|
Token string `json:"token"`
|
|
Owner string `json:"owner"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
// Settings holds global application configuration (single-row pattern).
|
|
type Settings struct {
|
|
Domain string `json:"domain"`
|
|
ServerIP string `json:"server_ip"` // Docker host IP (for NPM remote forwarding)
|
|
PublicIP string `json:"public_ip"` // Public-facing IP for DNS A records (e.g., NPM/proxy host)
|
|
Network string `json:"network"`
|
|
SubdomainPattern string `json:"subdomain_pattern"`
|
|
NotificationURL string `json:"notification_url"`
|
|
NpmURL string `json:"npm_url"`
|
|
NpmEmail string `json:"npm_email"`
|
|
NpmPassword string `json:"npm_password"`
|
|
WebhookSecret string `json:"webhook_secret"`
|
|
PollingInterval string `json:"polling_interval"`
|
|
BaseVolumePath string `json:"base_volume_path"`
|
|
SSLCertificateID int `json:"ssl_certificate_id"`
|
|
StaleThresholdDays int `json:"stale_threshold_days"`
|
|
AllowedVolumePaths string `json:"allowed_volume_paths"` // JSON array of allowed absolute paths
|
|
WildcardDNS bool `json:"wildcard_dns"`
|
|
DNSProvider string `json:"dns_provider"`
|
|
CloudflareAPIToken string `json:"cloudflare_api_token"`
|
|
CloudflareZoneID string `json:"cloudflare_zone_id"`
|
|
NpmRemote bool `json:"npm_remote"`
|
|
NpmAccessListID int `json:"npm_access_list_id"`
|
|
ProxyProvider string `json:"proxy_provider"`
|
|
TraefikEntrypoint string `json:"traefik_entrypoint"`
|
|
TraefikCertResolver string `json:"traefik_cert_resolver"`
|
|
TraefikNetwork string `json:"traefik_network"`
|
|
TraefikAPIURL string `json:"traefik_api_url"`
|
|
ImagePruneThresholdMB int `json:"image_prune_threshold_mb"`
|
|
BackupEnabled bool `json:"backup_enabled"`
|
|
BackupIntervalHours int `json:"backup_interval_hours"`
|
|
BackupRetentionCount int `json:"backup_retention_count"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
// Backup represents a backup metadata record.
|
|
type Backup struct {
|
|
ID string `json:"id"`
|
|
Filename string `json:"filename"`
|
|
SizeBytes int64 `json:"size_bytes"`
|
|
BackupType string `json:"backup_type"` // "manual" or "auto"
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
// DNSRecord tracks a DNS record managed by the application.
|
|
type DNSRecord struct {
|
|
ID string `json:"id"`
|
|
FQDN string `json:"fqdn"`
|
|
ProviderRecordID string `json:"provider_record_id"`
|
|
ConsumerType string `json:"consumer_type"` // "instance" or "standalone"
|
|
ConsumerID string `json:"consumer_id"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
// Instance represents a running (or stopped) container for a project stage.
|
|
type Instance struct {
|
|
ID string `json:"id"`
|
|
StageID string `json:"stage_id"`
|
|
ProjectID string `json:"project_id"`
|
|
ContainerID string `json:"container_id"`
|
|
ImageTag string `json:"image_tag"`
|
|
Subdomain string `json:"subdomain"`
|
|
NpmProxyID int `json:"npm_proxy_id"`
|
|
ProxyRouteID string `json:"proxy_route_id"`
|
|
Status string `json:"status"` // running, stopped, failed, removing
|
|
Port int `json:"port"`
|
|
LastAliveAt string `json:"last_alive_at"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
// Deploy represents a deployment attempt.
|
|
type Deploy struct {
|
|
ID string `json:"id"`
|
|
ProjectID string `json:"project_id"`
|
|
StageID string `json:"stage_id"`
|
|
InstanceID string `json:"instance_id"`
|
|
ImageTag string `json:"image_tag"`
|
|
Status string `json:"status"` // pending, pulling, starting, configuring_proxy, health_checking, success, failed, rolled_back
|
|
StartedAt string `json:"started_at"`
|
|
FinishedAt string `json:"finished_at"`
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
// DeployLog is a single log entry for a deploy.
|
|
type DeployLog struct {
|
|
ID int64 `json:"id"`
|
|
DeployID string `json:"deploy_id"`
|
|
Message string `json:"message"`
|
|
Level string `json:"level"` // info, warn, error
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
// StageEnv represents a per-stage environment variable override.
|
|
type StageEnv struct {
|
|
ID string `json:"id"`
|
|
StageID string `json:"stage_id"`
|
|
Key string `json:"key"`
|
|
Value string `json:"value"`
|
|
Encrypted bool `json:"encrypted"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
// VolumeScope defines the sharing scope for a volume mount.
|
|
// Valid scopes: instance, stage, project, project_named, named, ephemeral.
|
|
type VolumeScope string
|
|
|
|
const (
|
|
VolumeScopeInstance VolumeScope = "instance"
|
|
VolumeScopeStage VolumeScope = "stage"
|
|
VolumeScopeProject VolumeScope = "project"
|
|
VolumeScopeProjectNamed VolumeScope = "project_named"
|
|
VolumeScopeNamed VolumeScope = "named"
|
|
VolumeScopeEphemeral VolumeScope = "ephemeral"
|
|
VolumeScopeAbsolute VolumeScope = "absolute"
|
|
)
|
|
|
|
// ValidVolumeScopes contains all valid scope values for validation.
|
|
var ValidVolumeScopes = []VolumeScope{
|
|
VolumeScopeInstance, VolumeScopeStage, VolumeScopeProject,
|
|
VolumeScopeProjectNamed, VolumeScopeNamed, VolumeScopeEphemeral,
|
|
VolumeScopeAbsolute,
|
|
}
|
|
|
|
// IsValidVolumeScope returns true if the given string is a valid scope.
|
|
func IsValidVolumeScope(s string) bool {
|
|
for _, v := range ValidVolumeScopes {
|
|
if string(v) == s {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Volume represents a volume mount configuration for a project.
|
|
type Volume struct {
|
|
ID string `json:"id"`
|
|
ProjectID string `json:"project_id"`
|
|
Source string `json:"source"`
|
|
Target string `json:"target"`
|
|
Mode string `json:"mode,omitempty"` // legacy: shared/isolated — kept for DB compat
|
|
Scope string `json:"scope"` // instance, stage, project, project_named, named, ephemeral
|
|
Name string `json:"name"` // required for project_named and named scopes
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
// EventLog represents a persistent event log entry.
|
|
type EventLog struct {
|
|
ID int64 `json:"id"`
|
|
Source string `json:"source"`
|
|
Severity string `json:"severity"` // info, warn, error
|
|
Message string `json:"message"`
|
|
Metadata string `json:"metadata"` // JSON-encoded structured data
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|