#container-use
1 messages ยท Page 1 of 1 (latest)
Discussion on hacker news: https://news.ycombinator.com/item?id=44193933
This is fantastic. I just added it to kilo-code - here is a video of the creating two environments for 'hello world' using flask and fastapi video
check out the mcp at https://github.com/dagger/container-use.
I've created two Hello World web applications using the container-use MCP server, each in its own isolated environment:
- Flask Hello World Application
Environment ID: flask-hello/deciding-hawk
URL: http://127.0.0.1:5235
Technology: Flask
Base Image: python:3.11-slim
Features: Simp...
Thanks for sharing this! We'd love to highlight this more. I'll DM you ๐
@prime mason thank you! we should add kilo-code integration instructions in the readme ๐ want to open a pr? ๐
@_catwu As much as i love claude code, please bring an easy way to reverse to a checkpoint, the only way i know is through prompt and i always fear it forgets or cant reverse the code exactly as it was
This is really interesting https://github.com/humanlayer/12-factor-agents
Happy to do it. This will be my very first PR !
PR opened
https://x.com/bradwmorris/status/1931030786213605664
โmulti-agent madnessโ, great name for a future demo video
We passed 500 stars on github ๐
https://news.ycombinator.com/item?id=44226978 <-- container on mac native... Seems like low hanging fruit for dagger?
Yes this will remove friction to installing CU on Mac, it comes at a perfect time for us
Please Let me know if you have a few moments to chat any time this week.
FYI @cosmic birch @restive pumice I filed an issue to track (one of ) friday's topic. IMO it's an important one. https://github.com/dagger/container-use/issues/45
IMO this requires moving away from "each env is a branch" and towards "each env is a fork". At the moment our architecture straddles both concepts.
Constraining each env to a single branch IMO is incompatible with letting the agent work freely. What if the agent wants to juggle 5 branches for whatever reason? There's just no way to square that circle IMO.
Now, if each env is a fork, that feels more robust. First it maps better to the COW mechanics of Dagger, and containers in general. A fork is basically a copy of a directory. We can work with that.
Now, if each env is a fork - don't we lose the convenience of having a ready-to-merge branch from each env? Well yes, but I was thinking - git already has a system for that and it's called a remote. What if instead of showing each env as a branch, we showed each env as a remote? Then we can use git's existing tooling and conventions for finding and using the branches from each remote
One downside consequence of this would be, that we wouldn't have to use git worktrees. Instead we would use more vanilla git features. Basically remotes, and moving objects and refs between them
also as discussed I think we should group all the state into a unified custom ref instead of splitting the workdir and the rest. workdir should not be a special case in the state
I agree with the general vibes regarding robustness, but i'm be a little concerned about whether standard git UXes do a good job handling a local repo with a bajillion remotes. I also don't think that the original problem irt agents being unable to use git in containers necessarily needs to be coupled to enabling agents to use multiple branches in containers... this is plausibly something that we can increment towards.
Now, if each env is a fork - don't we lose the convenience of having a ready-to-merge branch from each env? Well yes,
lol i'd answer your rhetorical question with "no" , but it does get immediately weird because of restrictions on tracking branches. say i wanna create an env, starting from my local checkout of main. ok, make a new remote, call it env-adverb-animal, push main to to env-adverb-animal, mount it in a container, agent commits changes... now we've got new content on env-adverb-animal/main, BUT there's no good way to "link" that up to my source repo main because that main is supposed to track origin and you can't have 1 branch tracking 2 remotes
but there are standard git commands to manage all that and we can automate them if needed
more importantly it all maps to a familiar workflow for the user
i'm mostly concerned about fetching fwiw, or "refresh" buttons in guis
but you're probably right that it can be automated by server for the most part
(FWIW: we can prefix remote names with cu/ so that an env remote is cu/$ENV_NAME)
anyways the "you only get 1" restriction on tracking branches is the bigger concern here, like i still think we need source-repo checkouts of agent-created work, and if we want to show the user that the agent is continuing to work on a given branch, I don't see how we can get away from envs creating a branch, or eventually multiple.
but maybe the layout is something like cu/{$envRemote}/{$envBranch} where $envRemote is adverb-animal and $envBranch has a human-readable, non-collision-resistant name
actually wait no, that doesn't work... the branch name needs to be collision resistant if you wanna have a source repo branch that tracks it. otherwise you kick off the same task in parallel in 5 envs, and 4 of them fail because you're trying to create the same $envBranch source repo tracking branch 5 times with different remotes but the same branch name
so in short eschewing ties to branches basically throws away the possibility of populating tracking branches on the source repo. without tracking branches, git checkout envRemote/branch is always a detached head. that means you can merge it and log it without touching it, but the experience around checkout is gonna be weird:
more importantly it all maps to a familiar workflow for the user
people rarely use remotes without tracking branches in my experience, so having a remote without its own branches is unfamiliar, like in an uncanny valley way. concretely:
you'll have this detached head remote branch with a name that's very likely to collide with your local branch names or branch names from other remotes, and no automatic way to differentiate between what you've got checked out and the additional commits the agent has made since then.
all that said, you could of course have an env have both its own remote and it's own branches, each designed to be collision resistant. that said, i think the UX there is quite bad, it's a lot of random identifiers thrown in the users' face, and i'm not sure what concrete additional functionality we'd gain from adding the additional layer of identifiers for the remote when each branch is already unique, tracking, and so on
i'm also skeptical that users want an agent making changes to multiple branches... part of the value here has to be an opinion about how and where to contain an agent. reading from other branches has some obvious marginal value like "adapt this PR branch to additionally do XYZ", but idk when you'd really need an agent to have 1 environment with 2 different writable branches- why not fork the environment or even create a fresh one?
another random thing: we could totally make the envs look more like remotes if we want... tibor pointed out that that we can prefix remote names with cu/ to get cu/$ENV_NAME/human-readable-branchname... we can also switch the order of the branch identifier and change the remote name to cu/ to get a remote ref cu/$BRANCH_NAME that looks like cu/adverb-animal/human-readable-branchname
which tbh maybe helps with the cognitive overhead of what's going on here... i was optimizing for useful tab-completion where you type cu/flask-app/<tab> and see a list of environments that have been created to write a flask app, but maybe it'd be better to promote the illusion that only human-readable-branchname is actually a branch? ... downside to that is that you'd still not be able to git checkout human-readable-branchname because the tracking branch would still have to be adverb-animal/human-readable-branchname for the collision resistance
sorry for the novel lmao, imma log out
speaking of random git features that may have weird UX if we use them for novel purposes: the UX around pushing tags is HORRIBLE -- when i was trying to get rehydrate working i briefly experimented with tagging the initial commit of each env, and now i keep accidentally pushing those tags upstream. git push --tags --force origin v0.0.0 somehow pushed a tag for me just now that wasn't v0.0.0
I'm still digging the git implementation to gain an intuitive understanding -- I have to say, Connor, that the current state is very clever -- a lot of nice tricks ๐ง
lol shit, i was trying to make it dumb but it came out clever instead
post and discussion about containerized dev environments for coding agents. i suspect folks in this channel have something to contribute: https://news.ycombinator.com/item?id=44221655
https://lucumr.pocoo.org/2025/6/12/agentic-coding/
mentions container-use
Discussion: https://news.ycombinator.com/item?id=44255608
Heyho. Was pointed here from the hackernews thread on my post ๐
I don't have a ton of feedback at the moment but i'm evaluating it
welcome @hexed lance ๐
hey @hexed lance love the series, nice to see it's getting attention on HN. i'm using posts like yours to understand what people are trying to work with coding agents, and how that's going. so looking forward to hearing more about your workflow either here or in the next post.
welcome! i love how small world oss work is sometimes, we've had agents "build" roughly a billion flask demo apps while iterating on container-use for the last month ๐
welcome @hexed lance!
Hi all, I'm trying to get cu working (from cursor), mcp server is up and running, got a fresh local and remote git repo; but i'm keep getting this git related issue:
failed to open environment: failed initializing worktree: git command failed (exit code 128).... not a git repository
I can log a github issue, but wanted to see if the experts here encountered smtg similar?
another 'small world' situation - you contributed the Twig template engine to my Chyrp PHP blog engine project waaaaay back in 2008 ๐ welcome, funny to cross paths again!
Yes indeed! Small world ๐
Hope you're doing great! Still think of that thing every once in a while since it sometimes shows up in the PHP world still
likewise! yeah, Twig really took on a life of its own lol
Hi @sweet steeple! I'm going to try the same with Cursor, will report back in a minute
usually this means when calling environment_create the agent is providing a source argument that's not a git repository
It mentions โ.โ As source
gonna look into it, i wonder if cursor's like zed and it's running mcp servers with cwd=/
(i can't get cu working in zed because of this, it basically repeatedly fails to guess your project directory)
oh you know one way to debug, give it a complete path to the project in the prompt
I just tried and it seems to be working ...
Oh right, maybe!
@sweet steeple I started cursor from the git repository though (cd <repository>, cursor .) ... maybe that's why
let me try to start it from the macos dock directly see how it goes
Can you collapse one of those tool calls? Just to check the source
Will try the cmdline start as well
@sweet steeple the other thing is we are assuming that you're working on a git repo here, that error would also happen if you haven't done a disregard me, i can't read, you already said you've got a fresh local repogit init in your project directory
Could you try from the terminal, within the repo, to do a cu list? Just to remove Cursor from the equation and to check if cu is having issues with the repo itself
Cu list works perfectly
git -log working in that dir as well
Tried commandline startup of cursor in the repo no success
Doing this by explicitly mentioning the repo dir at startup, still not working
Fyi, managed to get it working by explicitly adding a rule to point to the correct source directory
We can maybe add this to the cursor rule template?
I tried the opposite (starting Cursor from the dock, opening the repository) and it also works, weirdly enough
Iโm on mac
I'm on mac too
PR up for Amazon Q Developer CLI chat ๐
https://github.com/dagger/container-use/pull/61
https://github.com/dagger/container-use/blob/2293be7103aaed2f18a6cb5aa010e4791ae5c90d/README.md
First big draft on the test suite: https://github.com/dagger/container-use/pull/65. The aim was to have:
- a nice UX to represent the test cases
- Focus on what I find critical to test -- a nice foundation
- Found a few bugs -- but preferred to skip the tests and fix them in follow-up instead of mixing things
Does cu have caching? https://x.com/cablelounger/status/1923829160373301411
if so, itโs a benefit worth calling out
.@OpenAI 's cloud codex will need environment caching.
For the `xs` rust project, it takes ~8 minutes to fetch cargo dependencies and run a cold `cargo test`, which makes spinning up many environments for small tasks prohibitive
yes via Dagger. We could leverage it more, but we do have it.
@cosmic birch could you say more about that? token usage is a concern for some when running agents in parallel and in background. (except if they're if they're using claude code with monthly subscription.)
My plan is to play with container-use over the weekend, but I wonder what the strategy would be for services that I need. Eg: i have a database (postgres) and a cache (redis) that is needed during development. What would be the recommended way to split this up?
Would you expect each environment to get their own isolated db/redis or for them to share something with the host?
I'll give it a try later today and report back on a recommendation. We don't have a good solution for that yet -- there is functionality in the run tool to launch background tasks and do container-to-container and host-to-container networking, but that's mostly meant for stateless processes (e.g. your app, not a db)
But maybe I can throw something very experimental together before the weekend ๐
For the tests Iโm working with rollbacks anyways so just having the db there works. For redis I could assign a prefix if the container gives me some seed I can use maybe. Itโs all different options
The easiest option is to spawn more containers ๐
Yep, it's the easiest. The only concerning part is ... you get an empty db/redis then what? Would probably need to prompt it into running migrations or something
My tests run migrations once so thatโs okay
That said, migrating in parallel can cause issues
Since the schema is shared between workers then
Yep. I was thinking of giving each environment their own instance of services (so even more containers)
Yes, we have caching (dagger's caching out of the box). We didn't do a ton of optimizations so we're barely using it, but in the scenario you shared, "fetch cargo dependencies" would only happen once
That being said, AFAIK that's not going to save tokens, just time. Waiting for an MCP to finish doesn't eat up tokens, just (your) compute (@restive pumice right?)
@jovial nimbus e.g. it's something we got for free by building on top of dagger
Understood. And if theyโre running in background while Iโm getting coffee then it doesnโt matter if it takes two seconds or two minutes.
the time saved on initial setup can make a big difference
especially for more complex environments.
it also translates to compute savings
@jovial nimbus Yep, what matters is tokens in/out. But when a command is cached, we still retrieve the output from cache (because the LLM might need it, e.g. "install foo" might return "ok I installed foo v1.2" which the agent actually needs)
But yeah -- in this scenario, for the xs project, it would take 8 minutes the first time, a couple of seconds thereafter
Also it makes sense when you have multiple environments -- the first one will take 8 minutes, the next 50 environments will only take a few seconds
might translate into a "sip of coffee" rather than making and drinking an entire one ๐
Gotcha. So itโs a time saving benefit plus reassurance: if I spin up 10 agents right before I leave for coffee, I only need to wait a few mins to see and be assured that theyโre off and running successfully and didnโt trip on some install failure
Oh and if I donโt like what the agent is doing I can terminate it and start over but this time not wait
Thereโs no cleanup and also no penalty for scrapping work and restarting.
the waiting doesn't consume tokens, but the output of the toolcall can... idk how that works out with caching but if cache hits re-return stdout from "fetch cargo depenencies" that can be a problem for token usage
the time savings here is a UX thing even in the async scenario: if it's gonna go off the rails, i do spend the first 45s looking at output before i run off for my proverbial coffee lol, so cache hits mean that that 45s is plausibly the agent starting to do actual work
it's like designing your long-running jobs for fast-fail - often a small change, but one that can be surprisingly valuable
My little cleanup friend for now when I've partied too hard
cu list | xargs -n 1 -I {} sh -c 'cu delete {}; git branch -D {};' && rm -rf .container-use && git remote remove container-use
@hexed lance I added some very crude service management, each environment gets their own instance with network routing (e.g. in each environment "postgres" and "redis" resolves to their own instance of those services) + port mapping with the host for debugging
Are there services have an env var or how would I find them?
@hexed lance when the agent enters an environment, it gets told which services are available and their addresses
right now you can either configure services manually or the agent can add them using an MCP tool (still debating whether it's a good thing or not to let the agent adding services)
There currently is no env var that gets set up automatically. However, <service name> resolves through DNS so you can have a static configuration to reach them out
these 127.0.0.1:<random port> are to reach them from your laptop, however internally they're just reachable through postgres:<default postgres port>
this is the response the agent is making for humans (with addresses reachable from the laptop), however it knows to use the internal endpoint from within, e.g. it generated this:
# Redis configuration
redis_client = redis.Redis(host='redis', port=6379, decode_responses=True)
I feel like I must be missing something completely obvious given there are no reported issues around this in GitHub... but I cannot for the life of me get container-use to work. I keep getting connection refused when following the instructions in the README.
[DEBUG] MCP server "container-use": Connection failed: McpError: MCP error -32000: Connection closed
[DEBUG] MCP server "container-use": Error message: MCP error -32000: Connection closed
[DEBUG] MCP server "container-use": Error stack: McpError: MCP error -32000: Connection closed
I have Docker running, tried installing container-use both from the script and from source... no sym links + I am passing the full path. Intel MacBook if that matters.
Trying to run it with Claude Code.
Hey @silent mason! What command did you use to add the MCP server to Claude?
Was it claude mcp add container-use -- cu stdio?
Sorry I need to head out for dinner, but I'll check in
That worked, thanks!! I don't have the bash history to see what I was doing differently. Full path seems to work too claude mcp add container-use -- $(which cu) stdio. Glad it's PEBKAC and not actually a problem with my environment.
I suspect maybe it clashed with another cu binary (thereโs one in macOS) and gave that cryptic error โฆ
Itโs in v0.0.2
I'm running into the same problem as above. Claude Code on Mac M1.
Connection failed: McpError: MCP error -32000: Connection closed
My config seems correct though:
$ claude mcp list
container-use: /Users/amueller/.local/bin/cu stdio
I realise this is experimental so I'm totally happy if it's not fixable, but I thought I'd check!
for completeness, my version:
$ /Users/amueller/.local/bin/cu version
cu version 0.0.2
commit: 279639ade9a6f8fc376e2060659f68c04acb632e
built: 2025-06-14T01:29:33Z
~~apologies if someone already posted this type of error but I can't get passed this issue. cu mcp is up . cline 3.17.8-313 vscode 1.101.0 claude 3.7 sonnet : Git cloned a simple flask app and asked to create a simple flask app. Error on environment_open. Source is correct path to the cloned repo locally ~~Error: failed to open environment: failed intializing worktree: git command failed (exit code 1): exit status 1 Output: Could not get home directory: $HOME is not defined
$HOME env is set properly. opened vscode from terminal (mac osx) and directly and same error either way
anyone else hit this ?
I resolved this error by ensuring HOME was set as env in the mcp server config
I resolved a similar issue by adding the "/Users/XYZ/.local/bin/" to beginning of $PATH
https://github.com/dagger/container-use/issues/18
cc @opaque zephyr
It currently collides with OSx's cu command (https://www.unix.com/man_page/osx/1/cu/) and some users (@samalba) have reported that they were a bit a confused initially as there was a bit of fri...
https://simonwillison.net/2025/Jun/14/multi-agent-research-system/
^interesting read around the concept of multi-agentic systems
OK, I'm sold on multi-agent LLM systems now. I've been pretty skeptical of these until recently: why make your life more complicated by running multiple different prompts in parallel when โฆ
IMO quite relevant for the container-use use-case
Iโm trying to use goose with container-use, but whenever I add container-use as an extension (just copying the template from the readme), goose hangs. Has anyone else ran into that?
Hey, can you please share your goose config ๐ ๐ -- Seems to be working for me rn
Iโm trying to use goose with container
I think I got my repo into a weird state where I can't make new cu workspaces? Getting this error
> this app is faking the iss load because of CORS issues. Figure out how to make this work for real
pls. I am open to a light backend if necessary
โ I'll analyze your ISS app and figure out how to fix the CORS issues to get real ISS data. Let me first examine the current codebase to understand what you have.
โ container-use:environment_open (MCP)(source: "/home/evan/dev/iss_demo_take_two", name: "iss-demo-cors-fix", explanation: "Opening environment to analyze ISS demo app and fix CORS
issues")
โฟ Error: failed to open environment: failed to propagate to worktree: failed to commit worktree changes: git command failed (exit code 1): exit status 1
Output: On branch iss-demo-cors-fix/deep-sculpin
nothing to commit, working tree clean
My git status looks like
iss_demo_take_two> $ git status
On branch main
nothing to commit, working tree clean
Anything I can do to get out of this situation?
I also noticed that claude code will try using the container-use MCP like 3 times and then it will just start yoloing changes to my local environemnt (rm -f, git checkout ..., etc lol).
May want to update the base CLAUDE.md to tell it to give up on the assigned task if it cannot use cu
@hexed lance how did the week-end experiment go? ๐
well it turns out i did an all-nighter with friends vibe coding
unfortunately i did not manage to use container-use ๐ฆ
didn't get a chance, or tried and hit a problem?
just the type of problem did not lend itself to containerization well (xcode project)
@restive pumice any luck on getting this to work with Zed?
boutta give it a try again on the nightly
After fixing the issues found with the tests -- wdyt about: https://github.com/dagger/container-use/issues/81 cc @cosmic birch
Interesting, would you mind firing a PR ? or an issue with a repro ๐
turns out the fix isn't on zed's public preview until wednesday, gonna try building from source but not gonna spend too much time yak shaving rust toolchains if it doesn't just work out the box
ran into a cu terminal error
https://github.com/dagger/container-use/pull/78 should fix it
@silver abyss if you wanna try the fix, i'd appreciate it. You can check out my branch and run go build -o ~/.local/bin/cu ./cmd/cu it will overwrite your installed binary (if you're not using homebrew).
I can! But I'm on homebrew, so can uninstall first
/opt/homebrew/bin/cu
brew uninstall container-use
probably safer indeed.
That's a very interesting edge case... In theory you could still benefit from the sandboxed file edits (via separate git worktrees) even if your build commands can't run in a linux container. Like a more streamlined version of the various git worktree hacks out there. Perhaps not worth the overhead?
cc @cosmic birch
@crimson plume and I got container use working on the experimental OpenAI Codex Rust CLI codex-rs that supports connecting to MCP servers ๐
Documented here: https://github.com/dagger/container-use/blob/main/README.md#openai-codex
need a quick review for the homebrew tap automation
NOTE: this requires that we configure a token that has Content and PR R/W permissions on container-use and homebrew-tap repos. I do not have the powers, but there's a pending one called rel...
feel free to merge
tq, i gotta merge it and cut a fairly meaningless release to make reality match README
in the meantime you can merge my PR before making the release ๐
sorry for the inane questions about the POSIX details btw, i just want it written down
@hexed warren the one weird thing about your PS1 PR is that we might actually wanna have dagger in the terminal PS1 since we're powered by dagger (as opposed to container-use or cu)
but imma merge anyways
happy to change that
it was a suggestion
Also, i'm doing bash --version to show we're in bash, but happy to change the PS1 to include the name of the shell
i'm also fairly ambivalent about it, it's really a tech marketing question for @opaque zephyr @cosmic birch
explicitly: should the shell PS1 say container-use or dagger
Im trying to use just the built-in vscode/copilot features to use container-use, I set up the system as described in the README and I can see the container-use MCP, however whenI try to run the example it keeps trying to do things locally on my machine.
Anyone have a simple example using just copilot in vscode?
/cc @potent canopy -- sounds like the instructions are not going through
try asking "... in an environment". Should be the default when adding instructions to the project
@restive pumice @potent canopy @hexed warren Just did this on top of #62 (didn't want to get #62 too huge): https://github.com/dagger/container-use/pull/85
Basically just getting rid of the state history / revisions etc. That made sense pre-git but not so much now?
It does handle migration under the hood
need another quick release infra review: https://github.com/dagger/container-use/pull/86. the homebrew tap publishing worked, but the order was all weird in a way that doesn't match the instructions i commiteed to REALEASING.md and creates a lil window during the release where the brew tap will break
merged
grrrrr sorry 1 more attempt, i'm playing the push-and-pray game with goreleaser yaml here, but i'm like 90% i solved it properly this time. https://github.com/dagger/container-use/pull/87 @hexed warren
this is my last push and pray attempt. upon closer inspection of the goreleaser docs instead of just the yaml schema, the issue here was that we were opening a PR from main onto main.
https://gorel...
i do have a setup for testing this on forks, but the PAT setup is annoying
"Please try again" ๐
woooo that did it
it does make the PR as me and the DCO is broken, but good enough for now
cool, we're all good and working on v0.0.5 and brew install dagger/tap/container-use. fyi @silver abyss since you installed from my tap as a test, you need to do this weird dance of brew uninstall container-use && brew untap cwlbraa/tap && brew install dagger/tap/container-use
just noticed
https://github.com/dagger/container-use/blob/main/install.sh#L66-L67
log_error "Windows is not supported"
log_info "container-use uses Unix syscalls and requires Linux or macOS"
but I can install on WSL and the cu binary runs...but it seems that cu stdio just returns after a second or so with no error message. Is there a way to debug this? Expected? edit: I used strace in WSL. See thread.
cc @restive pumice
Context: I was putting this in MSFT Visual Studio 2022 (not VS Code) and it seems like it will work fine with GH Copilot Agent except for this returning unexpectedly issue.
Hi, what if I want to do some experiments with container-use and I am not yet using actively any agentic coding tool? Which one requires no paid plan, or allows a very low rate for "hello-world"-like experiments?
just noticed
Hey ๐ , some people here have been using goose with google's gemini -- you have some quotas ; I guess VSCode with the integrated models is fine too
out of curiosity, has anyone been able to run goose + container use as a headless auto scaled multi user service?
Goose as a multi-user, pod-per-user service:
1. Auth: best OIDC/OAuth layer to map incoming users to pods.
2. Orchestration: operator/spawner that spins up (and reuses) one pod per user/session.
3. Storage: per-user persistent volume (EBS/EFS/S3-fuse) auto-attached so Goose retains history.
My main issue right now is mapping an auth identity to their own sessions / workspace, since goose in its current state, assumes that itโs a single user
perhaps the answer is just a separate goose Kubernetes deployment for each user, when the tech is still young
woah! Sounds cool. I haven't heard of anyone pulling that off yet, but I'm super interested! ๐ฟ
Kind of rough, should be able to push something up later today, but started a wip VS Code extension to setup commands and register the MCP server for container use...
does it actually open the environment in the editor? or just configures the container-use mcp?
Registers the mcp server and adds commands, but Iโm not sure those are worth while? Maybe a command to setup like the proposed doctor command?
yeah if it just configures the mcp server i was wondering what the use case is for installing an extension instead of just dropping in the json config
i think it's mostly that extensions can be a nice release channel - you can update container-use when you update your other extensions and some users don't ever wanna interact with a CLI (regardless of whether that's cu, brew, or apt-get)
ah so the extension actually distributes the binary too?
yeah one day (prolly not in jason's first go, though)
Probably helps with discovery being on the marketplace?
yeah i was wondering about that for cline too - they have an mcp-marketplace although it didn't seem like its actually getting updated unforunately
i'll make an issue there anyway
sometimes when i find random packages like this i wanna use in my dev setup, if i'm kinda ambivalent about the idea like it's not a strong "need", i look at a github readme and they want me to build from source or even download the binary manually from the releases page, i will check to see if somebody else has put it in homebrew or the aur, and if they haven't i do not download - extensions solve this
Actually, I can probably look at how the go extension install gopls and other tools and follow suit with a prompt if we canโt detect cu?
@silver abyss any luck with getting this to be less overwheliming of a command? ๐
q chat --trust-tools=container_use___environment_checkpoint,container_use___environment_file_delete,container_use___environment_file_list,container_use___environment_file_read,container_use___environment_file_write,container_use___environment_open,container_use___environment_run_cmd,container_use___environment_update
Or even a way to save this by default?
Looks like it's only with the non-brew version
i think you can put this in the config json
Help me im two weeks behind ๐
~/.aws/amazonq/mcp.json or somewhere else?
cline for example https://github.com/dagger/container-use?tab=readme-ov-file#cline
see the autoApprove field
yes in there
"autoApprove": [
"environment_file_read",
"environment_open",
"environment_run_cmd",
"environment_update",
"environment_file_write",
"environment_file_delete"
]
You are my hero, any reason not to just add this to the README?
yeah @silver abyss and I briefly talked about that yesterday. I'm not sure how opinionated people are about their auto-approve lists. My theory is that the concept of auto-approve is going to change very quickly. We could provide one block that has every tool listed in the autoApprove array though
i can add that in a sec
is there a way right now to see a diff of a merge before merging? i dont see anything in cu merge -h for flags
Amazon Q is working really well for me, thanks for the demo @silver abyss
If you run the big command, likely youโll see the config file if it exists.
Yeah, I was pleasantly surprised! Works great in terminal too for suggestions
Oh I am only using in Terminal haha, is there some other way ๐
its cu log <env>
hmmm.... we can add signing/notarizing to the release automation, i can prolly dig up some keys from dagger/dagger and justin, but this is still surprising to me that removing the signature helps because nowhere in the config do i do anything with signing 
also adding signing is likely to break any ability we have to "test release" using forks, so there is a drawback there
Then the problem is there is no signature.
codesign -s - adds an ad-hoc signature
ah cool, makes sense
But that only works when the user does it, you cannot do that in the release scripts
Although, TECHNICALLY, we could do codesign -s - in the install script ๐ but that would make us look really bad
Iโm a bit late to this discussion, but I did it the way I did with Q because it seemed the most idiomatic for now ๐
Im gonna make an alias for myself, but otherewise its all good
Half the battle was figuring out the format that each tool uses to refer to a particular MCP and itโs tools. Q was totally different than Claude code for example.
@silver abyss@crimson plume Hey thank for you adding the integrations for all those agents!
I was thinking ... what if we had a cu configure (name TBD) that:
- Detects which coding agent you're using (or asks you if we can't figure it out)
- Configures MCP. Configures the rule. Configures the yolo-auto-approve
This would greatly simplify the installation process (e.g. avoid the issues @blissful mural and others run into), while keeping our getting started a one liner (e.g. we'd still provide the docs for each agent, but that's an "advanced" use case on a separate page)
[/cc @restive pumice @hexed warren @potent canopy]
If you think it's a good idea I'll file an issue.
I think this thing should work both in interactive mode and in unattended mode (e.g. cu configure --yes or getting confirmations for Yolo update [Y/n])
The other thing ... the yolo updates, every time we change the MCP tools, those things are going to be outdated. We could have users just re-run cu configure to get the latest updates
Yeah, I hate those mcp docs -- I want a 1 click button
Yeah that sounds awesome especially if we can interactively choose the agent or multiple agents
We were talking about this at lunch ๐
Fun fact: me too ๐ different lunch, same topic
Btw, I fixed the host caching issue -- it's draft-y and burst the cache, and probably potentially fixed by your environment PR Andrea: https://github.com/dagger/container-use/pull/96 (I'll see after your rebase)
Might be worth merging with this cu doctor potentially, or maybe under the same namespace? https://github.com/dagger/container-use/issues/81.
I want, as a UX:
curl install_script.sh # command to install
cu doctor # everything is green
cu configure claude # boom it works
How can i pass aws credentials to the environment created from computer-use?
We actually have (undocumented) secrets support.
You can ask the agent to use secrets ("Use the AWS credentials found in <secret reference>")
<secret reference> works via secret providers, it currently supports:
env://ENV_NAME<-- environment variablefile://PATH<-- secret in a fileop://<PATH><-- 1Passwordvault://<PATH><-- Vault
Do you pass the computer-use logs to your server?
do you mean "container-use" when you say "computer-use"? Just to be clear ๐
container-use runs locally (and is open source), there are no external servers involved
oh yes my bad. container-use
why not both? (I didn't realize that computers in tupperware containers was a thing ๐คฃ of course it is)
@cosmic birch you reminded me to file this issue https://github.com/dagger/container-use/issues/98 (for later)
I already filed an issue for it on D-day, you commented on it ๐
Slightly different, issue 12 is for having the feature. Issue 98 is specifically for hiding secret references from the model (ie. virtualize them)
Yeah I was about to file a similar one after typing in here and you beat me to it
Fun fact: looks like this container-use PR was created using container-use: https://github.com/dagger/container-use/pull/80
Note to self: the commit messages are good to observe the agent, but not so good to share as a PR ... we should tweak that
/cc @opaque zephyr @restive pumice
I was thinking something similar like a setup (naming?) command would be super helpful instead of copying files from the README. Something like cu setup vscode|claude that would add the mcp config and extras directly in the repo would be a really nice DX!
Ok, got a lot farther with the VS Code Container Use extension:
- Added a command to "setup" the environment. This adds the mcp.json and prompts the user to add the optional copilot instructions
- Auto registers the MCP server when installed (which is why it showed up twice in the list
)
TODO:
- Check that the directory is a git directory
- Look at how the Go extension installs gopls and do something similar for cu so the user only needs to install the extension
- Prewarm the host machine (e.g. make sure Docker is there and pull the container image for the engine behind the scenes)
@cosmic birch regarding allowing container-use to potentially include third party stuff (files, directories) into the environment. Seems like once installed and configured, container-use has a high influence on what the agent does even if other MCP's are also registered in the agent session, doesn't it? cc @agile jacinth
Are we ready to merge your PRs #62 and #85 Andrea ? Just to ensure that this part of the API is stable and I can rebase the tests
Yes, it's ready. Was waiting to get some more feedback from you, @restive pumice and @hexed warren. Ok to merge?
checking again for err handling, 1 sec
@still robin Yes. Once the agent is tricked into using container-use once (because of the prompt), it gets an environment_id and is "stuck" to keep using it (e.g. no other MCP server takes an environment_id except container-use, so the agent has no choice)
@potent canopy @restive pumice merged!
Yaay, thanks ๐
Is it possible to update the version command to also include the Dagger SDK version? I need that to pull images dynamically
func (env *Environment) buildBase(ctx context.Context) (*dagger.Container, error) {
sourceDir, err := dag.
Host().
Directory(env.Worktree, dagger.HostDirectoryOpts{NoCache: true}). // bust cache for seperate calls (create vs update)
Sync(ctx) // but when restoring from env.container, sourceDir changes shouldn't bust cache
@cosmic birch i think this gives correct caching behavior for the host dir load btw, but i think it also might introduce a durability requirement on the dagger engine cache. like if you lose your engine cache, then try to restore one of the saved environment.container LLBs, this directory ID is gonna be missing, i think?
it's an edge case kinda, but one super cool thing is i think we can catch that error, and if we've saved off the initial ref, we can almost certain rehydrate the ref into some other worktree, then call this sync again to refill the cache.
there is a problem there, though, in that we'd then have to do a step by step rewrite of all the container-use-state notes after that "create environment" commit cuz every one will have changed
When you have a ton of environments, would it be helpful if there was a description based on the prompt you could view for each one?
Yes, totally
Not sure I follow but itโs been a long week ๐
https://github.com/dagger/container-use/pull/105
^^^ I just opened this. The PR itself doesnโt matter much, the cool thing is I mostly built this using container-use and goose, lots of dogfooding! Will dump some raw notes
Itโs good overall, but some UX quirks
I think the most annoying ones were:
-
switching between envs / resuming / etc: As @flat oar mentioned it would be useful to have a description or something, itโs very hard to find your environment back. But generally speaking, how you interact with an environment (create vs update) needs refining
-
Commits. Currently our commits are meant to โobserveโ what the agent did.However if you โuseโ them as regular commits, theyโre not very good!
The description is not great, and the logical separation is not great either: we have one commit per file change, but as I was iterating each prompt was modifying 4 files and generated 4-5 commits โฆ itโs almost impossible to rollback, cherry pick, etc. Also to open the PR I had to manually squash 100 commits into something logical
I donโt know how, but it would be better if the agent could split up the commits into logical working units, with a good description โฆ and maybe having the low level changes as notes
- small UX quirks
I wonder if the environment has a sentence descripton summarizing your prompt if the environment name can be a simple petname?
Yeah maybe a short/long description. cu list would list the short desc along with a timestamp? And cu info (?) the long description โฆ
Weโd keep the description updated throughout (offering a tool so the model can update the summary)
The new container-use-state can now have multiple fields aside from the container-id, this could be a good place to stash such info
lol sorry i was at the end of my brain rope as well, just had to write it down somewhere
Trying to wrap my head around how this things work and couldn't figure it out from reading the docs. I'd love to use this for my elixir/phoenix apps, is that possible? How does it know what kind of container to spin up?
Never mind I see. It looks like it tries to create a container on the fly and pick which base image based on your project.
is this expected behavior for now or a gap to be fixed ? the end summary instructs checkout but the changes are not in the checked out branch unless doing a cu merge ? If this behavior is expected, then the end summary should be corrected by tuning the copilot instructions https://github.com/dagger/container-use/blob/main/rules/agent.md ?
we're definitely abreast of this UX paper cut and several others around it- a ton of dagger employees have had similar problems. the hard part is that you can get the up-to-date checkout with git checkout container-use/<branch-name>, but that's a detached head because of how remotes work and lots of ppl are disoriented with a checkout of a detached head. we're actively iterating towards something that will be less confusing, so when you initially check out the agent's work it'll be up-to-date.
we've tried a bunch of different ways of prompt engineering around this, all of them work sometimes, but hopefully by changing the git integration slightly, we can get something that works all the time
I've been using cu lately and it already works for one of my use case so far, which seems very promising
. Just spotted a bug during my test and opened a https://github.com/dagger/container-use/pull/112, could anyone take a look ?
this might be more of a general dagger CLI question but I got to it using container-use the LLM spun up a node server http://127.0.0.1:55659 and it's still accessible but when I look at docker ps only dagger engine is listed, and I'm wondering how can I see the actual container still running
a lot of folks have been saying that container-use is "powered by docker containers" .... the reality is that it's powered by dagger containers, and because they're highly ephemeral and there a bajillion of them, there's no dagger ps command
tbh dagger should probably have a dagger services command, because those are sometimes not so ephemeral, like in raw dagger you can do dagger call fn-returning-service up and it'll stick around for as long as that cli process is running, but until container-use, that workflow is mostly used with terminal splits
looks good from 100 feet, will try to repro and merge tomorrow
Ahh OK yeah for this use case I am looking for something closer to a dagger ps because I don't get how to interact with the container the agent spun up
ahhhh there's cli commands, you're looking for cu list
Ohh awesome thanks!
also cu terminal, cu log, etc
Iโm finding my background command Iโm running (a phoenix server) is constantly dying after a short bit of time. Any thoughts as to why thatโs happening?
so some feedback on container-use so far: it definitely works, i don't entirely enjoy it yet. I think it needs to get much easier to understand wtf is going on as the agents are working and how to see it
the killer feature for sure should be actual parallelism but i find that just to be too hard to use right now
I had cu working great with claude but all of a sudden I seem stuck in a loop where no matter what I try its no longer able to do git operations.
Seeing things like this fatal: not a git repository: /home/levlaz/.config/container-use/repos/slopshop/worktrees/becoming-falcon
It does all the right stuff but then when I try to cu merge or git checkout none of the files are saved or changed in the worktree.
trace: https://dagger.cloud/levlaz/traces/7efdad517ef682dc576b21790295bd5d#a649a4ac25ec0228:EL1
Any ideas?
that is definitely a bug, the repo path should be /home/levlaz/.config/container-use/repos/slopshop
Not sure if it's possible but with brew install if you could have it warn when cu utility already installed like the script does it would be useful. Cost me a few minutes repeating same troubleshooting step after setting up on a new system realizing it was due to the same binary name conflict.
Iโd love to know more, was this Linux brew? On macOS thereโs always another cu binary, but the homebrew PATH will also always precede /usr/bin. the intent of the tap was to have it โjust workโ but there are edge cases we could warn about
Thanks for the feedback, it's very appreciated.
Yes we agree and solving the "wth is going on" issue is our top priority.
Does container-use support using Podman instead of Docker ?
here's my cursor Auto-run config so you don't get annoying tool prompts each time the agent uses container use .
The here's the list of commands:
mcp__container-use__environment_checkpoint,mcp__container-use__environment_file_delete,mcp__container-use__environment_file_list,mcp__container-use__environment_file_read,mcp__container-use__environment_file_write,mcp__container-use__environment_open,mcp__container-use__environment_run_cmd,mcp__container-use__environment_update
In case it helps anyone, I have this useful one liner that I add into my justfile (or makefile) that lets me clean up everything that is happening at the moment. I am not sure if its actually a good thing to do this but does seem to help when I get stuck in a weird spot.
clean:
cu list | xargs -n1 cu delete
git branch --list | grep -v main | xargs -r git branch -D
first bit cleans all cu environments, second bit removes all branches except for main
Appreciate the feedback! And agree with the sentiment, currently doing a bunch of dogfooding to improve the tooling
Do you think it's a tooling problem (e.g. give me more tools to figure out what's going on) or the complexity of the architecture?
I m starting to see a weird issue while using CU with kilo. I have this configuration in the MCP_settings.json which would add the CU as MCP tool in KIlo. { "mcpServers": { "container-use": { "command": "/opt/homebrew/bin/cu", "args": [ "stdio" ], "env": {}, "alwaysAllow": [], "disabled": false } } }. However i keep getting MCP error -32000: Connection closed error from the server status . Has anyone else faced this. How can i debug this further?
If it helps, this is how it looks like
Is there some good pattern for avoiding git conflicts? For example ill open up a cu generated thing in my editor and edit it. Then start a new session in cu but it keeps trying to update the old file instead of branching off of the latest.
Same thing happens when I delete a file, it keeps bringing it back in.
Anyone run into this?
it keeps trying to update the old file instead of branching off of the latest.
like it's creating a new environment, but not getting your local untracked changes?
ill open up a cu generated thing in my editor
say more, is this aftergit checkout env-id; git pull? and then are you still on that branch when trying to create a new environment?
MCP error -32000: Connection closed error from the server status . Has anyone else faced this. How can i debug this further?
start a tail -f -b0 /tmp/cu.debug.stderr.log, then toggle the server off and on again in kilo. do any logs appear? what happens if you run /opt/homebrew/bin/cu stdio directly? (could be a binary signature issue, could be something else, tryna eliminate the signature issue)
Yeah, but then ill switch back to main and start a brand new session. It will make a new branch but feels like its branching off something other than my main branch
im confused, you switch back to main, but are you're expecting main to have edits from the env branch? or is it the other way around, you expect creating a new session on main not to have edits from the env branch?
Sorry for any confusion. This is switching back to main after merging everything. Then wanting to move on to a net new tasks.
I am expecting to start the net new task from wherever my current HEAD is I suppose. But that does not seem to always be happening.
ahh gotcha that makes way more sense. it should absolutely be starting the net new task from your current head
cu version?
(main is a mess right now btw)
Ha,
levlaz@nao:~/git/image-annotator$ cu version
cu version 0.0.5
commit: e3aabe8daffbe3e12a1042e75848d41657183d98
built: 2025-06-16T23:26:03Z
am i living in the past?
you are not
that's the most recent stable
@blissful mural are you using cu merge to do that merge? and are you making the changes on the env branch and then committing them?
cmd := exec.CommandContext(ctx, "git", "merge", "-m", "Merge environment "+env, "--", "container-use/"+env)
(cu merge merges the remote ref, not your local checkout, so any changes you added locally before merging are lost)
Yeah I am probably doing this wrong I feel like I am doing
cu merge
edit on main
commit from main. I basically never go to the branch that cu is creating locally.
Either way feels like we should document the correct workflow here because its a bit confusing. If you are 100% vibing it works great, but as soon as you try to be a human in the loop I am noticing it becomes a bit more challenging.
yeah we're working on it, right now there is no correct workflow.
but more importantly, if you're committing on main and then it's still not getting those changes when creating a new env, it's not a "you're holding it wrong" thing, it's a bug
i don't think it can be a cache problem, but maybe there's something about merging that messes up initial worktree setup?
Ill work on a repro and file a bug report! \
Not entirely sure. I think a lot of it is tooling for sure. But some of it is probably inherent
In case it helps anyone, I have this
hi, version installed with homebrew (macOS) has missing commands, is that ok?
Like, no version command
thanks, taking a look ๐
can you share your
brew info container-use
==> container-use: 0.0.5
https://github.com/dagger/container-use
Installed
/opt/homebrew/Caskroom/container-use/0.0.5 (14.1MB)
Installed on 2025-06-16 at 16:33:36
From: https://github.com/dagger/homebrew-tap/blob/HEAD/Casks/container-use.rb
==> Name
None
==> Description
Containerized environments for coding agents
==> Artifacts
cu (Binary)
==> container-use: 0.0.5
https://github.com/dagger/container-use
Installed
/opt/homebrew/Caskroom/container-use/0.0.5 (14.1MB)
Installed on 2025-06-19 at 23:25:40
From: https://github.com/dagger/homebrew-tap/blob/HEAD/Casks/container-use.rb
==> Name
None
==> Description
Containerized environments for coding agents
==> Artifacts
cu (Binary)```
how about which cu
/Users/myuser/.local/bin/cu
see that's not the version you installed with homebrew, that was installed with the install.sh script
oh, I see
rm -f /Users/myuser/.local/bin/cu and you'll get the newer brew one instead
nice, thanks... will do after this vibe coding session ends ๐
i had some weird brew state making me unable to find container-use with brew ; everything is fine on our end indeed ๐
So, whoโll be the first to try container use with Gemini CLI? https://github.com/google-gemini/gemini-cli
Very curious how it does with parallel work compared to Claude Code
@cosmic birch @restive pumice for the shell completions, it is indeed a mess. There are two kinds of people: those who know what they're doing and know the cu completion bash pattern. For the rest, I'm debating to add an install command that detects the shell and tries to smartly modify the right rc file depending on the shell and the system. (detect if completion already installed, and append if not installed). I don't mind owning it if issues come up. So the UX would be cu completion install and that's it
For the record, docker installer modifies the shellrc that's detected. Kubectl has many pages of docs just for completion based on shell and platform.
Lemme put my shell thing up as a PR, it takes a different approach
I think if there's a way to add that to homebrew ... and then people installing manually we should give the the one off command (not persistent) and let them deal with it?
I hate homebrew so much I can't in good conscience recommend people to install homebrew for container-use, but if people already have it it is an easy install.
Which is why i'd like a "simple install + completion" that works for people who don't have homebrew. And that's a different target from "people who know what they're doing"
related topic: a cu init would be nice to skip the manual curl ... > CLAUDE.md step
I think there's a cu configure PR up
oh sweet
I'm splitting the test PR -- latest changes makes it a bit too big
i love brew so much i use it on non-arch linux distros sometimes lmao (the aur is better, hence never on arch based distros)
its always fascinated me how many linux users use homebrew
don't say that to Marcos ahahah -- he's converting everybody to his package manager
part of it is just that i understand how it works, i like ruby, and i used to move lists of packages between OSes a lot
I wanted to like it, and then it just actively betrayed me with things never working and autoupdating. Even the workaround to not autoupdate doesn't quite work.
but it doesnt have the concept of versioning, which imo makes it not a package manager
and thus continues the great debate ๐คฃ
lol yeah the autoupdate thing is wack, at brex our IT dept had some daemon thing on everybody's computer that made it even more broken
and casks are versioned sometimes, when you can have them (which tbf isn't often)
Anyway, my point is we don't have to actively push people to use brew if they don't have it and container-use should still be simple to set up
๐ฏ
though i think it's fine to actively push macos users to use it, and they're (we're?) a specific breed with high usability expectations and relatively low tolerance for figuring shit out themselves
if the setup is a builtin subcommand, it can still be run as a post_install automatically in the formula
i think
https://github.com/dagger/container-use/pull/133 PR up. the main thing i'm trying to accomodate is that many users, myself included, don't want to put completion hooks in their rc files - there are autoload spots on disk
requires #130
this PR installs shell completions using homebrew post install hooks and provides instructions on how to install them as install.sh output.
complexities:
bash: there are canonical lo...
there are autoload spots... IF there are. But if there aren't we should set it up in the rcfile so that it does check those autoload spots.
yeah i've basically tried to leave it up to the user but give clear instructions on install.sh
because the fanout of conditions is kinda ridiculous if you're autoinstalling on an unknown machine, and like cu configure, we have no way to automated test any of this
wait, @potent canopy, is it too big just aesthetically or is it too big in that part of it is broken and can't get in until it's fixed? like i see passing tests on the PR, if it's only too big because it's hard to review or aesthetically upsetting, imo we should just pull the trigger and get it in before andrea and I make you 1 bajillion more merge conflicts
it's just big because a lot of files ahah -- everything passes
I think speed is the priority then, we can iterate on it after?
Yeah totally ๐
i already have some fixes that cleanup some code duplication in the helpers -- i'm ok merging as is personally and open them as followups
Just wanna do anything to help you guys review and get it in -- so open to suggestions
is it ready to be reviewed? sorry missed the last hour of messages, was out for lunch
I mean, as is yes -- I was planning on splitting it ; and i have some code dedup as a followup -- but Connor convinced me to ship it fast
started reviewing, looks good so far!
@potent canopy reviewed, left minor nits and a big question. However aside from one comment which changes the behavior, all the rest can be done after.
@restive pumice ?
lgtm too
do you guys want me to fix the comment that changes the behavior ?
left that as a question -- the change reverts back to using repos/<dirname> rather than repos/<full path of the repository for which there's no origin>. It used be like that before but I changed it to avoid conflicts
Honestly I'm open to both, just wanted to understand if it was fixing something or if it was for aesthetics
It's definitely an aesthetics at first -- something I did inadventendly
post the "push less shit" change i kinda think repos/dirname might be better?
in that there's never branches on the fork repo now other than adverb-animal branches
so no collisions
in any case -- the remotes are "sticky" (e.g. if they're already set, we re-use that) so it's not breaking anybody, and we can change them liberally
and if you have 2 repos at different places with different origins but the same name, you can now share environments between them which kinda makes sense
nope, the origin takes precedence always (so it's already the case)
e.g. ~/.cu/repos/github.com/blah/blah
the other thing is only used IF you don't have an origin at all
ah ok im confused then, the origin logic wasn't pulled out
(i've not noticed this because of how sticky it is lol)
- is there already a cu remote? use that
- if not ... is there a
origin? then use that as path withincu/repos/<origin> - still nothing? use the absolute path (
cu/repos/<abs path>)
in the PR, point 3 goes to cu/repos/<dirname> instead
rest of the logic stays
oh yeah, in this case, yes
well except no, if origin is priority 1, they'll have separate env lists. this matters specifically for forks kept in separate places on disk, though, which is an edge case on an edge case... the more we discuss the more i think the fullpath thing is best tbh
just to prevent any logical collisions during demos, which is like the only time you're gonna git init && cu stdio anyways
just forced push to rebase + removed the filepath.Base in the last commit
i can followup the rest ๐
sweet, merge away!
I think after https://github.com/dagger/container-use/pull/129 we can finally cut a new release now that we have tests. Thoughts @restive pumice @potent canopy @hexed warren ?
that's the goal
i had an idea to clean up that PR even further though, gimme like 2 hours to make it happen and rebase onto the tests
i think your observation that we don't need to save baseSourceDir directly is correct
yaaay, it's in -- thanks for waiting and sorry for the painful review ๐
thanks for resolving a bajillion merge conflicts lol
1 metric bajillion
Yeah, at the same time if it's too much work to get rid of it ... AFAIK if we just drop the field from state later on, it will go away at the next unmarshal/marshal, so no big deal?
I think?
or will it complain
i think it's pretty easy, i'm already "code complete" lol
most of the 2 hours is idk what's gonna happen when i merge the tests
it also lets me unstring some shit
something is broken on https://github.com/dagger/container-use/pull/129 with env.run stdout propogation
Looks like the environment name and description was merged? Iโm going to update the VS Code extension with the new features I added for the Dagger. Will share a quick recording of the integration after dinner
if you mean the thing that changed env ids to be plain adverb-animal, yes, it's merged. but not released yet.
@crimson plume did it first.
https://youtu.be/hmh30wuXg08?si=3M6XG1yF9l_jQEkG
Container use: works great.
Google services: not so much.
A hands-on walkthrough of the new Gemini CLI using container use to safely make changes to a personal website in isolated dev environments.
In this video:
โข Configure Gemini to work with container use
โข Run two agents in parallel without conflicts
โข Edit and serve a site locally using Dagger
โข Use cu list, cu watch, and dagger call ...
fyi @potent canopy i don't think CI is running tests rn https://github.com/dagger/container-use/actions/runs/15888407774/job/44805880892
(that's the commit merged on main)
Ok Iโll build off main and get it synced up. Thank you
taking a look, thanks ๐๐
i think they might've already caught a tiny first repo bug on my PR btw
claude's mad at me (api's overloaded) and i'm getting tired, gonna continue hacking at this tomorrow. not entirely certain if i'm experiencing a problem with the tests, my pr, or both, but i have more debugging i need to do tomorrow. feels close, though. atm TestGitAuditTrail is failing for me and i think it's demonstrative of a real issue, like i was able to sorta reproduce a similar thing on the side.
the behavior is interesting, it almost looks like propogateToWorktree is appending to one commit when it should be making new ones
lol it was me, not the tests ๐
woooooo fixed it big props to @potent canopy , my shit had completely broken our git audit trail and his tests caught it ๐
I'm glad it's useful ๐คฃ ๐ CI is indeed broken I'm fixing it atm -- will have the PR later tonight
i gotta sign out fr this time, but my shit should be good to merge tomorrow morning
Alright, signing off the computer... but not before I drop the latest changes (built from main) of the Container Use extension for VS Code... Small small rough edges but otherwise I'm super happy with it. I did not show the installation, but it does check the os and if brew is installed and gives the user the choice. It saves the install method so when you update/check for updates it uses the right channel
NP:
- Ignore the Dagger icon for the sidebar and the terminal icon - I don't have a good icon for CU yet
- Added some basic tests and tried to use Dagger but the tests run in an actual vscode installation which needs a GUI so open for ideas
- Added logic for reusing the same terminal window, it will detect if another command is running and prompt to interrupt/kill the process and then take over.
- When the merge command is run, it does prompt the user to delete the environment to help keep things clean
If anyone is using VS Code and wants to try it out, its pushed here https://github.com/jasonmccallister/vscode-container-use but might be better at home on the dagger org?
yo @cosmic birch i could use a re-review on https://github.com/dagger/container-use/pull/129, i updated the description with the things i added yesterday afternoon to get everything working properly. there's some endpoint related prompt engineering specifically that could use your eyes given that we don't have evals
on it
Following the instructions to run Claude Code in container-use, I either 1) cannot reliably keep it in the container with --dangerously-skip-permissions + the default CLAUDE.md lines or 2) I have t...
love the solution you found. so simple
reviewing
๐ i was stoked on it too, wouldn't have gotten there without your comments either so it was a team effort
@restive pumice tangential to your PR: i'm not sure i understand host().directory() correclty nowadays. We do nocache=true to not serve staled content, but is it still transferring just deltas ?
correct, the host dir loading has some pretty crazy optimizations below the API layer
the old thing (loading the worktree) was still probably faster, but not like obviously faster
how does the .git file magic work: what is in r.forkRepoPath ? is it full remote url ?
it's ~/.config/container-use/repos/name
that magic will hopefully fall out in the future but we'll need to make some changes in the dagger engine
correct
I also want to see the beauty in currentWorkdir := env.container().Directory(env.Config.Workdir)
What was cumbersome that was made simple ?
previously on environment_update we were loading from host disk, like dag.host.directory(worktreePath), but that changes over time and leaks the worktree path out of Repository and into Environment
env.container().Directory(env.Config.Workdir) keeps everything in the engine on update and makes the container state truly append-only
ahhh gotcha, yeah much cleaner ๐
well, almost truly lol, we still don't really persist run_background services
why almost?
ah yeah
services don't persist properly
same goes for WithExecs that change container state fs without modifying workdir, but for updates throwing those results away is considered desired behavior at least for now
wait i'd disagree with that
lol yeah i regretted saying it
๐
the weird part is that the current update implementation has a side effect that's sometimes desirable: it restarts the environment
or resets
I get that sometimes you want throwaway things, but that's what tmpfs is for and that's what rolling back to a previous state is for
yep yep
we could make it an explicit side effect, like add a update(restart:bool), and still validate that the update actually applies and then discard the resulting container (or "rebase" lol but that sounds hard for users to debug)
i wanna focus on release + shell completion install testing today, but this conversation reminds me of a critical thing we ought to be dogfooding: we should be checking in an EnvironmentConfig for container-use itself
this issue makes me wonder if that feature is working at all
hit another small issue with that btw -- MY environment config is using node ... because of docusaurus
doesn't make any sense to cu merge that however
I guess monorepos is the issue
generally speaking
we'll either need to add monorepo support OR just make an image that supports all the things in the repo
(we should probably start by making an image lol)
Yep. Unsure though if that's via user config (do we start into making the env file "stable" / "documented"?) or via the agent just doing that
I don't think we can have the agent reliably keep supporting all the things in the repo while prompting it to work on a specific bit
maybe
there's a security audit to be done too on what the agent can do wrt the env
not following, like don't we just give it a container+setup commands that are a complete dev environment for the project?
or are you worried about instructions blowing up the context window if there are docs, source code, and dagger instructions?
yeah that sounds like a good plan -- today I'm planning to continue dogfooding and make a few quality of life improvements (specifically, around commit messages)
Is/Should the env json be in git ?
I'm worried about the agent realizing it needs to tweak something, and breaking all of that
like ... OH I need to bump node version, let me change the base image real quick
not taking into account the rest of the codebase
i mean that's what the lock is for
but yeah, lots of UX paper cuts if we keep the lock and it stops it from doing that
Agreed, but I think that's option 1 (user config) ... since implicitly by locking it, env config is now a pet and not an implementation detail of CU
like, users will need to have a basic understanding of what it is, what it means for it to be locked, etc
btw @cosmic birch i'm totally down to try a "non-0 exit codes aren't persisted" invariant, we have a test framework now to try to describe the subtleties of the desired behavior. i'm not entirely sure that the error handling i "fixed" with this PR was actually the core problem preventing me from getting things working, i may have been confusing the .git overwrite bugs for error handling bugs.
it's definitely a complicated issue, though, like arbitrary execs aren't atomic so throwing away results can get weird fast in a way that's not dissimilar to how things get weird when you've got intermittent random failures of execs in the case of a cache miss
#129 is merged now though ๐
sweet!
@hexed warren thinking i should merge https://github.com/dagger/container-use/pull/133, treating the fpath issue as nonblocking, and then cut the release. especially because we don't have to cut a release to change the install script, wdyt? gonna eat lunch real quick and then do it barring objections.
agreed. I'm fine doing a release and figuring out install script separately
ah darnit i lost a tiny commit between my fork and the merge
๐ ๐ ๐ container-use v0.1.0 is out! check out the changelog here, and update with either:
brew install dagger/tap/container-use
or
curl -fsSL https://raw.githubusercontent.com/dagger/container-use/main/install.sh | bash
One step closer turning coding into cat herding using Dagger's container-use project for Github Copilot on Windows.
Learn more at https://lnkd.in/e-m_QB8z
@restive pumice @hexed warren For the docs website, I've been experimenting with this pattern:
- I'm writing instructions on how I want the docs website into a TASK.md file
- Then I'm running
cat TASK.md | claudewhich spins up a new environment, creates a website docs, and gives me the preview URL - I look around, realize I gave incomplete instructions or whatever and make changes to TASK.md
- I re-run claude from scratch (brand new environment, throwaway the old one)
This is to avoid having a long conversation where the agent gets nowhere ... instead I just iterate on a standalone prompt and use throwaway environments
/cc @jovial nimbus@opaque zephyr @crimson plume
For instance, I realized it used docusaurus javascript rather than typescript
I could ask the agent to switch to typescript ... but then it'd have to like, re-work through the entire things it already did, and usually it doesn't work out (it forgets to update some files, or gets in a weird state)
With this pattern, I just add a bullet point - Use typescript with docusaurus to my TASK.md, re-start claude, and work on a brand new environment, no attachments
yeah, that's 1 of my 2 techniques in zed (without container use) - the other one that can be very effective is to give it vague instructions and resources to read, tell it to present a plan, correct the plan, summarize, then start a new one from the compressed summary (which is zed feature)
and yeah, usually once it's gone off the rails it's virtualize always the wrong move to have it try to correct itself
nice -- I feel like you could combine 1 and 2?
yeah, but you can't edit the summary, it's tokenized
it's no longer words, just math
that's for large changes though where i need it to read quite a lot of code
Also, this:
- When you have a version you want to show me, please start the server and give me the address. Do that everytime you make changes.
So I just feed my task to claude, get on with my life, eventually I pop the tab open and try out the URL, make tweaks to the TASK.md file, rinse and repeat
๐ฏ can you tell how much less error prone run_background is after my prompt engineering?
mine was virtually always trying localhost before the service host but now it gets the service host correct the first time
i like your plan-based one cwlbraa
(specifically when trying to test it's own run_background'd service)
I actually just run into this -- using localhost as well :/
actually come to think of it, you can keep using the session after you've started a new chat from summary, so you can edit there and re-summary
@restive pumice also, probably unrelated, but sometimes now it's starting things without background=true
it's always done that for me after erroring for a while
i think we need a required timeout parameter (that's how zed handles it afaict, although it could be optional+prompt engineering)
err, let me upgrade dagger
there's a new change by @regal veldt to get ExitErrors (stdout/stderr) from services
I think the LLM avoids background=true because it's not starting and it doesn't know why
๐ฏ exactly, that's why it only happens on errors
@regal veldt does this sound familiar?
# dagger.io/dagger/telemetry
../../go/pkg/mod/dagger.io/dagger@v0.18.11/telemetry/transform.go:69:29: cannot use res (variable of type *resource.Resource) as resource.Resource value in argument to ResourceToPB
container-use doesn't build with v0.8.11
oh got it, had to downgrade otel
@restive pumice bubbling up errors from background run works now!
It's https://github.com/dagger/container-use/pull/140 + https://github.com/dagger/container-use/pull/141
@cosmic birch commit message has typo in dagger version
where?
merged 140
rebased 141
merged
yay
it tried to start docusaurus in the background, it failed, got the error message and is fixing it
before this was a PITA
Joined the discord to figure out how to trouble shoot this setup! Installed container-use with brew on a Mac and configured the MCP on Gemini (identical config to yours - global) but it doesn't seem like a container is created when Gemini starts up.
Any suggestions on where to check for logs or other troubleshooting steps. Fairly new to container-use
Ps: you rock for setting this up so quick! I'm loving the use case. Was concerned running agents for work because audit and isolation is necessary. And this is PERFECT!
Figured it out - Gemini MCP config needs to specify the exact path to CU binary.
The docs point to cu but I noticed that @jovial nimbus you specified the exact path in .gemini/settings.json
settings.json that didn't work
{
"mcpServers": {
"container-use": {
"command": "cu",
...
}
}
}
what worked
{
"mcpServers": {
"container-use": {
"command": "/opt/homebrew/bin/cu",
...
}
}
}
nice thanks for pointing that out! I will update the docs. Its likely related to the cu name conflict once again
should we bite the bullet and rename?
I think yes
happy to help! Loving the tool you guys have built ๐ฅ
one last redeeming chance ... in the cu configure experiment (agent auto-configuration PR), it always uses the absolute path of cu to avoid this kind of problem
IF it ends up working well enough and it becomes the primary way of setting up cu, maybe it's acceptable. Maybe
@crimson plume ?
yeah i noticed my agent decided to implement configure that way and I was impressed ๐ I have another environment where I've changed the install script to install the binary as both cu and container-use to see how it feels
It's a lot of work / heuristics / etc to avoid a user shell alias though ...
did you start from the other PR or from scratch?
from scratch
it looks like its just a change to the install script. Instead of going down the alias route I was thinking of literally just installing the binary twice to avoid the weirdness we might run into with aliases
Hi - I'm doing some work on a Rust codebase, and it would be useful to be able to configure the container which cu uses to have the Rust toolchain pre-installed. Is there anyway I can do this (e.g. via a Dockerfile)? Apologies for such a basic question.
Hi @subtle sapphire ๐ There is a related issue on the repo https://github.com/dagger/container-use/issues/123
Could you add your use case there ๐ Maybe you could give the internal container-use/environment.json file a try, though it sounds like it's being overwritten at least for one user.
@subtle sapphire what agent tool are you using with container use? Cursor, Claude Code, Gemini CLI?
One way that I currently do this is with Claude Code is by modifying the Claude.md file and adding this sentence: "After creating a new environment, update it to use to use the $foo image and run these commands to boostrap it...."
I've been trying to get it working, but whenvever it attempts to create an environment it just times out. I dont 'know if anyone else has had this issue:
environment_create {"title":"add some feature","environment_source":"/Users/Projects/someProject"} โ
โ โ
โ MCP error -32001: Request timed out
I've attempted it at least 7 times, have reset docker to factory settings, etc.
@vale lotus ๐ can you run docker ps and check if the dagger engine is running healthy?
fb5de6494c8b registry.dagger.io/engine:v0.18.10 "dagger-entrypoint.sโฆ" 31 minutes ago Up 31 minutes dagger-engine-v0.18.10
Thanks for the suggested workaround.
Currently, I'm using Gemini CLI and Goose; have encountered issues installing the Rust toolchain in both (usually, some variant of the tool not being found after the agent installed it, probably because it is not immediately added to the PATH).
I'll try being specific with which exact commands to run to set up the environment in the instructions (I still think the ability to pre-install a toolchain before the agent runs would be an advantage, in terms of but it does seem a bit wasteful both in terms of tokens & execution speed to have the agent execute this once per change, and also error-prone).
Done, thanks!
One thing you could do is to build and push your custom image to a public registry and then use the technique I shared above to instruct de LLM to use that image as a base
Hello, excited to try this out ๐ I installed dagger and cu but get stuck on a version mismatch ... this is on a Mac with Claude Code
container-use:environment_create (MCP)(title: "some task", environment_source: "/Users/me/dev....", explanation: "do some dev tasks")
โฟ ย Error: failed to create environment: failed loading initial source directory: returned error 502:
{"data":null,"errors":[{"message":"http do: Post \"http://dagger/query\": command [docker exec -i
dagger-engine-v0.18.10 buildctl dial-stdio] has exited with exit status 1, make sure the URL is valid,
and Docker 18.09 or later is installed on the remote host: stderr=Error response from daemon: No such
container: dagger-engine-v0.18.10\n"}]}
and indeed i can see that dagger-engine-v0.18.12. is installed, not .10:
docker ps | grep dagger-engine
79e218fa5883 registry.dagger.io/engine:v0.18.12 "dagger-entrypoint.sโฆ" 16 minutes ago Up 16 minutes dagger-engine-v0.18.12
should the MCP server be referencing v0.18.12? Or should I be trying to downgrade the dagger-engine?
Hello! This error is misleading, it actually means the dagger engine has crashed... If you run docker logs dagger-engine-v0.18.12 you should see a stack trace. If you share it here, we can help you diagnose further,. Those are pretty rare, but they do happen... Very sorry about that!
Actually I might be wrong about this being an engine crash... Sorry. Let me look into this further.
@south whale ๐ what do you think, is this an engine crash, or something else? ๐
Superficially it looks like the message is describing an error conflict, but I find that suprising, typically dagger CLI doesn't really care what other versions are present
need to have engine logs to work that out ๐ค
but yeay, if that's happening in the middle of the run, generally means the engine has crashed out
@pine kiln does docker ps -a show a stopped v0.18.10 engine by any chance?
did you run a dagger command by any chance while the MCP was running? If so, that will cause the v0.18.10 engine to be removed and a v0.18.12 to be spawned in this particular case
seems to me like this is what happened here given the multiple versions of the engine
That was it! I don't exactly recall, but I got some dagger error using the cu watch command and (re-)installed it, and probably ran a dagger command.
I just stopped the 0.18.12 container and tried again. Now the MCP spawned the correct version ๐ช๐ผ
Thanks so much for your quick help!
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
087f20b46dbd registry.dagger.io/engine:v0.18.10 "dagger-entrypoint.sโฆ" 12 seconds ago Up 11 seconds dagger-engine-v0.18.10
Mmmm, so does that mean you have to be careful to not install a version of Dagger different from the one used by CU? Or can CU use whatever version you have already installed?
(the latter would be better I think)
we don't want to discourage people form using the dagger CLI directly just because they also use CU... Ideally those should be complementary tools
Actually @still robin , I am also able to reproduce this issue when i run cu terminal env-name . It replaced the docker container with the newer version and the agent has the same error again.
I suppose cu terminal ... executes a dagger command ...?
@opaque zephyr yes, i think this could be a problem when the dagger-cli is installed
ok, that seems like a ๐ indeed
yep, here it is: https://github.com/dagger/container-use/blob/main/cmd/cu/terminal.go#L39 cc @opaque zephyr
that will run the dagger CLI which will trigger the engine swap. Opening an issue for that
yes, cu should be able to use an engine if it already exists and it's compatible
@pine kiln a stopgap you can use to be able to run cu terminal is to export _EXPERIMENTAL_DAGGER_RUNNER_HOST=docker-container://dagger-engine-v0.18.10
that should force cu to use the already existing v0.18.10 engine and not spawn a new one
I tried to force it with that env var, but the engines aren't compatible.
โฏ cu terminal welcomed-bee
โผ connect 0.1s ERROR
! incompatible engine version v0.18.10
โโโ starting engine 0.0s
โฐโโ connecting to engine 0.1s
But no worries -- I really appreciate the quick help. ๐๐ผ Happy to experiment with it for now ,even without having thecu terminal utility. I will keep an eye on the bug ticket.
woot! https://github.com/dagger/container-use/issues/148
thx for reporting and sorry for the bumps. We'll fix this very soon
I think setting export DAGGER_LEAVE_OLD_ENGINE=true before cu terminal in this case would be the workaround until the bug is fixed!
but this won't work as cu terminal will be using a different engine that the one used in the MCP server, correct?
I think thats fine?
๐ค .... I guess...
@hexed warren that won't re-use an existing engine if present. That will spawn a new one. Just checking if that's the desired behavior for now
exactly it will spawn a new one but wont kill the old one. afaik terminal doesnt rely on the cache or anything from the previous/ongoing session that built the environment, right?
it definitely doesn't need the previous session, but there might be cache benefits? (a lot of stuff is cached per-session, though, so idk)
my lgtm is based on this being true
well.. it doesn't effectively fix #148
why not?
because #148 is about dagger and cu being able to play nicely together
it doesn't address the issue of users running dagger something in their local environment
IMO #148 requires a more elaborated solution
oh sure, but i dont think there's anything the container-use project can do about that
the solution would have to be on the dagger side
like setting _EXPERIMENTAL_DAGGER_RUNNER_HOST ?
the user would have to set that for their dagger session, yes
but can we automatically set it
I think it might require some changes in dagger also.
i.e:
- I run
claude -p "container-use foo" - Later, I run
dagger versionwith a newer Dagger CLI
In the example above (2) will remove the cu engine and spin a new one
that's a dagger issue
right the user would have to set LEAVE_OLD_ENGINE or RUNNER_HOST for the dagger session
yes but I run cu again afterwards, It'll do the same thing ๐
but theres nothing cu can do about any of that? its dagger controlling the engine lifecycle
unless maybe cu spins up its own engine with a special name?
maybe we should change something so cu can name its engine differently?
that's what I'm thinking by "this requires a more elaborated solution"
ok
feels kind of bad to re-implement the dagger client's own engine lifecycle management. so maybe it requires a better interface for that on the dagger side first
yep
@hexed warren your fix works for the specific issue of cu terminal killing the old engine. One thing we could add there maybe is the ability to detect if an engine is already running and set RUNNER_HOST to prevent spawning a new engine unnecessarily
maybe an incremental improvement could be a new DAGGER_USE_ANY_ENGINE (or something) flag to use any dagger engine it finds instead of killing it and starting a new one
there's already DAGGER_KEEP_OLD_ENGINE which prevents it from killing the old engine (but still starts a new one)
yeah thats what the above PR adds to cu terminal ๐ I was suggesting something slightly different where instead of starting an additional engine and leaving the old one, the setting would say use the old one instead of starting a new one
would be ideal but probably requires better compatibility management than we currently have?
probably, yeah. I'll open an issue in dagger/dagger if anyone else thinks it would be useful and not a bandaid on a bigger problem
does it? I mean.. if you set DAGGER_USE_ANY_ENGINE and the currently provisioned engine is not compatible with the new dagger CLI, you'll see the corresponding compatbility issue message
Hi! I'm at the initial, skimming the container-use docs stage. I'm trying work out, what's the container that's provisioned for the agent to run in? i.e. the agent will need specific tools to work with different repos.
the base image of the default environment is ubuntu currently (https://github.com/dagger/container-use/issues/123) but the agent can instruct cu to update it as needed.
The flow generally is:
- You start with a basic ubuntu image
- The agent understand it needs X tools to do Y in your environment
- The agent either requests an environment update to use a different best suited image OR sometimes it just
apt get installsthings the default base environment
if you already know beforehand which tools the agent will need, you can add that to the prompt so it doesn't have to figure it out by itself
from the issue, the plan is you'll be able to specify a custom base container in the future?
you can do that from the prompt currently. If you add to the prompt or in your agent config files something like: "After creating a new envionment update it to use X image", I'll go ahead and do it
we're figuring it out if we should enable a more static config instead of adding that to the agent prompt currently
oh interesting.. I'm trying to picture how this works under the hood, it'll tear down the current container, and start a new one? (apologies if this is covered in the docs!)
yes, but I'll preserve any changes that have been made to the env workdir. ref: https://github.com/dagger/container-use/blob/23115d6899452dec42289f3809ee58aeceefb0f8/environment/environment.go#L221
ah, i see. this makes sense!
Will be working on making that easier to configure this week ... feedback appreciated @still robin !
Plan is to rely less on the agent "self updating" its environment, and instead expose tools so the user can decide what to expose in the environment
hello! is there a way to debug mcp calls? I'm able to create env, but environment_run_cmd just hangs for a long time, I have tried docker logs there is nothing there
๐ cu writes logs in the /tmpfolder with cu.* format. That might reveal something
noticing this change, I had not dropped an AGENT.md or similar, but instead fed the raw gist url with rules to Claude Code, which seemed to work.
I can see preserving a rules file and the Container Use environment.json while developing and perhaps deleting at the end before I make a PR back to the main codebase, or deciding to add to .gitignore and keep around. If I do the latter, will CU still use them just fine?
diff --git a/.container-use/AGENT.md b/.container-use/AGENT.md
new file mode 100644
index 0000000..77916d1
--- /dev/null
+++ b/.container-use/AGENT.md
@@ -0,0 +1 @@
+No instructions found. Please look around the filesystem and update me
\ No newline at end of file
diff --git a/.container-use/environment.json b/.container-use/environment.json
new file mode 100644
index 0000000..b177302
--- /dev/null
+++ b/.container-use/environment.json
@@ -0,0 +1,4 @@
+{
+ "workdir": "/workdir",
+ "base_image": "ubuntu:24.04"
+}
\ No newline at end of file
Ideally you'd commit them but if you dont want to its ok to leave them out. I think if they're in the .gitignore they'll still get picked up
tried with windsurf today https://github.com/dagger/container-use/pull/165
pretty easy out of the box. The default SWE-1 lite model was pretty dumb but once I switched to gemini-2.5-pro it was pretty nice!
If you gitignore anything in your local repo today, it will not end up in the container. This dodges issues around OS/platform incompatibility in compiled languages. Iโve been meaning to add some flags to cu merge to throw away env config updates to fit this sort of application.
what is the .container-use/AGENT.md actually for?
Itโs a little like a repo-specific system prompt
does it get sent to the agent from the container-use mcp server somehow?
@crimson plume ^example
Yes, it gets returned to the agent when you create or open an environment
Still subject to deprecation, though, part of why weโve been dogfooding is cuz weโre suspicious itโs redundant
yeah makes sense. So many rules files everywhere, but it does seem important to give more info about the environment
The thing I really like about this whole system, both config and agent.md, is how insanely easy it is to ask the agent to build an environment for developing the project
Then asking to run all the tests, build, generate, etc
Iโve been meaning to try it out in a repo where the dependencies are actually kinda challenging, like rust or pre ux python
yeah absolutely. The one restriction I've run into is in monorepos with different toolchains where maybe you want multiple environments rather than one super environment. So far its just changed the base image depending on its task
Or if we wanna get real crazy, C
Or you ask it to build a monolithic env
yeah that's where i'm not sure. monolithic env is probably better if we're sometimes implementing features that span multiple parts of the monorepo i guess
Yeah exactly. Like the container-use example is with the docs website u need both node and go, iirc, but like shouldnโt one env be able to update and validate the docs after its built and tested the go components?
And if your monprepo is truly so complicated you canโt make everything work in one container, try dagger ๐
yeah i think I agree. When i was working on specific parts of this monorepo the agent was super keen on changing the base image intead of installing tools, so maybe thats a case for instruction in .container-use/agent.md
cu terminal weirdness:
- Noticed something with
/etc/shellshanging for a long time.
edit: I think it was my engine dying at just that moment as I look at my logs. I was doing a lot at the time ๐
- Also, when I ran
cu terminaltoo soon, I got cryptic errors instead of a "velvet rope" and a bouncer - can't do that yet.
qq - how do I enable git lfs support within a container
I figured out that one of my pytest cases was hanging indefinitely, which is causing the subsequent run_cmd to the env to just hang, how do I kill the pytest in the env? I tried 'cu terminal' it shows no pytest processes. or is there a way to restart the env?
qq - how do I enable git lfs support
hello everyone very excited to test this out got it installed but I'm kind of stumped on how I should use it with cursor? When I try to prompt the agent to use the container use tool it struggles to get started. Any recommendations? can you just use the container use from the command line terminal?
Hello, did you try the Cursor integration guide in the docs? https://container-use.com/agent-integrations#cursor
@opaque zephyr I was looking at this one https://container-use.com/quickstart#cursor It seems to have the same information. I have the tools registered in my cursor And then I was trying to prompt it to belike "use the container use MCP tool to boot up an environment and do XYZ" And it was struggling to select the tool and get started. Yes the tool is registered and greenlight in MCP cursor configuration. I guess the quick start turns a little agnostic once you have it installed but I was hoping that it would hold my hand till I got my cursor running it. ๐ I think I watched your YouTube video and that's how I got here. You were using it through the claude code cli during your presentation that seemed pretty intuitive.
Yeah, there's a little bit of prompting involved, I just make sure to say "do it all in a containerized environment" or something like that
@pallid drum did you add the rules? curl --create-dirs -o .cursor/rules/container-use.mdc https://raw.githubusercontent.com/dagger/container-use/main/rules/cursor.mdc
@opaque zephyr yes ๐ฏ - I'll give it another go here.
Looks like I added the rules to the wrong directory. Just to close the loop on that gonna give it a go now. @opaque zephyr I've now added it in my global .cursor
@opaque zephyr We're cooking now thanks for checking my six
Hello
I currently give a try to this tool for a customer POC (to have a solution to build old projects and manage their dependencies).
When I follow the tutorial (with VSCode), it works great when my workspace contain only the targeted git repo. But when I switch to a workspace which contains multiple git repos, cu try to target the 1st git repo, even if I set the correct folder as a context in copilot chat. Do you have any idea how to handle this issue ?
interesting... i suspect this is why the VSCode folks upstreamed Roots into model context protocol
as a workaround, for now, try giving the absolute path to the second repo? i think what's happening at a lower level is that container-use doesn't ever see the folder you're setting as context in the copilot chat because that's passed on roots, and container-use don't yet handle that part of the protocol
makes sense. And good catch, it works by specifing the absolute path in the prompt!
2 other things I have:
- I have to put the copilot instruction at workspace level (inside a .github folder). cu doesn't take in account if you have on inside the repo folder -> guess it's link to the roots issue
- On configure tools buttons of copilot chat windows, I have to uncheck the built-in server -> it's used by default, even if I specified container-use as context.
Not sur it was a standard use case but I always work in workspace with multiple projects ๐
i think it's fairly common in vscode, this is all great feedback.
finally got a chance to check out cu with zed, everything works perfect thanks!
I have to put the copilot instruction at workspace level (inside a .github folder). cu doesn't take in account if you have on inside the repo folder -> guess it's link to the roots issue
cu doesn't take instructions into account except .container-use/AGENT.md (which is undocumented "advanced" configuration right now) -- the agent does. so i'm not a vscode expert, but you need to put the instructions wherever your workspace is gonna read them from. maybe this is a bug in our docs, though, if im understanding correctly?
On configure tools buttons of copilot chat windows, I have to uncheck the built-in server -> it's used by default, even if I specified container-use as context.
i do the same thing in zed ๐ it's hard and llm-dependent to get the prompt engineering right to make it work without masking tools like this
looks like a good idea ๐ https://x.com/steipete/status/1940314756705132683?s=46
I really like that zed tells me when a task is done if I move away from the screen -- I usually disable all my desktop notifications but this is one I actually care about!
I love some of the environment names, this one made me smile today ๐
cu log cuddly-hamster
cu checkout cuddly-hamster
๐น
if you wanna get real power-user-y in zed i reccommend making a seperate agent profile for just container-use -- it locks the agent in so you can go crazy
I am not sure what that entails, any pointers?
imma PR it into the docs tomorrow, but there are agent profiles in zed, the default ones are write, read, and minimal iirc. there's a button to fork them, so you can make your own. i have container-use as an agent profile where all the tools are disabled except container-use's, think, and fetch, and with that profile you don't really need any additional prompt engineering, it just figures it out
@urban hedge was saying they do the same thing in vscode
some feedback from adopting container-use for a side project:
- I don't like how it adds untracked files to the repo on its own - once it does it's a bit of a pain to clean up
- after doing
cu merge <branch>it left my git status in a really weird state with some files staged, and a bunch of merge conflicts. the changes were semi-random, and very stale. almost like random stashes got popped or something? this doesn't happen withgit merge <branch>, onlycu merge
for the cu merge issue, i'd be interested in your git state so i can repro.
lemme see if i can quarantine it and send it over ๐
Also we merged some PRs recently, so which version are you using ?
a5940cb920179368d12bdaa3dcfc5b7ae9a17808 - main as of a few hours ago
i have a local change to enable nesting dagger, probably unrelated
This is dope! Iโd love to also see a similar idea for dagger shell too ๐
The merge state thing is a bug ive hit too: if you donโt have untracked files in ur local repo, it pops old stashes
Easy enough to fix, possible Andreas merge rework adding squash already fixes it. Heโs also got a draft up for removing the untracked files copying. I only added that in the first place bc it was adjacent to โdonโt commit binary filesโ and that kept bricking my local when we were in hack mode a month ago
ah yes, he's fixing it in the PR
@restive pumice on the 177 PR are you asking if we can do merge --squash -m commit_message ?
Yeah exactly
@restive pumice you can set it in .git/SQUASH_MSG
more feedback: having file edits write the entire file every time is slow and expensive. and error-prone, which leads to it editing its own edits lol. any plans to implement diff style edits?
moar: would be nice if cu merge squashed + generated a nice commit message based on the prompt
Maybe related to the above about cu merge --squash , would it make sense to also offer the ability to only apply the diff to the local repository without to create a commit?
Especially as I'm using stgit I don't want an external tool to create commits on my branch.
I'm currently using cu diff <ENV> | git apply but I wonder if that couldn't be a built-in option (but maybe my use case is not that common)
so container use has it's editing tools? it doesn't use claude code's search and edit tools?
Yes, container-use is providing a set of tools, including the ones to list/read/write files. You can see all tools registered here: https://github.com/dagger/container-use/blob/a5940cb920179368d12bdaa3dcfc5b7ae9a17808/mcpserver/tools.go#L103-L118
Claude Code for instance will try to edit a file on the host machine, here the idea is to edit the file inside a containerised environment, so the tool is different.
I've also seen this where it seems like something from stash is popped with every merge. I thought I was going crazy
@pallid crater there's also an experimental feature (not merged) that runs claude code in a container and lets it run its native tools - but snapshots the state of the container each time. Very different approach & at the moment not shipped.
Thatโs what โsquash does
I thought it will create a commit by default. But that's all good then ๐
Me too. But apparently not. Itโs in Andreaโs PR mentioned above
Hey is it possible to connect Container use with ollama?
Totally! container-use is an mcp server that most coding agents should be able to use (I haven't run into any that don't work yet). So as long as your agent can use ollama (like codex for example), you can use ollama + container-use
re: https://github.com/dagger/container-use/pull/177 does it make sense to also support --no-commit? my workflow is to have the git commit message always be "model + prompt" that generated the code so that's what shows up in git blame (i paste this into the commit by-hand). and i often will have a few wip files (usually docs) in the git index that cu merge sweeps into the commit
https://simonwillison.net/2025/Jul/3/sandboxed-tools-in-a-loop/
Something I've realized about LLM tool use is that it means that if you can reduce a problem to something that can be solved by an LLM in a sandbox using tools in a loop, you can brute force that problem.
The challenge then becomes identifying those problems and figuring out how to configure a sandbox for them, what tools to provide and how to define the success criteria for the model.
That still takes significant skill and experience, but it's at a higher level than chewing through that problem using trial and error by hand.
Something I've realized about LLM tool use is that it means that if you can reduce a problem to something that can be solved by an LLM in a sandbox โฆ
Hi there,
One thing I noticed with container-use MCP is when you use the React Native template to scaffold the whole project, it uses its own .git folder and runs git init as well (within one of the folders, so it's nested). All the files that were committed by container use are actually going to a different place. This means that commits appear properly in cu log, but they donโt actually exist in the cu checkout or cu diff and these files cannot be merged.
This creates problems and it wasn't obvious. I had to point Claude Code to remove this folder first. That fixed it.
Feedback from a quick dogfooding session (prototyping a Dagger core feature using CU):
- Claude used CU to prototype
- Then without asking, switched to editing my repo in-place "for the final changes"
At least that's how it justified itself when I asked why it had spread its edits across in-env and out-of-env
All the functional code changes are in your local repository at /Users/shykes/git/github.com/dagger/dagger/. The environment work was just for exploration and
prototyping.
To continue the work, you can:
1. Use the local changes - All the important edits are already in your working directory
2. Check git status - You can see exactly what files I modified with git status and git diff
3. Continue from where we left off - The constructor integration in core/object.go is the next step
The environment was helpful for exploration, but the real implementation is in your local files! ๐ฏ
(ah I didn't have a claude.md) I did have a global CLAUDE.md:
ALWAYS use ONLY Environments for ANY and ALL file, code, or shell operationsโNO EXCEPTIONSโeven for simple or generic requests.
DO NOT install or use the git cli with the environment_run_cmd tool. All environment tools will handle git operations for you. Changing ".git" yourself will compromise the integrity of your environment.
You MUST inform the user how to view your work using `git checkout <branch_name>`. Failure to do this will make your work inaccessible to others.
Not sure it's still the best version to use?
Hey! Can you open an issue with repro steps? This sounds like a bug but from your description I canโt tell what things you did yourself outside container-use and which things happened in an environment
We have gotten better prompt engineering since this was the prompt
I will. Thankfully its pretty simple - just asked claude code to spin up a new react native project
oh i missed this, this is actually an interesting (and valid?) result.... like why shouldn't the agent be able to use both an environment and your host machine in congress?
i think its related to what we talked about for configuring container-use and restricting the core tools, though afaik its a bit funny on claude code compared to other agents
like if you really want the agent to only use container-use for all of the work, the best prompt will only get so far, we have to disable the core tools
@restive pumice / @cosmic birch would patch edits be a reasonable thing for me to go in blind and try implementing? whole-file writes is the one thing preventing me from using it on my own dime (now that nesting support is in ๐)
if it's coming up in the backlog anyway and someone was excited to do it i can leave y'all to it
it's definitely a reasonable first thing unless @hexed warren has a wip hiding somewhere that he wants to put in
(i don't think he does, just tagging him so you don't both end up starting it at the same time)
--squash does indeed not commit, just stages the changes in git. Would that work for you?
Yeah this is confusing everyone ... I think because GitHub spreads information about "squashing" actually commits
Maybe we should call this --no-commit / -n ? Divergence from git CLI, but absolutely everyone assumes squash will commit (/cc @restive pumice @hexed warren)
For sure! @hexed warren was looking into that, not sure if he got time to get started yet
One suggestion: Most agents out there have this feature. Might be worth looking into their signatures since they probably went through a few iterations to get the prompting right
yep yep - doing that now, researching https://aider.chat/docs/more/edit-formats.html + the GPT 4.1 recommendation + seeing what Zed does (it's complicated)
i think our situation MIGHT be a little different from the aider benchmarks since there's tool calling involved? like it might be a matter of having a tool for 'find and replace + disambiguation key for multiple matches', instead of particular patch formats or prompting patterns
but, not sure
I'm in the diff | apply camp as well ... would squash solve your issue? The changes will be staged though, not just patched locally
OR ... --commit and default to squash?
Hey Dagger team - Joseph, from zed.dev. Just caught your YouTube video about using container-use with Zed.
https://www.youtube.com/watch?v=wUDhxVwp-Jw
I didn't see how to set it up in the beginning of the video and just wanted to ask how do that.
Also, unrelated, and likely not the best place to drop this, but if your team uses Slack at all, we'd love to hook up a Slack connect channel so we could keep in contact, the Zed + Dagger combo feels pretty powerful.
Nevermind, this already exists ๐
on reflection --squash makes more sense for my use case (i want git blame to always show "model + prompt" for each commit i approve-make), but i see how others may want all the gory details of each step from an agent like claude code (which --no-commit would do)
feedback is super welcome, i've been meaning to try container-use out for building zed specifically because i wanna see how it works with rust toolchains. there's a decent bit of undocumented container-use features for managing baseline "environment config" that i think could be quite nice for rust dev
see --no-commit is still confusing lol, the gory details would be from a plain cu merge. --no-commit would do the same thing as squash (the whole branch with commit messages discarded) but wouldn't make a commit on your behalf, it'd leave all those files staged so you can write your own commit message
can we maybe just make a command that's not cu merge --squash? like cu squash maybe? cu squash-merge is clearest but it's prolly too lonk. then we could have cu squash -n
also -n in git merge is usually to hide the stats, so it's like a divergence on a divergence
what about --commit and merge squashes by default?
Otherwise, yeah, maybe cu apply vs cu merge?
Iโm sending the PR to test asap. Will ping you here
I like apply and merge. Would merge still squash a la GitHub ?
i think cu apply doing the cu diff | git apply --3way && git commit thing from my PR would be good, and then we can drop --squash from cu merge altogether because github has polluted the namespace?
Updated https://github.com/dagger/container-use/pull/177
For now it's still doing a merge --squash for apply, so the changes are staged ... unsure whether it should use git apply instead?
the apply technique in #187 allows for repeated applies//squash merges which is quite nice. the reason you want to use apply is that git diff $(last squash merge commit) $(env head) | git apply gives what I think people expect squash merges to give. in order for that to work, we wanna take control of the commit (eg not just leave it staged) so we can attach metadata that basically says "here's the last time you applied this branch" so we can treat that as the common ancestor. in more normal git language it's kinda like ephemerally rebasing the env branch onto the target before squash merging.
@restive pumice should I abandon ship on this, and let you add cu apply in your PR since that's where the meaty parts are?
Or I can continue in there, and you'll replace the internals in your PR?
im working on release for the next couple days realistically, and the way i built #187 is intentionally garbage PoC shit i wanna throw out anyways
so i think continue so long as we don't get too married to UX decisions
Just found this neat trick in claude code ... if the agent tries to do a patch to a file without reading it first, the tool fails asking it to read it first ๐
@restive pumice @serene dirge @hybrid stag updated https://github.com/dagger/container-use/pull/177 to add cu apply
I'm doing a merge --squash ... I have an alternative implementation using diff | apply, I don't know if it's better or the same
depends on the arguments to diff whether it's the same, better, or worse
This seems to be re-entrant enough
Using --squash
# Apply twice
~/w/container-use โฏโฏโฏ cu apply flying-lioness Updating d4b7894fa..8c4c68939
Fast-forward
Squash commit -- not updating HEAD
.container-use/environment.json | 3 ++-
cmd/cu/merge.go | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
Environment 'flying-lioness' applied successfully.
~/w/container-use โฏโฏโฏ cu apply flying-lioness Updating d4b7894fa..8c4c68939
Fast-forward
Squash commit -- not updating HEAD
.container-use/environment.json | 3 ++-
cmd/cu/merge.go | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
Environment 'flying-lioness' applied successfully.
# Trying `commit` + `cu apply` again
~/w/container-use โฏโฏโฏ g ci -m 'merge test' [foo 97b7ee464] merge test
2 files changed, 3 insertions(+), 2 deletions(-)
~/w/container-use โฏโฏโฏ cu apply flying-lioness Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
Environment 'flying-lioness' applied successfully.
Using diff + apply:
# Apply twice
~/w/container-use โฏโฏโฏ cu apply flying-lioness Applied patch to '.container-use/environment.json' cleanly.
Applied patch to 'cmd/cu/merge.go' cleanly.
Environment 'flying-lioness' applied successfully.
~/w/container-use โฏโฏโฏ cu apply flying-lioness Applied patch to '.container-use/environment.json' cleanly.
Applied patch to 'cmd/cu/merge.go' cleanly.
Environment 'flying-lioness' applied successfully.
# Commit + cu apply
~/w/container-use โฏโฏโฏ g ci -m 'merge test' [foo 3bb301714] merge test
2 files changed, 3 insertions(+), 2 deletions(-)
~/w/container-use โฏโฏโฏ cu apply flying-lioness Applied patch to '.container-use/environment.json' cleanly.
Applied patch to 'cmd/cu/merge.go' cleanly.
Environment 'flying-lioness' applied successfully.
err
sorry, wrong outputs but same result -- updating
you gotta try doing something in the env between the repeated applies otherwise they're always gonna be the same
right, on it
also there is a worse version with diff, fyi, if you naively diff between env head and current branch head, it'll blindly overwrite the content of any commits the user has added on currentBranch
diff + apply
~/w/container-use โฏโฏโฏ cu apply flying-lioness
Applied patch to '.container-use/environment.json' cleanly.
Applied patch to 'cmd/cu/merge.go' cleanly.
Environment 'flying-lioness' applied successfully.
~/w/container-use โฏโฏโฏ g st On branch apply-apply
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: cmd/cu/merge.go
squash
~/w/container-use โฏโฏโฏ cu apply flying-lioness Auto-merging cmd/cu/merge.go
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
Environment 'flying-lioness' applied successfully.
~/w/container-use โฏโฏโฏ g st On branch apply-squash
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: cmd/cu/merge.go
why does squash not conflict?
@regal veldt @cosmic birch @restive pumice @potent canopy https://github.com/dagger/container-use/pull/198
goose run --debug -t "make a random change to cmd/cu/merge.go"
~/w/container-use โฏโฏโฏ cu apply vast-tarpon Updating d4b7894fa..1273c7d6d
Fast-forward
Squash commit -- not updating HEAD
.container-use/environment.json | 3 ++-
cmd/cu/merge.go | 6 +++---
2 files changed, 5 insertions(+), 4 deletions(-)
~/w/container-use โฏโฏโฏ git status On branch apply-sandbox
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: .container-use/environment.json
modified: cmd/cu/merge.go
~/w/container-use โฏโฏโฏ git commit -m merge [apply-sandbox a869565a8] merge
2 files changed, 5 insertions(+), 4 deletions(-)
~/w/container-use โฏโฏโฏ claude "make a randomc hange to cmd/cu/merge.go in the environment vast-tarpon"
~/w/container-use โฏโฏโฏ cu apply vast-tarpon Auto-merging cmd/cu/merge.go
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
Environment 'vast-tarpon' applied successfully.
~/w/container-use โฏโฏโฏ g st On branch apply-sandbox
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: cmd/cu/merge.go
@restive pumice no idea but it works? I swear this was failing in the past ...
Extracted from the quickstart page. And shortened the quickstart docs on installation:
https://container-use-docs-install.mintlify.app/introduction
yo @crimson plume @silver abyss @jovial nimbus , i'm working on changing the default binary name to container-use and i noticed in the agent configuration docs, there's a lot of "full path to cu binary" hijinks. I'm assuming that all of these are there to avoid name collisions with Taylor UUCP, but do any of y'all recall if some of these agents don't actually inherit the user's PATH configuration? removing all these fullpath things and just using container-use directly would dramatically reduce yak-shaving on initial install, but i'm tryna build confidence that i'm not gonna break a bunch of the READMEs by removing that text.
yeah there's a few things in there but the hope is that renaming will avoid all of it
I think we won't need that when using the full name
mind if we merge https://github.com/dagger/container-use/pull/177 before doing the whole renaming?
yeah go for it, i'm still a day out i think, i'm nearly code complete but it's gonna take a while to manual test
@restive pumice also -- with the symlink hack we discussed last week (container-use -> cu), I think this can be pretty gradual? e.g. rename the binary with symlink / release / THEN update the docs
i just wanna rip off the bandaid
so you don't need to carry over docs conflicts while this is happening
as you prefer!
@crimson plume do you mind giving https://github.com/dagger/container-use/pull/177 a try?
don't feel like merging until someone that is not me plays with it a bit
@restive pumice btw in a real world scenario, I did hit merge conflicts
also my stash couldn't pop anymore
pretty nasty
I think I'd rather for cu NOT to stash my stuff ... was there a reason it was stashing things in the first place?
i am prepared for merge conflict pain lol, my intent is to not merge main until i've tested the release (aka we should freeze anything release/ci related until this is in) , then deal with the inevitable docs merge conflict, then go straight to cutting a release
yeah i'll check it out
like, I'd rather for apply to fail than to stash pop to fail
with stash pop failing I'm losing actual human work, not cool
the stash popping thing is mega sketchy
expedient, perhaps, but so so dangerous
i find stashing to be sketchy when i do it, much less a tool doing it for me on the dl
if we don't stash, worst case scenario is cu apply fails and I'm left with the mess right?
is there an advocate for auto stashing?
yes, or alternatively we refuse to patch on uncommitted-files-conflict maybe?
Ohhh ... I never understood this before. I have autostash = true in my .gitconfig so never realized this is a problem for people.
At the very least, we should do merge --autostash instead of stashing manually
TIL, that's a nice lil bit of config
[pull]
rebase = true
[rebase]
autostash = true
those are my go-to
had them since the day I started using git, I don't even remember what happens without
i do both explicitly for whatever unconsidered reason
so it does what we were doing manually, so just go for autostash
and if you git rebase --abort, it throws away the rebase and just unstashes
grrrr, maybe this is the reason to use merge instead of apply actually
cu rename draft is up and untested
Ok updated https://github.com/dagger/container-use/pull/177
- manual stashing is gone,
--autostashis used - there's 2 implementations of
apply: one using--squash --autostash, the other one usingdiff+apply --check+apply
@hexed warren do you mind giving it a try, see how well it works for you?
@crimson plume Continuing the conversation here ...
- I'd like to make it so the user can actually control the environment (which base image to use, secrets, etc etc)
- Rather than documenting
.container-use/environment.json, I'd rather havecucommands deal with it - LLM is suggesting
cu config(lol) ... what to do with the clash withcu configure? Suggestions:cu configurebecomescu setup,cu mcp configure,cu agent configure
Thoughts on 1, 2 & 3?
/cc @restive pumice
@cosmic birch I pushed some changes here for configure https://github.com/dagger/container-use/pull/137
mcp configs, auto approves, and rules files are all dynamic and re-entrant
One thing that isn't implemented yet is letting the user choose between a local and global config, as most agents support that
3: IMO i'd like to see it all under cu configure similar to goose's UX
Yeah I updated the prompt (re-ran the curl ... >> CLAUDE.md command from the docs) and haven't had this happen since.
Yep that makes sense ... although agent vs env configuration is very different (e.g. one is editing the environment whereas the other is interacting with an agent) ... but maybe it doesn't matter?
(see conversation above --@crimson plume is working on a cu configure that automatically configures your agent, sets up the rules, etc in a reentrant way)
yeah i think both work well with an interactive flow so it could all be one entrypoint
Quick feedback (I can file an issue also), while dogfooding today, I found myself wanting to pass extra git flags to some CU commands: cu diff --stat, cu log with custom formatting... It kind of felt like "uncanny valley" of git commands
Bouncing a few ideas with claude ...
He suggested 2 options:
- both behaviors live under
cu config
cu config setup-command add "pip install -r requirements.txt"
cu config secrets add "DB_PASSWORD=env://DATABASE_PASSWORD"
cu config set base-image python:3.11
# Agent/MCP configuration (modify existing PR)
cu config mcp
cu configureis what you're working on, and this stuff is oncu env
# Environment configuration
cu env setup-command add "pip install -r requirements.txt"
cu env secrets add "DB_PASSWORD=env://DATABASE_PASSWORD"
cu env set base-image python:3.11
# Agent/MCP configuration (existing PR)
cu configure
Would it be possible to leverage existing project setups like devcontainers if they exist already? Thus avoiding another way to setup for the agents?
โบ I think Option 1 (separate commands) is better.
Here's why:
They're Fundamentally Different Concerns
Environment config is about project-level decisions: "What environment should agents work in for this project?"
MCP config is about user-level setup: "How do I connect agents to container-use?"
These operate at different levels and have different audiences/usage patterns.
Usage Patterns Are Different
Environment config: Ongoing project management, multiple developers, frequent changes
MCP config: One-time setup, rarely changed, per-developerThe more frequently used one (environment config) should be optimized for brevity.
Conceptual Clarity
When a user runs cu config, what are they configuring? If it's both environment AND agent setup, that's confusing.
cu env clearly means "I'm configuring the development environment."
cu configure clearly means "I'm setting up container-use integration."My Recommendation
cu env setup-command add "pip install -r requirements.txt"
cu configure add-server container-use
Working on that part now ... I was considering adding support for dockerfiles if you already have one for development, but adding more makes sense
Do we need some config regarding devcontainers itself? Never used it myself
@crimson plume Thoughts? Can't make up my mind
why dont we start with a separate cu env and see how it goes from there?
Yeah itโs a somewhat open standard spec already https://containers.dev/implementors/spec/. That said it covers a lot more than maybe you were thinking?
The purpose of the Development Container Specification is to provide a way to enrich containers with the content and metadata necessary to enable development...
For me though, a base image and secrets, env vars are probably the most vital things to get working for agents for project specific use.
Would you mind sharing to me a snippet of your devcontainer config? Just to get a sense of the what we'd need to support (e.g. the dockerfile stuff seems pretty trivial, but I'm wondering how things such as entrypoint would translate to this?)
we really need to at least figure out -- for all these shadow git commands imo so you can pass your own additional flags after the --
and tbh this feeling is even worse when you're me and started doing the whole thing with raw git commands, like i'm constantly switching back and forth between the 2, forgetting which one is in my history, etc
Thinking about this Iโm not sure it would make sense to re-implement the spec or parts of the spec just for container-use. However, it seems if a repo has a devcontainer setup already that probably 95%+ of the env needed for an agent to work with properly since itโs already setup. Perhaps it could be offloaded to an existing tool that handles the spec like devpod?
@dawn veldt does devcontainer support multi-container?
Yes it supports docker compose as well.
but if you have a docker-compose file and/or dockerfile, what's the point of devcontainer.json?
It glues those together along with extra stuff you would need to setup it all up automatically both locally or in a remote clould env. This includes secrets, extra dev tools that a prod base image might not have as well as personal dotfiles, etc. So again it goes beyond what an agent would need but there is a decent amount of overlap I think.
@restive pumice @crimson plume @hexed warren @serene dirge
Ok this is an exploration rather than a proposal ...
- add
cu configcommand to manage the environment (e.g. change base image and such)
docs: https://container-use-cu-config.mintlify.app/environment-configuration
PR: https://github.com/dagger/container-use/pull/202
- on top of that, here's a somewhat radical change: agents can't update their own config permanently. instead, they will inform the user to run
cu configcommands. Basically it moves the ownership back to the user
PR: https://github.com/dagger/container-use/pull/203
also some cleanup -- there's a tool to update config and a tool to update metadata, rather than a gigantic tool that does both
It's unfinished
Alternatives:
-
Leave as is where ownership is split between the agent and the user
-
Leave as is, but exclude those changes from
cu merge/cu apply... maybe add some flags to merge/apply only the environment config? Seems a bit tricky though to preserve history etc -
Do even less -- remove the tool to update the config, let the user deal with whatever environment it is given (and let the user deal witht hat)
I don't know which one is best between merge --squash and diff | apply (is one or the other less likely to be modified from .gitconfig that could break?) but I like the cu apply -d command idea ๐ Clearer to me than a cu merge --squash even if that does the same thing. And easier to discover when listing the available commands.
yeah i like cu apply as opposed to cu merge --squash . FYI @serene dirge I added a comment here https://github.com/dagger/container-use/pull/177#issuecomment-3047626460 not sure what you think about it.
Testers - what's your workflow for going from "finished" environment to clean PR? I find myself doing 1) cu checkout 2) rebase + squash
One issue I had: in addition to squashing, I also wanted to write a detailed commit message summarizing everything that has been done in the squashed history.
I wanted to ask claude to do that, but it couldn't, I assume because of CU interference with git
I think that's where the cu apply from #177 helps. But it doesn't solve the commit message issue.
I started and didn't finish this yet: https://github.com/dagger/container-use/pull/176
Basically the agent would keep a description of the environment up to date as it's working, which then would be used in commands such as cu merge
Nowadays I don't checkout anymore, I create my own branch and cu merge or cu apply (PR pending) inside
If I cu merge I need to squash and write a commit, if I cu apply I just write the commit
What's cu apply -d? ๐
it deletes the env after
oh, duh!
Yeah, at least the way I use it is I don't create a specific branch, the result of container-use is just one commit among others hand made (or not) so I just use container-use for a very specific task and if that's good, just apply and delete (and most of the time edit manually the code generated by through cu)
So for that cu apply -d is exactly what I like ๐
i reviewed the second one (203), and i think this feels like a good set of tradeoffs: move the config closer to the user, but keep the "magic" where you can have the agent help you write the config while insta-validating it. i do think it needs some polish, like the commands it tells the user to run should actually result in the config that the agent validated through the tool, but as a whole it feels like a good direction.
Just commented -- I left a huge part of the design out when I opened the PR: https://github.com/dagger/container-use/pull/203#discussion_r2192999102
@cosmic birch Related to environments : one aspect I'd like to revisit is the "opening" of environments by the LLM. It's related to base image ownership, but a bit tangential. I really think the LLM should not know about the environment it's in as long as it is aware that it's in an environment.
Am I doing something wrong or is it typical to have for example 82 different environments created in a single session? I am nervous using cu that I'm going to 1) end up a huge amount of docker data that 2) my llm is going to lose track of work because of the psycho number of containers. On point 2), I do already have to tell the llm "hey which branch are you talking about?". This is seemingly fixed by manually creating or specifying a branch name, but when i get bad results (e.g. it works for a long time and gives me something that is very far from even building), I worry it is losing track of things (e.g. maybe it resolves each build error in a separate containers)?
I've look a bit for resources to help alleviate these concerns--appreciate your answers and/or pointers to other resources ๐
Hey @primal drum -- no that's not expected, it's typically one environment per session. Which agent and model are you using?
Sometimes it might create another environment, but that is pretty rare (or because you explicitly ask it to do so)
I'm using claude code. It could be that I'm using this toolkit that sometimes spawns a lot of parallel tasks https://github.com/ethpandaops/ai-cookbook. Maybe that's missing a cleanup step?
@primal drum using claude code too ... maybe toolkit related. What's your typical workflow with the toolkit, so we can try to repro?
i wonder if it might be as simple as an LLM with a parallelism toolkit and complete task isolation likes to go crazy with the parallelism simply because it can, and doesn't have to worry about tasks overlapping
(in which case, very cool result even if 82 env branches are a pain to handle lol)
also makes me wonder if maybe we need some optional tools for the agent itself to apply -d envs into other envs
like maybe there's 82 just because the agent has no way to merge or delete envs
Hm ai cookbook is updating frequently and some command names have changed, but for repro try: setup according to readme, enter any smallish repo with a few submodules, set up your MCP server and demand in CLAUDE.md that it use your MCP server, execute claude --dangerously-skip-permissions then run user command /init-project-ai-docs
ah they're user commands? i was assuming they were mcp tools, maybe disregard what i was saying before
One thing that would be helpful would be some kind of 'last used' status info on cu list, or perhaps branch/container renaming after some amount of time to something more informative. But in any case it's still a cool project and very useful, thanks for putting it together
strongly agreed, i think there are some balls in the air intended to improve this exact thing (llm-generated updates to env summaries) ... i also think maybe you need to upgrade your binary because we definitely have an UPDATED field on cu list now
cu list
ID TITLE CREATED UPDATED
enjoyed-leopard Container-use binary rename project 1 day ago 1 day ago
usable-buck Test new git file export logic - with giโฆ 5 days ago 5 days ago
frank-flea Test git file export logic changes 5 days ago 5 days ago
I am brainstorming about the relationship between envs and sessions.
- I am in a git project, playing with it, I want a single env. I can do new sessions, but same env.
- Parallel agents: each instance is its own fork of the last env.
Maybe cu new or cu create creates a new env in the current folder. cu use can select a different one. Folder/project-scoped. When the session starts it knows which env to open.
Dunno if: one could possibly change it during a running session? Maybe a bad idea.
Question related to the previous one: how atomic are each of these environments? If I delete something an env can I break in any way an existing but newer environment, at the docker level, the dagger level, or even in terms of my models reasoning capabilities?
they are very isolated from each other. inside an env, there's virtually nothing the agent can do to break a different env. even when we had an env_fork tool, everything is very append-only, so even using environment_update to reset the base image of the base environment won't break its fork (the env fork tool was removed a while ago just because of dubious usefulness).
from outside an environment, there are definitely ways to break stuff. specifically with the container-use git remote, i'm sure there are plenty of unsafe operations you can make there to mess things up.
in terms of your model's reasoning capabilities... that's a harder question. a lot of agents let you roll back chat history, but with container-use rolling back chat history won't roll back an environment's edits, and that can confuse the LLM quite a bit. usually that's not destructive, but from the llm's perspective it'll look like the instructions you gave it have already been acted on.
Thank you for thinking about that, it's been bothering me for a while ...
I did toy with a cu create in #132 but there's some edge cases ... @restive pumice has insights
"insights" lol i really want to keep the UX that you don't need to run any cu commands to start using cu
like i don't think it's an improvement to push env management to humans
Yeah, it's a fine line ... I 100% agree the user shouldn't need to run commands, but I also feel like the agent shouldn't be able to go crazy with environments on its own
I don't know if the two goals are compatible, but I wish there'd be a solution where they are
i think they can be ๐ we just need sensible defaults
the hard part is picking 1, like i dunno about the "1 env for 1 git project" thing as a default, but it'd be a cool option to have
I think it's more about decoupling the two loops: 1) develop within an environment 2) configure an environment. If you have clean decoupling of the loops, you can still change which loop is done by a human or by agent. They're 2 different problems
A common requirement for many orgs to use an environment effectively is likely going to be the ability for the agent to install dependencies from private registries. This seems like something that might be tricky to do automatically, but will be very common.
@restive pumice @hexed warren @crimson plume Refined https://github.com/dagger/container-use/pull/203 and https://github.com/dagger/container-use/pull/202
cu configmanages the environment config (human side)- the agent CAN modify PARTS of the config -- but it's all ephemeral, in the environment state, NOT in git
- the human can look at the agent-modified environment config and can also decide to bring those changes home
- whenever the agent makes ephemeral config changes, it will notify the user to run a command to make the changes persistent
(^^ related)
Also updated the MCP tools to make it more straightforward for the agent ...
Returned environments have a config field. environment_config takes that same blob (a subset) to update the config. Non-config things (e.g. env title) are now in environment_update_metadata. Agent is happy
As soon as the higher priority UX issues are solved , secrets are definitely one of the first things we want to add. And yes private registries are a great usecase
want to hash out the subcommand names in 202?
cu config agent and cu config env? and then we can still have a nice interactive tui if you just do cu config to choose [agent,env], then which agent, etc
cu configure is ready to go otherwise. fixed the linting and made the configs local where possible. Codex and goose dont have local mcp server configs afaik
@restive pumice @hexed warren @crimson plume @serene dirge Been thinking more about this ...
I'm finding the idea of tying the environment to the git branch more and more interesting.
Basic UX: git checkout -b my-thing + claude: the agent now works in the my-thing environment. The user is free to switch to any other branch and do whatever, that session is tied to my-thing
Some additional thoughts I had:
- It would solve a lot of confusion (at least mine) since you're in control of the environment lifecycle / naming, and the control tools are what I'm already used to (git branching)
- This basically means that we get environment branching? Like, if from
my-thingyou createmy-other-thing, you get branched off state and continue from there? - It does raise questions about UX though -- we moved to a model where the fork works "independently" and you
cu diffetc, but this would change things? I guess in this case the old model ifgit checkout+git pullto grab changes back makes more sense thancu apply/cu merge - What does this mean for "remote git repositories"?
this might go without saying but it's at least no worse than without container-use, where when you roll back the chat history, any edits it made so far will still be there on your local machine
depends on the agent ๐ (zed actually rolls backs the edits)
ah interesting - i've been almost exclusively using claude code lately
do you have a read on Zed vs. Claude Code with the same model? always wondered since I like Zed's UX, but never took the time to compare
(farming out to @regal veldt if you have thoughts / opinions -- thinking about how to manage environments. right now the agent creates them and you have to find them. wondering if there's a better world)
personally, being able to control the environment is one of the first things i wanted, since my project has particular dependencies (like tree-sitter version) and I don't like them being guessed or drifting from my local machine
that session is tied to my-thing
i think you mean the session is tied to container-use/my-thing (the remote tracking branch?) otherwise we get into a mess of concurrency problems with the user repo branch, worktrees, etc... or are you thinking we try to work directly in the user's repo?
but also, my project is Daggerized, so REALLY the first thing i wanted was for it to just use my dagger module for most things
@regal veldt oh, this is those PRs ^^^
basically how to control the environment config
this is another topic -- not how to control the config, but to control the lifecycle. Basically who creates them, how they're named, how you find them
i used claude code for maybe 20 minutes on release and haven't revisited it
In the meantime, you can kinda manually edit .container-use/environment.json like this: https://github.com/dagger/container-use/blob/main/.container-use/environment.json
undocumented and will be replaced by those 2 PRs (at least the UX of it)
also, like... do you really not want multiple envs per branch? if i was happy making multiple branches to have multiple concurrent agent sessions, i'd just use worktrees (git co -b my-thing vs git worktree add -b my-thing ../my-thing)
Thatโs a bug Iโd say
i used it "in anger" for a few days recently and found it pretty ergonomic. the mode switching keybinds (plan vs. constantly confirm vs. faceroll edits), the way it manages memory (# to memorize something into CLAUDE.md or global memory), and the notifications integration (so you notice when it's waiting for input) all add up pretty well. it's more YOLO than Zed for sure, but you can interrupt it at any time to course-correct, and most of the time it figures things out on its own and backtracks. would recommend trying it some more tbh, i didn't really get it before
The main problem with this is for the use cases where you want to navigate the source code graph independently from the env (dag) graph
claude code avoids this "bug" by not providing the chat rewinding/editing feature in the first place ๐
Like one thing Iโve been wondering whether itโs overkill or not is if the agent could backtrack the env
i just don't want a tui for this tbh, and if i do i want it to be tiny and dumb (goose)
Wrong. Thatโs the feature I integrate with in the other proxy project
Hit esc twice
oh wat. the help text just says 'double tap esc to clear input'
Itโs possible the feature is under utilized and I accidentally found it
my main point is if our baseline for testing is a UX that requires a lot of human interaction (code review in Zed, not sure what Goose UX is like) there's a risk of not meeting the majority of vibecoders where they are
It rewinds the bash env (look at your /tmp)
tru
but like really we should all be using a vscode fork then so ๐คทโโ๏ธ
yeah, those are huge too, but i'm not sure which has the bigger reputation for yolo/full automation
the TUI aspect doesn't really matter much to me since most of the time you just leave it to do its thing and worry about something else while it crunches away
i've seen a lot of people go full yolo with cursor/windsurf but I personally don't understand why you'd want an IDE agent for that flow
yeah i've had like 4-5 terminals open with it at times
Itโs social media โcontentโ!
yeah, the IDE doesn't help much with the yoloing. half the time i barely use the zed review thing anyways, it's just like an extra layer of diffing on top of git that i end up bulk-accepting
personally I really like the ergonomics of warp but its not BYOM
How does warp work?
they have free/pro/turbo tiers and they host the models. So you still get sonnet 4 or whatever you want to use but its through their APIs
and its an agent in the terminal (not a TUI agent) so the interactions with the agent are much different than in an IDE or standalone tui/app
here's a video https://www.youtube.com/watch?v=9HP8T7ZRtcE
What if your terminal wasnโt just smart, but agentic? In this demo, we take Warp 2.0 for a spin, the first Agentic Development Environment, and show how it supercharges your developer workflows when combined Container Use.
Youโll see how to:
- Launch and manage multiple coding agents in parallel, each in its own containerized, git-isolated...
pretty cool naming:
Itโs basically a GUI command line environment
Technically closer to an IDE. I wonder what happens if you open vim inside warp.
when i tried out warp 1 nvim worked "fine" -- some text rendering issues and wackiness with cell padding and headers but otherwise fine
it's not ghostty or alacritty in terms of performance though, for obvious reasons
Iโm just wondering if they do PS1 magic to detect yield or if they just send each exec which if vim works doesnโt seem to be the case.
i'm fairly certain there's some crazy shell "integration" injection a-la ghostty/iterm but i don't know what the trick is. really the best part of warp is the way it ties command output to the actual commands and even that requires that it knows things a terminal emulator shouldn't lol
this is probably what you're looking for. In general it does what you want a terminal to do because they were a terminal long before they added an agent
"destructive, open-world" eh - is that accurate? or is there a setting we should tweak? (i have 0 idea what this actually does)
@regal veldt yeah that's undocumented because half baked ... it adds a service in the environment (like postgres). Should 100% not be done by an MCP tool
oh i meant all of them - i think these are properties you can set on mcp tools but i'm not sure how mcp clients interpret them. are all of ours considered destructive/open-world?
(wondering if the fact that we're sandboxed/containerized affects it basically)
i suppose they're still destructive to the environment
Oh ... I don't actually know how to set them? I don't think it's destructive since it's sandboxed?
Welcome to the Dagger community @tropic bane ! @silver abyss is working closely with the Zed team, so feel free to reach out to him or I if you have any questions. Happy to have you here and trying it out!
we should definitely be open world: false for every tool, and then i think some of the tools are in fact idempotent//read only
Good point!
Well, you do get containers from it compared to work trees โฆ
maybe itโs a counter point: right now it feels like itโs two things: container sandboxing plus advanced multi env per branch management
The most โlightweightโ thing container-use could do is the container/isolation layer without altering too much the worktree part
Not too sold on this, just brainstorming
Also multi env per branch ideally to me thatโs an advanced feature on top, you wouldnโt need to learn on day 1.
Whereas right now to me / my usage pattern if feels like the normal case is a special case
the UX that's hidden under multi-env-per-branch in the human-kinda-in-the-loop "normal" use case is that throwing away the results from a session is the default noop action... like i maybe go parallel 10% of the time, but i throw an env away and rework my prompt multiple times a day... if you've got 1 branch 1 env, we'd need a touchpoint to revert the env to the state prior to xyz session. the UX of that touchpoint would be complicated by the fact that 1-env-1-branch means you don't even have an identifier to revert to bc it's all 1 env id... as i say this i realize there's a classic infra analogy here: cattle not pets
if i've gotta set up a branch for each env, and if shit goes wrong in that env i've gotta make a new one... i'm gonna treat each of those like a pet. whereas right now, envs are incredibly disposable "let it fail" little boxes
very true!
I found all this discussion about environments very interesting. To share a bit my experience so far, I was kind of meh ๐ when I saw the environment aspect. Especially it continues to pick go 1.23 on a go 1.24 codebase, meaning I can't cu terminal easily. And this cu terminal is no nice I want to use it!
So to have the ability (but maybe not mandatory) to better define the environment is key. This also means it doesn't have to be guessed each time. And it might also a way to add specific tools to an environment as a way to constraint the agent to use those tools, to be closer to what would look like a manual experience.
In parallel, I started to play with Dev Containers (because some of the Dagger tests can't work on my Mac machine, but once inside a dev container that works just all fine).
I wonder how all that could be one single thing: to be able to define/describe and environment, why not using dagger shell (like container | from golang:1.24.4.alpine | with-mounted-directory ...) in a way I can dagger terminal and this will open a terminal in this env, and container-use will be able to use the exact same description to do its job.
Maybe that's a bit too much, I don't know.
Also there's the question of the different tools container-use might need that are not necessarily part of the described environment, but I guess the llm can find its own way to install them as needed.
Development containers documentation and specification page.
FWIW I'm hitting the cache issues with cu terminal too. It's making it unusable, I don't want to wait for all the things to be rerun. /cc @potent canopy
food for thought on debuggability: https://github.com/dagger/container-use/issues/208
When debugging why a tool is failing, I would find it useful to be able to call the same tool from a terminal. Especially for tools that use a tool-specific, different container than the env. Or ma...
FWIW I'm hitting the cache issues with
We need a standardized "Agentic PATH" object somewhere in the Agentic Workflow Ecosystem -- like a .path file mayjaps -- and we keep all our pathings in there - because the agents get lost so frequently. Even for files they've written -- clearly we can do lots of things on an individual level - but there should be an Agentic Standard for this. Or am I hallucinating? (Or maybe my ystems are just messy)
Sorry if this has been asked before...
In my corporate environment, I think I've determined that I'd need to configure container-use to use a dagger environment running in one of our k8s clusters. However, given that dagger deploys to k8s (at least in the helm chart) as either a daemonset or stateful set and without an Ingress/LoadBalancer, and because it seems that container-use suggests giving it basically a pod-and-port, how do I handle a (contrived) example like: I have a cluster where I can run 5 dagger pods. I have 13 developers wanting to use container-use . Do I just manually distribute them among the 5 pods?
has anyone run into the following while using container-use (in my case with gemini as an MCP Server)
Apologies for the screenshot, copy pasta is hard on discord
error
failed to create environment: failed loading initial source directory: failed to get content hash: failed to get snapshot: failed to sync: failed to create new copy ref: failed to prepare as 09cq8fgu9osl8u1titqsyopwn: failed to createprepare snapshot dir: failed to create temp dir: mkdir /var/lib/dagger/worker/snapshots/snapshots/new-3624974111: no space left on device
oooh, do you have space left on your computer ?
Is there a way I can access the container to clear this out
I do
it seems to be a temp fs on the container that's full - not the host machine
Same thing when it tries to pull down the image to get into the container
cu terminal informed-wahoo
...
53f8e4dcf39b:
02996c4bc849:
write /var/lib/docker/tmp/GetImageBlob3892905716: no space left on
! failed to run command: exit status 1
I wonder if it's the docker engine that needs increased resource allocation cause the host machine has enough space
That's it yes, can you please check -- usually that's the issue
Dagger expands as long as it's allowed (and garbage collects periodically)
hmm if I restart docker engine I'll loose everything within the container though right?
is the filesystem ephemeral or written to a volume (for container-use)?
mmh the git notes represnet your state so if you apply it you shouldn't loose
help me unwrap that please - what's git notes and how do I apply it?
with pleasure, available in 15 min (sorry about that), would that work for a sync on dev-audio ? ๐
absolutely, much appreciated @potent canopy
Trying to figure out how things work under the hood, stumbled on the above ^
When I try and run cu checkout to execute the flow on my host machine I end up with 2 new branches
cu list
ID TITLE CREATED UPDATED
informed-wahoo Azure CLI Documentation Query Utility 2 hours ago 2 hours ago
git branch
* main
cu checkout informed-wahoo
Switched to branch 'cu-informed-wahoo'
Q: At this point I should be on cu-informed-wahoo branch and that should be the only branch that's created on my "host" git repo
BUT
git branch
cu-informed-wahoo
* informed-wahoo
main
I have two branches created both which point to the container-use remote
git remote
container-use
cu version
cu version 0.1.0
commit: 410ddd56d059fa517f323f0cf12f08fde413b8f7
built: 2025-06-26T20:08:31Z
hi everyone ! discovered cu today and am trying it out now with cc .
i'm just trying to set up a default image for the agent , but want to check if configure is now a deprecated command ?
Any assistance would be greatly appreciated.
sorry about that - our docs are currently ahead of what's shipped ๐ we were just discussing this problem yesterday and decided "we'll wait until someone notices" since we're currently shipping frequently enough that it's nice to avoid that mild release engineering quagmire. well, here we are!
yo @urban hedge i am testing the roots support in VSCode right now, and even without my changes i can't repro this in VSCode 1.102.0, copilot, agent mode, and claude 3.7/3.5... on my end it looks like vscode injects a <workspace info> block at the beginning of the context that includes the absolute paths to all the folders in the workspace as well as a dump of paths in those dirs, OS and shell information.... am i missing something about your setup?
I've been investigating and playing with this tool, but I still can't figure out the complete value add.
So container use is this container with some tools like EnvironmentFileDeleteTool , EnvironmentAddServiceTool, EnvironmentCheckpointTool.
What I'm wondering is how will this container-user:
- Ensure the integrity of my local machine when I run claude code? The cc can still cause havoc when I use continaer-use as it's just an MCP in the toolset
- How can the get access to more advanced tools like interaction with other MCPs such as playwright?
I watched a bunch of demos where people create 2 versions of the same feature, but the problem is these are quite simple - no iterating on tests, or browser use etc. (basically running in a rich text editing environment).
In the keynote, Solomon starts the interaction with claude-yolo -> this is already an unsecured environment -> but it's the environment I prefer to use as it has the tools I need.
But then I don't have the security and can't skip all prompts.
Maybe I am expecting too much from container-user?
Thank you for your time.
In that case you should know that I added cu to context 7 so if anyone's using that MCP they'll have visibility to docs from the GitHub repo
And that explains why cu config didn't work for me either
To get the additional safety youโre looking for, I personally deny the agent access to the built-in tools that modify the filesystem while blanket-allowing container use tools.
Regarding other MCP servers like playwright, right now itโs somewhat challenging to interop cu and any of those servers that also have a host filesystem dependency, BUT there are suitable hacks if you prompt engineer the agent to let it know that environment code is available to XYZ server at path=~/.config/container-use/<env id> โฆ. You do have to be careful that the agent canโt run commands on the host system once it knows about that directory, though, because it will happily go in there and break stuff if it can
I see the following example environment setup-command listed in the docs:
Setup Commands:
3. ./scripts/dev-setup.sh
However, I can't seem to get this working. The environment_create tool always fails to find the file. I've tried prepending with /workdir to the setup-command, etc. Not sure how to debug this since the logs are not overly helpful and since the container isn't created I can't shell into it.
Can you please share which model you are using?
I'm using Claude Sonnet 4 in Zed (with a constrained container use profile).
^^^ /cc @restive pumice since you're most familiar with Zed
@dawn veldt is the dev-setup.sh file committed in git?
Yes, the script is committed. I'm using cu latest 0.3. I can try it with claude code too if it might be related to zed.
I don't think it should be related to Zed ...
let me try to repro something similar
I donโt recall if the source repo is actually present in the container at the point where we run setup commands
We might copy it last as a cache optimization
otherwise rerunning create would get cache misses for the setup commands
@restive pumice It used to, but maybe that got changed
oh yeah, that's it -- it's done before mounting the code now
Itโs a weird tradeoff to be fair, like personally Iโd rather have it create fast than be able to run stuff with my repo already mounted, but I can totally see the argument for the other way.
@restive pumice becase we mostly do go ๐ if we had to run pip install -r requirements.txt or npm install, we'd rather have it the other way or it wouldn't be usable
2 options:
- do it the other way around, forget about performance
- have setup_commands and ... build_commands or something? pre/post code
Fair I guess, but those are also slightly different in that you really only want the 2 files declaring dependencies
/cc @dawn veldt basically that's the reason -- to optimize for caching, the commands are run BEFORE the code is copied inside
This is basically how you'd do this in a Dockerfile:
FROM myimage
RUN apt-get install ... # setup commands
COPY . . # copy the code
Looking into a fix right now
In the meantime, to get you unblocked: is there a way you could put the setup.sh stuff directly into container-use's setup commands?
So the use case I wanted to add a setup script is I need to create files like .npmrc and maven settings.json files with env var references so that I can install dependencies from private repos. Can't easily do this with a single line command.
The other option might be using a base image that has this already, but that requires more moving parts.
@dawn veldt Fair -- I'll have a fix out today, just trying to see what the best approach is
/cc @restive pumice @regal veldt
Unsure about the approach / how to call both commands?
Thanks! A follow up feature or need might be to somehow share this. I forsee most of this being boilerplate for a lot of internal projects.
Which maybe a base image might be better for, I'm not sure. Does cu support pulling from private docker registries?
If you commit .container-use to the repository, the configuration will be shared (e.g. anyone creating environments will have the same setup commands etc).
Is that what you were thinking about?