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" ctxstore "github.com/docker/cli/cli/context/store"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/goccy/go-yaml"
"github.com/imdario/mergo" "github.com/imdario/mergo"
"github.com/jesseduffield/lazydocker/pkg/commands/ssh" "github.com/jesseduffield/lazydocker/pkg/commands/ssh"
"github.com/jesseduffield/lazydocker/pkg/config" "github.com/jesseduffield/lazydocker/pkg/config"
@ -40,6 +41,7 @@ type DockerCommand struct {
Config *config.AppConfig Config *config.AppConfig
Client *client.Client Client *client.Client
InDockerComposeProject bool InDockerComposeProject bool
ProjectName string
ErrorChan chan error ErrorChan chan error
ContainerMutex deadlock.Mutex ContainerMutex deadlock.Mutex
ServiceMutex deadlock.Mutex ServiceMutex deadlock.Mutex
@ -124,6 +126,17 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
if err != nil { if err != nil {
dockerCommand.InDockerComposeProject = false dockerCommand.InDockerComposeProject = false
log.Warn(err.Error()) 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 return dockerCommand, nil
@ -208,7 +221,7 @@ func (c *DockerCommand) assignContainersToServices(containers []*Container, serv
L: L:
for _, service := range services { for _, service := range services {
for _, ctr := range containers { 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 service.Container = ctr
continue L continue L
} }
@ -360,6 +373,24 @@ func (c *DockerCommand) DockerComposeConfig() string {
return output 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 // determineDockerHost tries to the determine the docker host that we should connect to
// in the following order of decreasing precedence: // in the following order of decreasing precedence:
// - value of "DOCKER_HOST" environment variable // - value of "DOCKER_HOST" environment variable

View file

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