Skip to content

Commit 5bf6870

Browse files
committed
Implemented support for 'Apple Container' as a runtime environment
Apple Container is a Docker-like system for managing containers in macOS 26+ Tahoe. Not all Docker features are supported but enough support exists to have Lazydocker function as a frontend.
1 parent 4e2f26b commit 5bf6870

File tree

131 files changed

+4127
-2665
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+4127
-2665
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ TODO.md
33
Lazydocker.code-workspace
44
.vscode
55
.idea
6+
coverage.txt

README.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<img src="https://user-images.githubusercontent.com/8456633/59972109-8e9c8480-95cc-11e9-8350-38f7f86ba76d.png">
4141
</p>
4242

43-
A simple terminal UI for both docker and docker-compose, written in Go with the [gocui](https://github.com/jroimartin/gocui 'gocui') library.
43+
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!
4444

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

8787
## Requirements
8888

89+
### Docker Runtime (Default)
8990
- Docker >= **1.13** (API >= **1.25**)
9091
- Docker-Compose >= **1.23.2** (optional)
9192

93+
### Apple Container Runtime (Experimental)
94+
- macOS 26 beta or later
95+
- Apple Silicon Mac
96+
- Apple Container CLI (`container` command available in PATH)
97+
9298
## Installation
9399

94100
### Homebrew
@@ -255,14 +261,39 @@ You can also use `go run main.go` to compile and run in one go (pun definitely i
255261
256262
## Usage
257263
264+
### Basic Usage
265+
258266
Call `lazydocker` in your terminal. I personally use this a lot so I've made an alias for it like so:
259267

260-
```
268+
```bash
261269
echo "alias lzd='lazydocker'" >> ~/.zshrc
262270
```
263271

264272
(you can substitute .zshrc for whatever rc file you're using)
265273
274+
### Container Runtime Selection
275+
276+
By default, lazydocker uses Docker. You can specify a different container runtime using the `--runtime` flag:
277+
278+
```bash
279+
# Use Docker (default)
280+
lazydocker
281+
lazydocker --runtime docker
282+
283+
# Use Apple Container (requires macOS 26 beta and Apple Silicon)
284+
lazydocker --runtime apple
285+
```
286+
287+
### Available Flags
288+
289+
```bash
290+
lazydocker --help
291+
-c --config Print the current default config
292+
-d --debug Enable debug mode
293+
-f --file Specify alternate compose files
294+
-r --runtime Container runtime to use (docker, apple)
295+
```
296+
266297
- Basic video tutorial [here](https://youtu.be/NICqQPxwJWw).
267298
- List of keybindings
268299
[here](/docs/keybindings).

coverage.txt

Lines changed: 0 additions & 1715 deletions
This file was deleted.

docs/Config.md

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

136+
## Container Runtime
137+
138+
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:
139+
140+
```bash
141+
# Use Docker (default)
142+
lazydocker
143+
144+
# Use Apple Container
145+
lazydocker --runtime apple
146+
```
147+
148+
Note: The runtime cannot be changed from within the application. You must restart lazydocker with the appropriate flag.
149+
136150
## Replacements
137151

138152
You can add replacements like so:

main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var (
2929
configFlag = false
3030
debuggingFlag = false
3131
composeFiles []string
32+
runtimeFlag = "docker"
3233
)
3334

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

5658
flaggy.Parse()
@@ -71,7 +73,7 @@ func main() {
7173
log.Fatal(err.Error())
7274
}
7375

74-
appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles, projectDir)
76+
appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles, projectDir, runtimeFlag)
7577
if err != nil {
7678
log.Fatal(err.Error())
7779
}

pkg/app/app.go

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ import (
1717
type App struct {
1818
closers []io.Closer
1919

20-
Config *config.AppConfig
21-
Log *logrus.Entry
22-
OSCommand *commands.OSCommand
23-
DockerCommand *commands.DockerCommand
24-
Gui *gui.Gui
25-
Tr *i18n.TranslationSet
26-
ErrorChan chan error
20+
Config *config.AppConfig
21+
Log *logrus.Entry
22+
OSCommand *commands.OSCommand
23+
DockerCommand *commands.DockerCommand
24+
AppleContainerCommand *commands.AppleContainerCommand
25+
ContainerRuntime *commands.ContainerRuntimeAdapter
26+
Gui *gui.Gui
27+
Tr *i18n.TranslationSet
28+
ErrorChan chan error
2729
}
2830

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

44-
// here is the place to make use of the docker-compose.yml file in the current directory
45-
46-
app.DockerCommand, err = commands.NewDockerCommand(app.Log, app.OSCommand, app.Tr, app.Config, app.ErrorChan)
47-
if err != nil {
48-
return app, err
46+
// Initialize the appropriate container runtime based on config
47+
switch config.Runtime {
48+
case "docker":
49+
// here is the place to make use of the docker-compose.yml file in the current directory
50+
app.DockerCommand, err = commands.NewDockerCommand(app.Log, app.OSCommand, app.Tr, app.Config, app.ErrorChan)
51+
if err != nil {
52+
return app, err
53+
}
54+
app.closers = append(app.closers, app.DockerCommand)
55+
app.ContainerRuntime = commands.NewContainerRuntimeAdapter(app.DockerCommand, nil, "docker")
56+
containerCommand := commands.NewGuiContainerCommand(app.ContainerRuntime, app.DockerCommand, app.Config)
57+
app.Gui, err = gui.NewGui(app.Log, app.DockerCommand, containerCommand, app.OSCommand, app.Tr, config, app.ErrorChan)
58+
case "apple":
59+
app.AppleContainerCommand, err = commands.NewAppleContainerCommand(app.Log, app.OSCommand, app.Tr, app.Config, app.ErrorChan)
60+
if err != nil {
61+
return app, err
62+
}
63+
app.ContainerRuntime = commands.NewContainerRuntimeAdapter(nil, app.AppleContainerCommand, "apple")
64+
containerCommand := commands.NewGuiContainerCommand(app.ContainerRuntime, nil, app.Config)
65+
app.Gui, err = gui.NewGui(app.Log, nil, containerCommand, app.OSCommand, app.Tr, config, app.ErrorChan)
66+
default:
67+
return app, err // This should be caught by config validation, but just in case
4968
}
50-
app.closers = append(app.closers, app.DockerCommand)
51-
app.Gui, err = gui.NewGui(app.Log, app.DockerCommand, app.OSCommand, app.Tr, config, app.ErrorChan)
5269
if err != nil {
5370
return app, err
5471
}
@@ -77,6 +94,18 @@ func (app *App) KnownError(err error) (string, bool) {
7794
originalError: "Got permission denied while trying to connect to the Docker daemon socket",
7895
newError: app.Tr.CannotAccessDockerSocketError,
7996
},
97+
{
98+
originalError: "Apple Container CLI not found",
99+
newError: "Apple Container CLI not found. Please ensure the 'container' command is installed and available in your PATH.",
100+
},
101+
{
102+
originalError: "failed to get containers",
103+
newError: "Failed to retrieve containers. Please check if the container runtime is running.",
104+
},
105+
{
106+
originalError: "failed to get images",
107+
newError: "Failed to retrieve images. Please check if the container runtime is running.",
108+
},
80109
}
81110

82111
for _, mapping := range mappings {

0 commit comments

Comments
 (0)