Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ TODO.md
Lazydocker.code-workspace
.vscode
.idea
coverage.txt
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<img src="https://user-images.githubusercontent.com/8456633/59972109-8e9c8480-95cc-11e9-8350-38f7f86ba76d.png">
</p>

A simple terminal UI for both docker and docker-compose, written in Go with the [gocui](https://github.com/jroimartin/gocui 'gocui') library.
A simple terminal UI for both docker and docker-compose, written in Go with the [gocui](https://github.com/jroimartin/gocui 'gocui') library. Now with experimental Apple Container support!

![CI](https://github.com/jesseduffield/lazygit/workflows/Continuous%20Integration/badge.svg)
[![Go Report Card](https://goreportcard.com/badge/github.com/jesseduffield/lazydocker)](https://goreportcard.com/report/github.com/jesseduffield/lazydocker)
Expand Down Expand Up @@ -86,9 +86,15 @@ Memorising docker commands is hard. Memorising aliases is slightly less hard. Ke

## Requirements

### Docker Runtime (Default)
- Docker >= **1.13** (API >= **1.25**)
- Docker-Compose >= **1.23.2** (optional)

### Apple Container Runtime (Experimental)
- macOS 26 beta or later
- Apple Silicon Mac
- Apple Container CLI (`container` command available in PATH)

## Installation

### Homebrew
Expand Down Expand Up @@ -255,14 +261,39 @@ You can also use `go run main.go` to compile and run in one go (pun definitely i

## Usage

### Basic Usage

Call `lazydocker` in your terminal. I personally use this a lot so I've made an alias for it like so:

```
```bash
echo "alias lzd='lazydocker'" >> ~/.zshrc
```

(you can substitute .zshrc for whatever rc file you're using)

### Container Runtime Selection

By default, lazydocker uses Docker. You can specify a different container runtime using the `--runtime` flag:

```bash
# Use Docker (default)
lazydocker
lazydocker --runtime docker

# Use Apple Container (requires macOS 26 beta and Apple Silicon)
lazydocker --runtime apple
```

### Available Flags

```bash
lazydocker --help
-c --config Print the current default config
-d --debug Enable debug mode
-f --file Specify alternate compose files
-r --runtime Container runtime to use (docker, apple)
```

- Basic video tutorial [here](https://youtu.be/NICqQPxwJWw).
- List of keybindings
[here](/docs/keybindings).
Expand Down
1,715 changes: 0 additions & 1,715 deletions coverage.txt

This file was deleted.

14 changes: 14 additions & 0 deletions docs/Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,20 @@ You may use the following go templates (such as `{{ .Container.ID }}` above) in
- [`{{ .Container }}`](https://pkg.go.dev/github.com/jesseduffield/[email protected]/pkg/commands#Container) and its fields. For example: `{{ .Container.Container.ImageID }}`
- [`{{ .Service }}`](https://pkg.go.dev/github.com/jesseduffield/[email protected]/pkg/commands#Service) and its fields. For example: `{{ .Service.Name }}`

## Container Runtime

Lazydocker supports multiple container runtimes. By default it uses Docker, but you can switch to Apple Container (on macOS 26+ with Apple Silicon) using the `--runtime` flag:

```bash
# Use Docker (default)
lazydocker

# Use Apple Container
lazydocker --runtime apple
```

Note: The runtime cannot be changed from within the application. You must restart lazydocker with the appropriate flag.

## Replacements

You can add replacements like so:
Expand Down
4 changes: 3 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var (
configFlag = false
debuggingFlag = false
composeFiles []string
runtimeFlag = "docker"
)

func main() {
Expand All @@ -51,6 +52,7 @@ func main() {
flaggy.Bool(&configFlag, "c", "config", "Print the current default config")
flaggy.Bool(&debuggingFlag, "d", "debug", "a boolean")
flaggy.StringSlice(&composeFiles, "f", "file", "Specify alternate compose files")
flaggy.String(&runtimeFlag, "r", "runtime", "Container runtime to use (docker, apple)")
flaggy.SetVersion(info)

flaggy.Parse()
Expand All @@ -71,7 +73,7 @@ func main() {
log.Fatal(err.Error())
}

appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles, projectDir)
appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles, projectDir, runtimeFlag)
if err != nil {
log.Fatal(err.Error())
}
Expand Down
57 changes: 43 additions & 14 deletions pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import (
type App struct {
closers []io.Closer

Config *config.AppConfig
Log *logrus.Entry
OSCommand *commands.OSCommand
DockerCommand *commands.DockerCommand
Gui *gui.Gui
Tr *i18n.TranslationSet
ErrorChan chan error
Config *config.AppConfig
Log *logrus.Entry
OSCommand *commands.OSCommand
DockerCommand *commands.DockerCommand
AppleContainerCommand *commands.AppleContainerCommand
ContainerRuntime *commands.ContainerRuntimeAdapter
Gui *gui.Gui
Tr *i18n.TranslationSet
ErrorChan chan error
}

// NewApp bootstrap a new application
Expand All @@ -41,14 +43,29 @@ func NewApp(config *config.AppConfig) (*App, error) {
}
app.OSCommand = commands.NewOSCommand(app.Log, config)

// here is the place to make use of the docker-compose.yml file in the current directory

app.DockerCommand, err = commands.NewDockerCommand(app.Log, app.OSCommand, app.Tr, app.Config, app.ErrorChan)
if err != nil {
return app, err
// Initialize the appropriate container runtime based on config
switch config.Runtime {
case "docker":
// here is the place to make use of the docker-compose.yml file in the current directory
app.DockerCommand, err = commands.NewDockerCommand(app.Log, app.OSCommand, app.Tr, app.Config, app.ErrorChan)
if err != nil {
return app, err
}
app.closers = append(app.closers, app.DockerCommand)
app.ContainerRuntime = commands.NewContainerRuntimeAdapter(app.DockerCommand, nil, "docker")
containerCommand := commands.NewGuiContainerCommand(app.ContainerRuntime, app.DockerCommand, app.Config)
app.Gui, err = gui.NewGui(app.Log, app.DockerCommand, containerCommand, app.OSCommand, app.Tr, config, app.ErrorChan)
case "apple":
app.AppleContainerCommand, err = commands.NewAppleContainerCommand(app.Log, app.OSCommand, app.Tr, app.Config, app.ErrorChan)
if err != nil {
return app, err
}
app.ContainerRuntime = commands.NewContainerRuntimeAdapter(nil, app.AppleContainerCommand, "apple")
containerCommand := commands.NewGuiContainerCommand(app.ContainerRuntime, nil, app.Config)
app.Gui, err = gui.NewGui(app.Log, nil, containerCommand, app.OSCommand, app.Tr, config, app.ErrorChan)
default:
return app, err // This should be caught by config validation, but just in case
}
app.closers = append(app.closers, app.DockerCommand)
app.Gui, err = gui.NewGui(app.Log, app.DockerCommand, app.OSCommand, app.Tr, config, app.ErrorChan)
if err != nil {
return app, err
}
Expand Down Expand Up @@ -77,6 +94,18 @@ func (app *App) KnownError(err error) (string, bool) {
originalError: "Got permission denied while trying to connect to the Docker daemon socket",
newError: app.Tr.CannotAccessDockerSocketError,
},
{
originalError: "Apple Container CLI not found",
newError: "Apple Container CLI not found. Please ensure the 'container' command is installed and available in your PATH.",
},
{
originalError: "failed to get containers",
newError: "Failed to retrieve containers. Please check if the container runtime is running.",
},
{
originalError: "failed to get images",
newError: "Failed to retrieve images. Please check if the container runtime is running.",
},
}

for _, mapping := range mappings {
Expand Down
Loading