Skip to content

fix(desktop): open Docker Desktop only when it has run before; keep each installation on its engine - #831

Merged
dustywusty merged 8 commits into
mainfrom
dustywusty/docker-desktop-not-podman
Oct 29, 2026
Merged

dustywusty merged 8 commits into
mainfrom
dustywusty/docker-desktop-not-podman

Conversation

@dustywusty

@dustywusty dustywusty commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

What

On macOS and Windows, a new OpenBot Desktop installation picks its container engine in this order:

  1. Docker answers: it is used as it is.
  2. Docker Desktop is installed but stopped, and has run before: it is opened and used. "Run before" means its VM disk exists, so its terms were accepted and its first-run screens are done.
  3. Otherwise, Podman: the Podman already installed, or one OpenBot installs, as before. This includes a Docker Desktop that was installed and never opened, and a docker command that does not answer.

The engine chosen is saved with the installation (.openbot-engine.json in the installation folder, read with preparation::saved_engine). Every later install, Start and sign-in uses only that engine:

  • A Podman installation never moves to a Docker that happens to answer, and the reverse. Moving would start OpenBot with none of its images and an empty database.
  • A saved Docker whose Docker Desktop is stopped is opened before Start. It answered for this installation before. The wait is limited to 3 minutes. If Docker Desktop stops on a screen of its own (updated terms, a required sign-in), the person is told to finish it there.
  • An installation from before this record is pinned to the engine its images are found on, at its next successful Start.

Start brings the engine up. Before, only install started the Podman machine. Reopening OpenBot goes straight to Start, which only looked for an engine, so after a restart a Podman installation failed with "podman is installed but not answering. Start it and try again." Now Start first brings up the saved engine:

  • A saved Docker opens Docker Desktop.
  • A saved Podman, or an installation from before this record with nothing answering, starts OpenBot's own openbot machine when it exists.

No machine is created at Start, and nobody else's is started. An older installation that was on Docker cannot land on an empty machine: Start requires the installation's images on the engine it uses.

Linux: a Docker that answers is used, and anything else gets Podman, as before.

Why

With Docker Desktop installed but quit, setup found no engine that answered and installed Podman behind an administrator prompt, a second engine on a machine that already had Docker.

The first fix opened any installed Docker Desktop and waited 5 minutes for Docker. A Docker Desktop that was never opened shows Docker's subscription terms first. From outside, OpenBot cannot tell that window from a password prompt, a required sign-in or a slow boot, so it would put a person in front of Docker's terms and wait on them. OpenBot must never do that.

How "has run before" is checked

Docker Desktop's VM disk holds every image and container. Docker creates it when its engine first starts, and Docker Desktop does not run until its terms are accepted. These are the places Docker documents in How to back up and restore your Docker Desktop data:

  • macOS: ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
  • Windows: %LOCALAPPDATA%\Docker\wsl\disk\docker_data.vhdx (WSL 2). Also checked: the older wsl\data\docker_data.vhdx and wsl\data\ext4.vhdx, %LOCALAPPDATA%\Docker\vm-data\DockerDesktop.vhdx (Docker VMM) and %ProgramData%\DockerDesktop\vm-data\DockerDesktop.vhdx (Hyper-V).

The check is a stat only. On macOS the disk is inside Docker's app container, where reading or listing raises "would like to access data from other apps". A stat raises nothing: on macOS 27.0.1, stats of Docker.raw (with and without following links) produced no tccd request, while the same process's docker calls do log kTCCServiceSystemPolicyAppDataDetailed requests. OpenBot never runs docker for this check.

A disk moved elsewhere in Docker's settings is not found, and that machine gets Podman, which is the safe side.

Kept from earlier revisions

  • No Compose is placed after starting Docker Desktop. It ships its own.
  • Once Docker answers after the install step, the Podman machine steps are skipped.
  • Docker's own CLI is found wherever Docker Desktop is looked for, ~/Applications included.

OpenBot does not install Docker Desktop.

Test

  • install::tests::the_engine_is_chosen_by_this_table covers every row:
    • an answering Docker;
    • a stopped Docker Desktop used before (opened) and never used (Podman), with and without Podman beside it;
    • a stopped docker with no Docker Desktop (Podman);
    • an existing Podman;
    • nothing (Podman installed);
    • a saved Docker (answering, opened, disk moved, none to open);
    • a saved Podman (Docker answering, Docker Desktop used before, Podman removed);
    • Linux.
  • Further install::tests run the install step itself for these cases. No Podman is ever installed beside a Docker Desktop that is opened, and a Podman installation never moves to an answering Docker.
  • docker_desktop::tests cover:
    • the VM-disk signal (absent, a folder where the disk should be, present) and the documented macOS path;
    • starting a stopped Docker Desktop, and the time limit.
  • tests::start_brings_up_the_engine_this_installation_runs_on and a_machine_that_fails_to_start_stops_start_with_its_own_words (main.rs): Start opens Docker Desktop for a saved Docker, starts OpenBot's machine for a saved or older Podman installation, creates or starts no other machine, and does nothing on Linux or when the engine answers.
  • preparation::tests::the_saved_engine_outlives_a_new_preparation: the saved engine survives a new release being prepared.
  • macOS: cargo fmt --check, cargo clippy --all-targets -- -D warnings and cargo test --lib --bins (659 + 156) pass.
  • Windows: cargo xwin check --target x86_64-pc-windows-msvc --all-targets compiles. Windows clippy with -D warnings fails only on dead code and unused imports already on main (vault.rs, provider_oauth_lock.rs, stack.rs), none in this change.

…hen it is not; never Podman in its place

With Docker Desktop installed but quit, setup found no answering engine and installed Podman behind
an administrator prompt: a second engine on a machine that already had Docker, and one local
Intelligence refuses. On macOS and Windows the engine is now Docker Desktop. Installed and stopped,
it is opened and waited for. Missing, Docker's own installer (4.96.3, pinned to the digests Docker
publishes) is downloaded with progress, installed without accepting Docker's terms, and opened so
the person accepts them in Docker's window. A Podman somebody already has is still used; a stopped
docker with no Docker Desktop (OrbStack, Colima) is left for its owner to start. Linux is unchanged.
The non-macOS branch mapped a spawned process to Default::default(), leaving the type to inference,
which had nothing to go on: error[E0282] on Linux and Windows. It is std::process::ExitStatus's
default, which reads as success; a started Docker Desktop is the whole job there.
@dustywusty

Copy link
Copy Markdown
Collaborator Author

Linux and Windows CI failed to compile this branch: root cause and fix

  • Error: error[E0282]: type annotations needed for Result<_, std::io::Error> at desktop/src-tauri/src/docker_desktop.rs:232, in jobs core, app (linux) and app (windows).
  • Where it entered: the original commit on this branch. The non-macOS launch path was command(&app).spawn().map(|_| Default::default()). Nothing pins the type of Default::default(), so inference fails.
  • Why it went undetected: that branch is #[cfg(not(target_os = "macos"))], and the branch was built and tested only on macOS, so the code was never compiled before CI ran it. A Windows cross-check from macOS isn't possible here because ring needs the Windows SDK.
  • Fix: .map(|_| std::process::ExitStatus::default()). The default status reads as success, which is right: starting Docker Desktop's executable is the whole job there.
  • Evidence: a standalone program with the old expression reproduces the same E0282; the fixed one compiles and runs. CI on this push is the proof for Linux and Windows.

The engine choice on macOS and Windows is now: a Docker that answers is used; an installed Docker
Desktop that is stopped is started; any other stopped `docker` (OrbStack, Colima) is left for its
owner; a machine with no Docker gets Podman, as it did before; an existing Podman is used.

OpenBot no longer installs Docker Desktop itself, so its pinned installers, the streamed download
and the 15-minute first-start wait are removed. Linux is unchanged.
@dustywusty dustywusty changed the title fix(desktop): start Docker Desktop when it is installed, install it when it is not; never Podman in its place fix(desktop): start an installed Docker Desktop instead of installing Podman beside it Oct 27, 2026
@dustywusty
dustywusty marked this pull request as ready for review October 27, 2026 22:16
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-27T22:18:06.079975Z 36f6969 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36f69695af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/src-tauri/src/install.rs Outdated
Comment thread desktop/src-tauri/src/docker_desktop.rs
…nd its CLI in ~/Applications

Starting a stopped Docker Desktop returned from the install step into the Podman-only machine
steps, which fail at `podman machine list` on a machine with no Podman. engine_ready now detects
again after the install step and returns an answering engine (with Compose) directly.

The CLI fallback for macOS looked only in /Applications/Docker.app, while setup also starts a
Docker Desktop in ~/Applications; Docker answering was never seen and the start timed out. The CLI
places are now derived from docker_desktop::app_places, so the two lists cannot drift.
@dustywusty
dustywusty requested a review from samjulien as a code owner October 29, 2026 04:13
place_compose asks Podman whether Compose runs. On a Docker-only machine there is no Podman, so
it downloaded a docker-compose provider into OpenBot's tools directory. Docker's `docker compose`
looks for plugins in its cli-plugins directories, never on PATH, so nothing used it. Docker
Desktop ships Compose itself, and engine_ready checks Docker's Compose once Docker answers.
@dustywusty

Copy link
Copy Markdown
Collaborator Author

No Compose download after starting Docker Desktop (048bf48)

  • Problem: after setup started a stopped Docker Desktop, it ran place_compose. That function checks Compose through acquire::address(), which is Podman on the openbot machine. On a Mac or PC with Docker only, there is no Podman, so the check failed and setup downloaded a docker-compose provider into OpenBot's tools folder.
  • Why nothing used it: Docker's docker compose looks for plugins in its cli-plugins folders, not on PATH. Docker Desktop ships its own Compose plugin.
  • Where it entered: 3479d27, the first commit on this branch, which added the Docker Desktop start path and reused the Compose step that was written for Podman.
  • Why it went undetected: the download succeeds and is only wasted, so setup does not fail. The unit test used a stub for place_compose that always succeeded.
  • Fix: the Docker Desktop branch places no Compose. engine_ready now checks Docker's own Compose after Docker answers (from 8ce0725). If Compose is missing, it shows missing_compose instead of downloading a copy. The test now panics if place_compose is called on this path.
  • Not changed: the "Docker already answers" branch still runs place_compose. There, docker can be Podman's compatibility wrapper, which does use a docker-compose on PATH.

@dustywusty
dustywusty enabled auto-merge (squash) October 29, 2026 04:23
@dustywusty
dustywusty disabled auto-merge October 29, 2026 04:39
…ach installation on its engine

OpenBot opened any installed Docker Desktop and waited up to 5 minutes for
Docker to answer. A Docker Desktop that was installed and never opened shows
its subscription terms first, and nothing outside it tells that window from a
helper prompt, a required sign-in or a slow boot. So a person could be put in
front of Docker's terms and left waiting.

A new installation now uses, in order: a Docker that answers; on macOS and
Windows, a stopped Docker Desktop whose VM disk exists (it has run, so its
terms are done), which is opened; otherwise Podman, as before. A stopped
`docker` with no Docker Desktop behind it is no longer an error: it gets
Podman. The disk is checked with a stat only, which on macOS 27.0.1 raises no
"access data from other apps" request (checked against the TCC log).

The engine chosen is saved with the installation (.openbot-engine.json,
preparation::saved_engine) and every later install, Start and sign-in uses
only that engine. A Podman installation no longer moves to a Docker that
happens to answer, onto an empty database, and the reverse. A saved Docker
whose Docker Desktop is stopped is opened before Start, with a 3-minute limit
and a message for one that stops on a screen of its own. Installations from
before this record are pinned on their next successful Start.
…at install

Only install started the Podman machine. Reopening OpenBot goes straight to
Start, which only looked for an engine, so after a restart a Podman
installation failed with "podman is installed but not answering. Start it and
try again." Nobody this app is for can act on that.

Start now brings up the saved engine first, before startup is held: a saved
Docker opens Docker Desktop, and a saved Podman (or an installation from
before engines were saved, with nothing answering) starts OpenBot's own
machine when it exists. No machine is created at Start and nobody else's is
started. An older installation that was on Docker cannot land on an empty
machine: Start requires the installation's images on the engine it uses.
@dustywusty dustywusty changed the title fix(desktop): start an installed Docker Desktop instead of installing Podman beside it fix(desktop): open Docker Desktop only when it has run before; keep each installation on its engine Oct 29, 2026
@dustywusty
dustywusty merged commit 4766e42 into main Oct 29, 2026
25 checks passed
@dustywusty
dustywusty deleted the dustywusty/docker-desktop-not-podman branch October 29, 2026 05:41
dustywusty added a commit that referenced this pull request Oct 29, 2026
Takes main's engine choice (#831): Docker Desktop is opened only when it
has run before, and each installation stays on the engine it was set up
on. The old copy of #831 on this branch is dropped, including
after_engine_install, which duplicated main's answering_after_install
and ignored the saved engine. Kept from this branch: path_with_docker,
downloads chosen by the machine's architecture on Windows on ARM, and
the per-user Docker Desktop location on Windows.

Takes main's #823 and #821 (StartFresh replaces DatabaseReset; the local
Intelligence screen offers it too), #860, and #858's Recorder step label.

The web app keeps main's theme and skin picker (#856); this branch's
CopilotKit reskin of the app and its two fonts are dropped. Its desktop
CSS (room for the macOS window buttons, sidebar resize) stays.
dustywusty added a commit that referenced this pull request Oct 29, 2026
…man machine

Which engine OpenBot uses is main's (#831): Docker if it answers, Docker Desktop if it has run
before, otherwise Podman, saved with the installation. This commit no longer changes that choice.

Local Intelligence's k3d needs rootful Podman (CopilotKit/Intelligence#2147), so the machine OpenBot
creates is `--rootful`, and OpenBot addresses it through its `<name>-root` connection, the rootful
engine, both for its own machine and for a running machine it adopts. On a rootful Windows machine
the host-gateway setting goes to the system configuration. An existing rootless machine is never
switched; local Intelligence setup and start decline there instead, with a `rootless-podman`
failure whose row names `podman machine set --rootful`.

Every Intelligence CLI process gets COPILOTKIT_LOCAL_ENGINE for the engine OpenBot runs on, recorded
when the engine is ready (also where Docker answers right after the install step) and when Start
pins it; before either, the installation's saved engine. For a Podman machine it also gets
CONTAINER_HOST and DOCKER_HOST naming the machine's forwarded API, drops an inherited
DOCKER_CONTEXT, and has Podman's directory on PATH. While Podman installs, the step row names the
password prompt macOS or Linux raises. The window's runtime row no longer says Docker Desktop.
dustywusty added a commit that referenced this pull request Oct 29, 2026
…man machine

Which engine OpenBot uses is main's (#831): Docker if it answers, Docker Desktop if it has run
before, otherwise Podman, saved with the installation. This commit no longer changes that choice.

Local Intelligence's k3d needs rootful Podman (CopilotKit/Intelligence#2147), so the machine OpenBot
creates is `--rootful`, and OpenBot addresses it through its `<name>-root` connection, the rootful
engine, both for its own machine and for a running machine it adopts. On a rootful Windows machine
the host-gateway setting goes to the system configuration. An existing rootless machine is never
switched; local Intelligence setup and start decline there instead, with a `rootless-podman`
failure whose row names `podman machine set --rootful`.

Every Intelligence CLI process gets COPILOTKIT_LOCAL_ENGINE for the engine OpenBot runs on, recorded
when the engine is ready (also where Docker answers right after the install step) and when Start
pins it; before either, the installation's saved engine. For a Podman machine it also gets
CONTAINER_HOST and DOCKER_HOST naming the machine's forwarded API, drops an inherited
DOCKER_CONTEXT, and has Podman's directory on PATH. While Podman installs, the step row names the
password prompt macOS or Linux raises. The window's runtime row no longer says Docker Desktop.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant