Skip to content

fix(compose): build sidecar images and adopt foreign containers on the native path - #115

Merged
bilby91 merged 1 commit into
mainfrom
fix/native-compose-adopt-and-sidecar-builds
Aug 23, 2026
Merged

fix(compose): build sidecar images and adopt foreign containers on the native path#115
bilby91 merged 1 commit into
mainfrom
fix/native-compose-adopt-and-sidecar-builds

Conversation

@bilby91

@bilby91 bilby91 commented Aug 23, 2026

Copy link
Copy Markdown
Member

Two gaps in the native compose orchestrator versus the shellout backend, both surfaced by adversarial review of crunchloop/dap#4828 (which makes ComposeBackendNative the only backend):

1. Non-primary build: services were never built

The orchestrator only creates containers from images (serviceToRunSpec uses svc.Image; the missing-image pull-retry is gated on a non-empty reference), and prepareComposeServiceImage only handles the primary service. A build: sidecar reached ContainerCreate with an empty image and the Up failed — the shellout backend delegated to docker compose up, which builds implicitly.

Fix: Engine.upComposeNative now builds every selected non-primary build: service before the orchestrator runs, honoring compose semantics (image:+build: tags the result with image:; build-only gets compose v2's <project>-<service> default), then pins each via ApplyBuildOverride so hashing, drift detection, and pull-retry all see a concrete reference. runServices selection is honored; build order is deterministic.

2. Foreign containers were destroyed on non-recreate Ups

ensureService recreated any existing container whose dev.containers.config-hash/image-digest labels didn't match — including containers this orchestrator never created (shellout backend, plain docker compose up), which carry no such labels at all. Removing them destroys the writable layer (in-container $HOME, etc.) that the shellout path's NoRecreate contract preserved — a data-loss hazard for every workspace migrating from shellout to native on its first resume.

Fix: a container with the compose project/service labels but no dev.containers.config-hash label is adopted: started if stopped, otherwise left alone. Drift-based recreation still applies to containers carrying our labels, and Recreate-mode Ups still tear the whole project down before the orchestrator runs, so forced refreshes behave exactly as before.

Tests

  • compose: foreign-container adoption (exited → started, running → hands-off; no remove, no create).
  • engine: sidecar build matrix (build-only naming, image:+build: tagging, plain-image untouched, runServices exclusion, project mutation to image-only).
  • go test ./compose/ . green; cmd/devcontainer and runtime/applecontainer fail locally only on the pre-existing missing libACBridge.dylib embed (built by the Makefile in CI).

Needed for crunchloop/dap#4828 — will be consumed as v0.4.1.

🤖 Generated with Claude Code

…e native path

Two gaps versus the shellout backend, both found adversarially reviewing
the switch to ComposeBackendNative as the only backend in dap:

1. Non-primary services with `build:` were never built — the orchestrator
   only creates containers from images and the pull-retry is gated on a
   non-empty reference, so a `build:` sidecar reached ContainerCreate
   with an empty image. Engine.Up now builds every selected sidecar
   before the orchestrator runs (image:+build: tags the built image with
   image:, build-only gets compose v2's <project>-<service> default) and
   pins the result via ApplyBuildOverride, so hashing, drift detection
   and pull-retry all see a concrete reference.

2. ensureService recreated any existing container whose
   dev.containers.config-hash / image-digest labels did not match —
   including containers the orchestrator did not create (shellout
   backend, plain docker compose), which have no such labels at all.
   Removing them destroys the writable layer the shellout path's
   NoRecreate contract preserved across restarts. Such containers are
   now adopted: started if stopped, otherwise left alone. Drift-based
   recreation still applies to containers carrying our labels, and
   Recreate-mode Ups still tear the whole project down first.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your current included review allowance is based on your included PR review attempts over the past 7 days.

Next review available in: 30 minutes

Limit details: You’ve used the included review currently available. Your 66 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

You’re in a promotional period — use the checkbox below to run this review for free:

  • Run review for free

On-demand reviews are free for the next 29 days. After that, they cost $0.25 per reviewed file.

How can I continue?

Run this review now using the option above, or comment @coderabbitai review --use-credits.

You can also wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e02fd3bf-a194-48dc-87ef-5eae6c43c92f

📥 Commits

Reviewing files that changed from the base of the PR and between 1232606 and 144e5ca.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • compose/apply_override.go
  • compose/orchestrator.go
  • compose/orchestrator_test.go
  • up.go
  • up_compose_sidecar_test.go

Comment @coderabbitai help to get the list of available commands.

@bilby91
bilby91 merged commit 65cef43 into main Aug 23, 2026
19 checks passed
@bilby91
bilby91 deleted the fix/native-compose-adopt-and-sidecar-builds branch August 23, 2026 00:35
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