feat: add custom health check commands per app
All checks were successful
Check / check (pull_request) Successful in 1m45s

Add configurable health check commands per app via a new
'healthcheck_command' field. When set, the command is passed
to Docker as a CMD-SHELL health check on the container.
When empty, the image's default health check is used.

Changes:
- Add migration 007 for healthcheck_command column on apps table
- Add HealthcheckCommand field to App model with full CRUD support
- Add buildHealthcheck() to docker client for CMD-SHELL config
- Pass health check command through CreateContainerOptions
- Add health check command input to app create/edit UI forms
- Extract optionalNullString helper to reduce handler complexity
- Update README features list

closes #81
This commit is contained in:
user
2026-03-17 02:11:08 -07:00
committed by clawbot
parent 67361419f5
commit 067cb86124
12 changed files with 352 additions and 79 deletions

View File

@@ -1094,6 +1094,29 @@ func (svc *Service) buildContainerOptions(
network = app.DockerNetwork.String
}
cpuLimit, memoryLimit := extractResourceLimits(app)
healthcheckCmd := ""
if app.HealthcheckCommand.Valid {
healthcheckCmd = app.HealthcheckCommand.String
}
return docker.CreateContainerOptions{
Name: "upaas-" + app.Name,
Image: imageID.String(),
Env: envMap,
Labels: buildLabelMap(app, labels),
Volumes: buildVolumeMounts(volumes),
Ports: buildPortMappings(ports),
Network: network,
CPULimit: cpuLimit,
MemoryLimit: memoryLimit,
HealthcheckCommand: healthcheckCmd,
}, nil
}
// extractResourceLimits returns CPU and memory limits from the app model.
func extractResourceLimits(app *models.App) (float64, int64) {
var cpuLimit float64
if app.CPULimit.Valid {
@@ -1106,17 +1129,7 @@ func (svc *Service) buildContainerOptions(
memoryLimit = app.MemoryLimit.Int64
}
return docker.CreateContainerOptions{
Name: "upaas-" + app.Name,
Image: imageID.String(),
Env: envMap,
Labels: buildLabelMap(app, labels),
Volumes: buildVolumeMounts(volumes),
Ports: buildPortMappings(ports),
Network: network,
CPULimit: cpuLimit,
MemoryLimit: memoryLimit,
}, nil
return cpuLimit, memoryLimit
}
func buildLabelMap(app *models.App, labels []*models.Label) map[string]string {