Skip to content

Commit 4db7436

Browse files
authored
feat: add Coolify labels as fallbacks for container name and group (#4384)
1 parent 98a4901 commit 4db7436

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

assets/models/Container.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export class Container {
8585
get namespace() {
8686
return (
8787
this.labels["dev.dozzle.group"] ||
88+
this.labels["coolify.projectName"] ||
8889
this.labels["com.docker.stack.namespace"] ||
8990
this.labels["com.docker.compose.project"]
9091
);

docs/guide/container-names.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,12 @@ services:
2727
```
2828
2929
:::
30+
31+
## Coolify Integration
32+
33+
If you're using [Coolify](https://coolify.io/), Dozzle automatically recognizes Coolify's labels as fallbacks:
34+
35+
- `coolify.resourceName` → Used as container name if `dev.dozzle.name` is not set
36+
- `coolify.projectName` → Used for grouping if `dev.dozzle.group` is not set
37+
38+
No additional configuration is needed for Coolify deployments.

internal/docker/client.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,17 @@ func newContainer(c docker.Summary, host string) container.Container {
386386
name := "no name"
387387
if c.Labels["dev.dozzle.name"] != "" {
388388
name = c.Labels["dev.dozzle.name"]
389+
} else if c.Labels["coolify.resourceName"] != "" {
390+
name = c.Labels["coolify.resourceName"]
389391
} else if len(c.Names) > 0 {
390392
name = strings.TrimPrefix(c.Names[0], "/")
391393
}
392394

393395
group := ""
394396
if c.Labels["dev.dozzle.group"] != "" {
395397
group = c.Labels["dev.dozzle.group"]
398+
} else if c.Labels["coolify.projectName"] != "" {
399+
group = c.Labels["coolify.projectName"]
396400
}
397401
return container.Container{
398402
ID: c.ID[:12],
@@ -412,13 +416,17 @@ func newContainerFromJSON(c docker.InspectResponse, host string) container.Conta
412416
name := "no name"
413417
if c.Config.Labels["dev.dozzle.name"] != "" {
414418
name = c.Config.Labels["dev.dozzle.name"]
419+
} else if c.Config.Labels["coolify.resourceName"] != "" {
420+
name = c.Config.Labels["coolify.resourceName"]
415421
} else if len(c.Name) > 0 {
416422
name = strings.TrimPrefix(c.Name, "/")
417423
}
418424

419425
group := ""
420426
if c.Config.Labels["dev.dozzle.group"] != "" {
421427
group = c.Config.Labels["dev.dozzle.group"]
428+
} else if c.Config.Labels["coolify.projectName"] != "" {
429+
group = c.Config.Labels["coolify.projectName"]
422430
}
423431

424432
container := container.Container{

internal/docker/client_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,105 @@ func Test_dockerClient_ContainerActions_error(t *testing.T) {
260260

261261
proxy.AssertExpectations(t)
262262
}
263+
264+
func Test_newContainer_labelPriority(t *testing.T) {
265+
tests := []struct {
266+
name string
267+
labels map[string]string
268+
containerName string
269+
expectedName string
270+
expectedGroup string
271+
}{
272+
{
273+
name: "dozzle labels take priority",
274+
labels: map[string]string{"dev.dozzle.name": "dozzle-name", "coolify.resourceName": "coolify-name", "dev.dozzle.group": "dozzle-group", "coolify.projectName": "coolify-project"},
275+
containerName: "/docker-name",
276+
expectedName: "dozzle-name",
277+
expectedGroup: "dozzle-group",
278+
},
279+
{
280+
name: "coolify labels as fallback",
281+
labels: map[string]string{"coolify.resourceName": "coolify-name", "coolify.projectName": "coolify-project"},
282+
containerName: "/docker-name",
283+
expectedName: "coolify-name",
284+
expectedGroup: "coolify-project",
285+
},
286+
{
287+
name: "docker name as final fallback",
288+
labels: map[string]string{},
289+
containerName: "/docker-name",
290+
expectedName: "docker-name",
291+
expectedGroup: "",
292+
},
293+
{
294+
name: "coolify name with dozzle group",
295+
labels: map[string]string{"coolify.resourceName": "coolify-name", "dev.dozzle.group": "dozzle-group"},
296+
containerName: "/docker-name",
297+
expectedName: "coolify-name",
298+
expectedGroup: "dozzle-group",
299+
},
300+
}
301+
302+
for _, tt := range tests {
303+
t.Run(tt.name, func(t *testing.T) {
304+
summary := docker.Summary{
305+
ID: "abcdefghijklmnopqrst",
306+
Names: []string{tt.containerName},
307+
Labels: tt.labels,
308+
}
309+
c := newContainer(summary, "localhost")
310+
assert.Equal(t, tt.expectedName, c.Name)
311+
assert.Equal(t, tt.expectedGroup, c.Group)
312+
})
313+
}
314+
}
315+
316+
func Test_newContainerFromJSON_labelPriority(t *testing.T) {
317+
tests := []struct {
318+
name string
319+
labels map[string]string
320+
containerName string
321+
expectedName string
322+
expectedGroup string
323+
}{
324+
{
325+
name: "dozzle labels take priority",
326+
labels: map[string]string{"dev.dozzle.name": "dozzle-name", "coolify.resourceName": "coolify-name", "dev.dozzle.group": "dozzle-group", "coolify.projectName": "coolify-project"},
327+
containerName: "/docker-name",
328+
expectedName: "dozzle-name",
329+
expectedGroup: "dozzle-group",
330+
},
331+
{
332+
name: "coolify labels as fallback",
333+
labels: map[string]string{"coolify.resourceName": "coolify-name", "coolify.projectName": "coolify-project"},
334+
containerName: "/docker-name",
335+
expectedName: "coolify-name",
336+
expectedGroup: "coolify-project",
337+
},
338+
{
339+
name: "docker name as final fallback",
340+
labels: map[string]string{},
341+
containerName: "/docker-name",
342+
expectedName: "docker-name",
343+
expectedGroup: "",
344+
},
345+
}
346+
347+
for _, tt := range tests {
348+
t.Run(tt.name, func(t *testing.T) {
349+
state := &docker.State{Status: "running", StartedAt: time.Now().Format(time.RFC3339Nano)}
350+
json := docker.InspectResponse{
351+
ContainerJSONBase: &docker.ContainerJSONBase{
352+
ID: "abcdefghijklmnopqrst",
353+
Name: tt.containerName,
354+
State: state,
355+
HostConfig: &docker.HostConfig{},
356+
},
357+
Config: &docker.Config{Labels: tt.labels},
358+
}
359+
c := newContainerFromJSON(json, "localhost")
360+
assert.Equal(t, tt.expectedName, c.Name)
361+
assert.Equal(t, tt.expectedGroup, c.Group)
362+
})
363+
}
364+
}

0 commit comments

Comments
 (0)