Add project name to docker command

Determing docker compose project name provides the ability to
work with services of each docker compose project separately
in various Lazydocker instances, even if services have the
same names

Determing project name is only available if name explicitly
specified in docker compose project config (docker compose v2)
This commit is contained in:
Daniil Groysman 2025-02-11 20:24:45 +03:00 committed by Гройсман Даниил
parent bedde4a037
commit 60f2dd42ee
2 changed files with 40 additions and 5 deletions

View file

@ -18,6 +18,7 @@ import (
ctxstore "github.com/docker/cli/cli/context/store"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/goccy/go-yaml"
"github.com/imdario/mergo"
"github.com/jesseduffield/lazydocker/pkg/commands/ssh"
"github.com/jesseduffield/lazydocker/pkg/config"
@ -40,6 +41,7 @@ type DockerCommand struct {
Config *config.AppConfig
Client *client.Client
InDockerComposeProject bool
ProjectName string
ErrorChan chan error
ContainerMutex deadlock.Mutex
ServiceMutex deadlock.Mutex
@ -124,6 +126,17 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
if err != nil {
dockerCommand.InDockerComposeProject = false
log.Warn(err.Error())
} else {
composeCommand := config.UserConfig.CommandTemplates.DockerCompose
yamlDockerComposeConfig, err := osCommand.RunCommandWithOutput(fmt.Sprintf("%s config --format=yaml", composeCommand))
if err == nil {
dockerCommand.ProjectName, err = determineProjectName(yamlDockerComposeConfig)
}
if err != nil {
log.Warn(err.Error())
}
}
return dockerCommand, nil
@ -208,7 +221,7 @@ func (c *DockerCommand) assignContainersToServices(containers []*Container, serv
L:
for _, service := range services {
for _, ctr := range containers {
if !ctr.OneOff && ctr.ServiceName == service.Name {
if !ctr.OneOff && ctr.ServiceName == service.Name && (c.ProjectName == "" || ctr.ProjectName == c.ProjectName) {
service.Container = ctr
continue L
}
@ -360,6 +373,24 @@ func (c *DockerCommand) DockerComposeConfig() string {
return output
}
// determineProjectName tries to the determine the docker compose project name
func determineProjectName(yamlDockerComposeConfig string) (string, error) {
var projectName string
var config map[string]any
err := yaml.Unmarshal([]byte(yamlDockerComposeConfig), &config)
if err != nil {
return projectName, err
}
projectName, ok := config["name"].(string)
if !ok {
return projectName, fmt.Errorf("Incorrect value of docker compose project name in config: %s", config["name"])
}
return projectName, nil
}
// determineDockerHost tries to the determine the docker host that we should connect to
// in the following order of decreasing precedence:
// - value of "DOCKER_HOST" environment variable

View file

@ -80,10 +80,14 @@ func (gui *Gui) refreshProject() error {
func (gui *Gui) getProjectName() string {
projectName := path.Base(gui.Config.ProjectDir)
if gui.DockerCommand.InDockerComposeProject {
for _, service := range gui.Panels.Services.List.GetAllItems() {
container := service.Container
if container != nil && container.DetailsLoaded() {
return container.Details.Config.Labels["com.docker.compose.project"]
if gui.DockerCommand.ProjectName != "" {
return gui.DockerCommand.ProjectName
} else {
for _, service := range gui.Panels.Services.List.GetAllItems() {
container := service.Container
if container != nil && container.DetailsLoaded() {
return container.Details.Config.Labels["com.docker.compose.project"]
}
}
}
}