Container Lifecycle and Sessions - mensfeld/code-on-incus GitHub Wiki
Understanding how containers and sessions work in COI.
-
Containers are always launched as non-ephemeral (persistent in Incus terms)
- This allows saving session data even if the container is stopped from within (e.g.,
sudo shutdown 0) - Session data can be pulled from stopped containers, but not from deleted ones
- This allows saving session data even if the container is stopped from within (e.g.,
-
Inside the container:
tmux→bash→<ai-tool>- When the AI tool exits, you're dropped to bash
- From bash you can: type
exit, pressCtrl+b dto detach, or runsudo shutdown 0
-
On cleanup (when you exit/detach):
- Session data (tool config directory) is always saved to
~/.coi/sessions-<tool>/ - If
--persistentwas NOT set: container is deleted after saving - If
--persistentwas set: container is kept for reuse - Cleanup is protected by
sync.Onceto prevent race conditions between signal handlers and deferred cleanup
- Session data (tool config directory) is always saved to
-
Docker/Compose support: Session containers automatically get Docker support flags (
security.nesting,security.syscalls.intercept.mknod/setxattr) applied before the container starts, so Docker and Docker Compose work out of the box inside sessions.
| Mode | Workspace Files | AI Tool Session | Container State |
|---|---|---|---|
| Default (ephemeral) | Always saved | Always saved | Deleted |
--persistent |
Always saved | Always saved | Kept |
Restores the AI tool conversation in a fresh container:
- Use when you want to continue a conversation but don't need installed packages
- Container is recreated, only tool session data is restored
- Workspace-scoped: Only finds sessions from the current workspace directory (security feature)
Keeps the entire container with all modifications:
- Use when you've installed tools, built artifacts, or modified the environment
-
coi attachreconnects to the same container with everything intact
Converts a running ephemeral session to persistent mode:
# Convert the current session to persistent (keeps the container on exit)
coi persistThis is useful when you started an ephemeral session but later decide you want to keep the container (e.g., after installing tools or setting up the environment).
Forward your host's SSH agent into the container so git-over-SSH works without copying private keys:
# ~/.coi/config.toml
[ssh]
forward_agent = trueThe host's SSH_AUTH_SOCK is bridged into the container at /tmp/ssh-agent.sock via an Incus proxy device. COI automatically sets SSH_AUTH_SOCK inside the container and includes retry logic to handle an Incus race condition where proxy devices on freshly-launched containers may not create the listen socket immediately.
Key points:
- Disabled by default (opt-in for security)
- Gracefully skips if no SSH agent is running on the host
- Works with both ephemeral and persistent containers
- Device is replaced on persistent container re-entry
Selectively forward host environment variables into the container by name:
# ~/.coi/config.toml
[defaults]
forward_env = ["ANTHROPIC_API_KEY", "GITHUB_TOKEN", "AWS_ACCESS_KEY_ID"]
# Static environment variables (always set)
[defaults.environment]
RUST_BACKTRACE = "1"
NODE_ENV = "development"Key points:
- Values are read from the host at session start — never stored in config files
- Missing variables produce a warning but don't fail the session
- Config values from different levels are merged (deduplicated)
- Profile-level
environmentvars are also applied
-
exitin bash → exits bash but keeps container running (use for temporary shell exit) -
Ctrl+b d→ detaches from tmux, container stays running -
sudo shutdown 0orsudo poweroff→ stops container, session is saved, then container is deleted (or kept if--persistent)
-
coi shutdown <name>→ graceful stop with session save, then delete (60s timeout by default) -
coi shutdown --timeout=30 <name>→ graceful stop with 30s timeout -
coi shutdown --all→ graceful stop all containers (with confirmation) -
coi shutdown --all --force→ graceful stop all without confirmation -
coi kill <name>→ force stop and delete immediately -
coi kill --all→ force stop and delete all containers (with confirmation) -
coi kill --all --force→ force stop all without confirmation -
coi unfreeze→ unfreeze a paused container (e.g., after security monitor auto-pause)
coi shell # Start session with default AI tool
# ... work with AI assistant ...
sudo poweroff # Shutdown container → session saved, container deleted
coi shell --resume # Continue conversation in fresh containerNote: exit in bash keeps the container running - use sudo poweroff or sudo shutdown 0 to properly end the session. Both require sudo but no password.
coi shell --persistent # Start persistent session
# ... install tools, build things ...
# Press Ctrl+b d to detach
coi attach # Reconnect to same container with all tools
sudo poweroff # When done, shutdown and save
coi shell --persistent --resume # Resume with all installed tools intact# Terminal 1: Start first session (auto-allocates slot 1)
coi shell
# ... working on feature A ...
# Press Ctrl+b d to detach (container stays running)
# Terminal 2: Start second session (auto-allocates slot 2)
coi shell
# ... working on feature B in parallel ...
# Both sessions share the same workspace but have isolated:
# - Home directories (~/slot1_file won't appear in slot 2)
# - Installed packages
# - Running processes
# - AI tool conversation history
# List both running sessions
coi list
# coi-abc12345-1 (ephemeral)
# coi-abc12345-2 (ephemeral)
# When done, shutdown all sessions
coi shutdown --allAssign human-friendly names to your containers for easy management from any directory:
# .coi/config.toml
[container]
alias = "myproject"coi shell myproject # Launch session using alias (from any directory)
coi attach myproject # Attach to running aliased container
coi kill myproject --force # Kill by alias
coi attach myproject-2 # Attach to slot 2 by aliasAliases are registered in ~/.coi/aliases.json on first use and stored as user.coi.alias metadata on each container. coi list shows aliases next to container names.