copilot_here: October 2025 Updates - Auto-Updates, Cross-Platform Support, and More
On this page9 sections ▾
I've been running GitHub Copilot CLI in Docker with copilot_here (my previous post covers the initial setup), and the October updates addressed Windows startup, script installation and updates, argument forwarding, and image cleanup.
#What's New in October 2025
Here's a quick summary of the major updates. Skip to any section that interests you:
- Windows Docker Desktop Support - Added a fallback when user creation fails
- Auto-Updating Scripts - One command to update your shell functions without manual copy-paste
- Quick Install Method - One command instead of copying 200+ lines into your shell config
- Argument Pass-Through - Forwards native Copilot flags such as
--resume - Script Versioning - Know exactly which version you're running
- YOLO Mode Enhancements - Auto-approve everything with
--allow-all-paths - Smart Image Cleanup - Only removes images older than 7 days, saves bandwidth and time
#1. Windows Docker Desktop Support
The setup worked on my Mac, but failed during user creation on Windows Docker Desktop.
#The Issue
In the Windows failure I was handling, the entrypoint script hadn't created the non-root user (appuser). It then tried to switch to that missing user with gosu and failed. The error establishes the missing user; it doesn't explain why user creation failed.
error: failed switching to "appuser": unable to find user appuser:
no matching entries in passwd file#The Fix
Instead of just assuming user creation works, I added a verification step:
# Verify the user was created successfully
if ! id appuser >/dev/null 2>&1; then
echo "Warning: Failed to create appuser, running as root" >&2
mkdir -p /home/appuser/.copilot
exec "$@"
fiThe fallback runs as root and prints a warning, so it changes the user the command runs under. I accepted that tradeoff for this local development tool, but the warning matters when checking the permissions available in a session.
I also restructured the README to show PowerShell instructions alongside bash/zsh rather than buried in a footnote.
#2. Auto-Updating Scripts
The Docker image can auto-update via docker pull, but what about the shell functions users add to their .bashrc or .zshrc? Those live on the host machine and don't update themselves.
#The Challenge
I wanted users to be able to update their shell functions without:
- Manually copying code from GitHub
- Re-running curl commands
- Editing their shell config files
- Accidentally breaking their setup
#The Solution
I created standalone script files (copilot_here.sh and copilot_here.ps1) that users can download once and source in their shell profiles. Then I added an update flag that:
- Downloads the latest version from GitHub
- Shows you the version change
- Automatically reloads your current shell session
copilot_here --updateOutput:
Updating scripts from GitHub repository...
Updated bash/zsh script
Current version: 2025-10-28
Reloading shell function...
Scripts updated successfully!It updates the file and reloads the function in your current session, so you don't need to restart your terminal.
If you have the script symlinked somewhere (like a dotfiles repo), the update function detects the symlink and updates the source file, so your dotfiles stay in sync.
#3. Quick Install Method
The old setup required users to copy shell function code from the README and paste it into their config files. It worked, but it was awkward. The installer downloads and sources a script file instead.
#Before (Manual Mode):
# User copies 200+ lines of bash from README
# Pastes into ~/.zshrc
# Hopes they got it all
# Maybe accidentally pastes twice
# Now has duplicate functions 😬#After (Quick Install):
curl -fsSL https://github.com/GordonBeeming/copilot_here/releases/download/cli-latest/install.sh | $SHELLBecause the script lives in its own file, later updates use copilot_here --update.
I also added duplicate detection, so if you accidentally run the setup twice, it won't add the source line multiple times:
if ! grep -q "source ~/.copilot_here.sh" ~/.zshrc 2>/dev/null; then
echo 'source ~/.copilot_here.sh' >> ~/.zshrc
fi#4. Argument Pass-Through: Unlocking Native Copilot Features
I had built-in support for specific flags like --help and --no-cleanup, but that meant I was re-implementing argument parsing for flags the underlying CLI already handled. So I added automatic pass-through instead:
# Built-in wrapper args
WRAPPER_ARGS=("--help" "-h" "--no-cleanup" "--no-pull" "-d" "--dotnet"
"-dp" "--dotnet-playwright" "--update" "--upgrade")
# Check if arg is wrapper-specific or should pass through
for arg in "$@"; do
if [[ ! " ${WRAPPER_ARGS[@]} " =~ " ${arg} " ]]; then
# Not a wrapper arg, pass it to the container
passthrough_args+=("$arg")
fi
doneArguments the wrapper doesn't recognise are passed to Copilot for it to handle:
copilot_here --model gpt-4 "explain this code"
copilot_here -v # Show version
copilot_here --whatever-future-flag-gets-added#The --resume flag
One example is --resume. When Copilot is mid-task and something interrupts it (network hiccup, timeout, whatever), you can pick up right where it left off:
copilot_here --resume
For long-running tasks, not having to start over is a real time-saver. And since it goes through the pass-through logic, there's nothing special I had to do to support it.
When you run copilot_here --help, it shows both the wrapper's help AND the underlying Copilot CLI help, so you can discover features like --resume naturally.
#5. Script Versioning
When someone reports an issue, the first question is always "which version are you on?" So every script now has a version header:
# Version: 2025-10-28The format is YYYY-MM-DD for the primary version, and if I make multiple updates in one day, it becomes YYYY-MM-DD.1, YYYY-MM-DD.2, etc.
This already came up while testing changes. Instead of the vague "are you on the latest?", I can say "you need 2025-10-28 or later for that."
#6. YOLO Mode Enhancements
copilot_yolo mode lets you skip confirmation prompts entirely. Where copilot_here asks before executing commands, YOLO mode just runs:
copilot_yolo "fix all the linting errors in this project"
# Auto-approves all tool usage, including file modificationsI added a --allow-all-paths flag specifically for this, which pairs with auto-approval for a fully hands-off run. Useful for workflows you trust. I'd leave it off for anything touching production.
#7. Smart Image Cleanup
The cleanup could remove an unused image and immediately pull the same image again on the next launch. That made the cleanup cause unnecessary downloads.
#The Problem
The cleanup logic had two issues:
- It was trying to remove intermediate images with
<none>tags, which would fail and spam your console - It removed ALL unused images, including the current latest one, forcing an unnecessary re-download
Failed to remove: ghcr.io/gordonbeeming/copilot_here:<none>
Pulling latest image...
# Downloads the same image it just removed 🤦#The Fix
The cleanup checks the image age:
# Get cutoff timestamp (7 days ago)
local cutoff_date=$(date -d '7 days ago' +%s 2>/dev/null || date -v-7d +%s 2>/dev/null)
# Get all copilot_here images, excluding <none> tags
local all_images=$(docker images --filter "label=project=copilot_here" \
--format "{{.Repository}}:{{.Tag}}|{{.CreatedAt}}" | grep -v ":<none>" || true)
# Only remove if older than 7 days
if [ -n "$image_date" ] && [ "$image_date" -lt "$cutoff_date" ]; then
docker rmi "$image" >/dev/null 2>&1
fiThe cleanup runs after the pull and filters out <none> tags. The age check uses the image creation date, not the time it was downloaded. An image created more than seven days ago can still be the current release, so age alone does not guarantee that cleanup will retain the image just pulled.
The changes make the wrapper easier to maintain: version information helps with bug reports, argument forwarding avoids duplicating Copilot's parser, and the installer keeps shell setup in one file. Windows still has the root-user fallback described above, so that warning is worth checking when diagnosing a startup problem.
#What's next
A few things I'm still poking at:
- Better error messages when GitHub token scopes are wrong (currently the error is cryptic)
- Support for custom Docker registries for enterprise setups
- A configurable cleanup period, though honestly 7 days hasn't caused complaints yet
The project is on GitHub: copilot_here. The installer takes one command and you get Copilot CLI running in a sandboxed container that keeps itself up to date.