Skip to content

Commit

Permalink
Add project name to docker command
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
Groysman881 authored and Гройсман Даниил committed Feb 12, 2025
1 parent bedde4a commit 60f2dd4
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
33 changes: 32 additions & 1 deletion pkg/commands/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
Expand Down
12 changes: 8 additions & 4 deletions pkg/gui/project_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
}
}
}
}
Expand Down

0 comments on commit 60f2dd4

Please sign in to comment.