Jump to content

Opencode isolation and burner workflow 260216: Difference between revisions

From Game in the Brain Wiki
No edit summary
Add HOST/DISTROBOX labels, remove BoxBuddy, expand golden image and cloning sections
Line 2: Line 2:


This guide establishes a '''Distrobox-based isolation workflow''' for running OpenCode. This prevents AI agents from accidentally modifying your host system files and allows you to "nuke" the environment if it gets corrupted or compromised.
This guide establishes a '''Distrobox-based isolation workflow''' for running OpenCode. This prevents AI agents from accidentally modifying your host system files and allows you to "nuke" the environment if it gets corrupted or compromised.
== Command Context ==
Every command in this guide is prefixed with where it must be run:
{| class="wikitable"
|-
! Prefix !! Meaning
|-
| <code>'''[HOST]'''</code> || Run this in a terminal on your normal Linux desktop, outside any container
|-
| <code>'''[DISTROBOX]'''</code> || Run this inside the Distrobox container after entering it
|}


== Part 1: The "Burner" Philosophy ==
== Part 1: The "Burner" Philosophy ==
Line 18: Line 31:
'''The Loop:'''
'''The Loop:'''


'''Spin up''' a fresh Arch/Ubuntu container with a '''Custom Home'''.
'''Spin up''' a fresh Ubuntu container with a '''Custom Home'''.


'''Inject''' the necessary tools (NodeJS, Git, OpenCode CLI).
'''Inject''' the necessary tools (NodeJS, Git, OpenCode CLI).
Line 124: Line 137:
== Part 4: Setup Instructions ==
== Part 4: Setup Instructions ==


Choose your preferred method.
=== Step 1: Install Distrobox ===


=== Option A: Command Line (Recommended) ===
'''[HOST]'''
 
==== 1. Install Distrobox ====
 
'''HOST TERMINAL'''


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 136: Line 145:
</syntaxhighlight>
</syntaxhighlight>


==== 2. Create the Burner Container ====
=== Step 2: Create the Burner Container ===


'''HOST TERMINAL'''
'''[HOST]'''


We create a container with a '''custom home directory'''. This is the key isolation step.
We create a container with a '''custom home directory'''. This is the key isolation step.
Line 149: Line 158:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
 
# Create the storage folder on your host first
Create the storage folder on your host first
 
mkdir -p ~/opencode_burner_data
mkdir -p ~/opencode_burner_data


Create the container mapped to this folder
# Create the container mapped to this folder
 
distrobox create --name opencode-burner --image ubuntu:24.04 --home ~/opencode_burner_data
distrobox create --name opencode-burner --image ubuntu:24.04 --home ~/opencode_burner_data
</syntaxhighlight>
</syntaxhighlight>


==== 3. Enter the Container ====
=== Step 3: Enter the Container ===


'''HOST TERMINAL''' → '''CONTAINER TERMINAL'''
'''[HOST]''' Run this to step inside. Your prompt will change.


Run this to step inside. Your prompt will change.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
distrobox enter opencode-burner
distrobox enter opencode-burner
</syntaxhighlight>
</syntaxhighlight>


=== Option B: BoxBuddy (GUI Users) ===
=== Step 4: Install Dependencies ===
 
'''WARNING:''' By default, BoxBuddy '''shares your real home directory'''. You must explicitly change this setting during creation, or you are not isolated.
 
Open BoxBuddy and click the '''+ (Create)''' button.
 
'''Name:''' opencode-burner
 
'''Image:''' ubuntu:24.04


'''Home Directory:''' Click the File icon. Navigate to and select your created opencode_burner_data folder. '''Do not leave this blank.'''
'''[DISTROBOX]'''


Click '''Create'''.
Once created, click the '''Terminal Icon''' (right side) to enter the box.
=== 4. Install Dependencies ===
'''CONTAINER TERMINAL'''
Now that you are ''inside'', install the necessary tools. We no longer need Firejail.
'''For Ubuntu 24.04:'''
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo apt update && sudo apt install -y nodejs npm git build-essential python3
sudo apt update && sudo apt install -y nodejs npm git build-essential python3
</syntaxhighlight>
</syntaxhighlight>


=== 5. Install OpenCode ===
=== Step 5: Install OpenCode ===


'''CONTAINER TERMINAL'''
'''[DISTROBOX]'''


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 203: Line 189:
</syntaxhighlight>
</syntaxhighlight>


=== 6. Configure OpenCode (Manual Edit) ===
=== Step 6: Configure OpenCode ===


'''CONTAINER TERMINAL'''
'''[DISTROBOX]'''


We need to manually edit the config file. Since we are in a minimal terminal, we use <code>nano</code>.
'''Open the file:'''
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
mkdir -p ~/.config/opencode
mkdir -p ~/.config/opencode
Line 218: Line 201:
If the file already has content, use this sequence to clear it quickly:
If the file already has content, use this sequence to clear it quickly:


<code>Alt</code> + <code></code> : Go to the very first line (Top).
<code>Alt</code> + <code></code> : Go to the very first line (Top).


<code>Alt</code> + <code>A</code> : 'Mark' the text (Start selection).
<code>Alt</code> + <code>A</code> : 'Mark' the text (Start selection).
Line 227: Line 210:


'''Paste the Configuration:'''
'''Paste the Configuration:'''
Copy the JSON below and paste it into the terminal (usually <code>Ctrl</code>+<code>Shift</code>+<code>V</code> or Right Click).


<syntaxhighlight lang="json">
<syntaxhighlight lang="json">
{
{
"provider": {
  "provider": {
"ollama": {
    "ollama": {
"npm": "@ai-sdk/openai-compatible",
      "npm": "@ai-sdk/openai-compatible",
"name": "Ollama Local",
      "name": "Ollama Local",
"options": {
      "options": {
"baseURL": "http://127.0.0.1:11434/v1"
        "baseURL": "http://127.0.0.1:11434/v1"
},
      },
"models": {
      "models": {
"qwen2.5-coder:7b": { "name": "Qwen 2.5 Coder (7B)" }
        "qwen2.5-coder:7b": { "name": "Qwen 2.5 Coder (7B)" }
}
      }
},
    },
"deepseek": {
    "deepseek": {
"npm": "@ai-sdk/openai-compatible",
      "npm": "@ai-sdk/openai-compatible",
"name": "DeepSeek API",
      "name": "DeepSeek API",
"options": {
      "options": {
"baseURL": "https://api.deepseek.com/v1",
        "baseURL": "https://api.deepseek.com/v1",
"apiKey": "sk-YOUR_API_KEY"
        "apiKey": "sk-YOUR_API_KEY"
},
      },
"models": {
      "models": {
"deepseek-chat": {
        "deepseek-chat": { "name": "DeepSeek V3 (Fast & Smart)" },
"name": "DeepSeek V3 (Fast & Smart)"
        "deepseek-reasoner": { "name": "DeepSeek R1 (Thinking Model)" }
},
      }
"deepseek-reasoner": {
    }
"name": "DeepSeek R1 (Thinking Model)"
  }
}
}
}
}
}
}
</syntaxhighlight>
</syntaxhighlight>


'''Save and Exit:'''
'''Save and Exit:''' <code>Ctrl+O</code> → Enter → <code>Ctrl+X</code>


<code>Ctrl</code> + <code>O</code> (Write Out/Save) -> Press <code>Enter</code> to confirm.
=== Step 7: Create Workspace ===


<code>Ctrl</code> + <code>X</code> (Exit).
'''[DISTROBOX]'''
 
=== 7. Create Workspace ===
 
'''CONTAINER TERMINAL'''


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 277: Line 251:
</syntaxhighlight>
</syntaxhighlight>


=== 8. Launch OpenCode ===
=== Step 8: Launch OpenCode ===


'''CONTAINER TERMINAL'''
'''[DISTROBOX]'''


Because we isolated the entire home directory in Step 2, we don't need complex Firejail commands. The AI is already in a padded cell.
Because we isolated the entire home directory in Step 2, we don't need complex Firejail commands. The AI is already in a padded cell.
Line 287: Line 261:
</syntaxhighlight>
</syntaxhighlight>


=== 9. Save Your Work & Create Base Image (Optional) ===
=== Step 9: Save as a Golden Image ===
 
Once the container is fully configured, save it as a reusable '''golden image''' so future sessions start pre-installed without repeating Steps 4–7.
 
'''[DISTROBOX]''' Exit the container first:
 
<syntaxhighlight lang="bash">
exit
</syntaxhighlight>
 
Your prompt should return to the host (e.g., <code>justin@hostname</code>).


'''Persistence:'''
'''[HOST]''' Stop the container:
Since we used the <code>--home</code> flag, all your code and configs are already saved on your '''Host Machine''' in <code>~/opencode_burner_data</code>. You can delete the container, and your files remain safe.


'''Creating a "Golden Image":'''
<syntaxhighlight lang="bash">
To avoid reinstalling Node/Git/OpenCode for the next burner, save this container as a base image.
distrobox stop opencode-burner
</syntaxhighlight>


'''IMPORTANT:''' You must exit the container first! <code>distrobox</code> is a tool installed on your host, not inside the box.
'''[HOST]''' Commit the container state to a named Podman image:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
podman commit opencode-burner localhost/opencode-golden:latest
</syntaxhighlight>


1. Leave the container FIRST
'''[HOST]''' Verify the image was created:


exit
<syntaxhighlight lang="bash">
podman image ls | grep opencode-golden
</syntaxhighlight>
 
You should see output like:
 
<pre>
localhost/opencode-golden  latest  a1b2c3d4e5f6  2 minutes ago  1.1 GB
</pre>
 
== Part 5: Starting Sessions from the Golden Image ==
 
Each new working session creates a throwaway container from the golden image. When the session ends, delete the container — leaving no trace.
 
=== Single Session ===


Your prompt should change (e.g., from justin@u260216 back to justin@host)
'''[HOST]''' Create a new session container:


2. Stop the container (Run this on HOST)
<syntaxhighlight lang="bash">
mkdir -p ~/opencode_burner_data_session1
distrobox create --name opencode-session-1 --image localhost/opencode-golden:latest --home ~/opencode_burner_data_session1
</syntaxhighlight>


CLI User:
'''[HOST]''' Enter it:


distrobox stop opencode-burner
<syntaxhighlight lang="bash">
distrobox enter opencode-session-1
</syntaxhighlight>


BoxBuddy User: Click the "Stop" (Square) button.
'''[DISTROBOX]''' Start working immediately — everything is pre-installed:


3. Save as a new image (Use 'podman' or 'docker')
<syntaxhighlight lang="bash">
cd ~/opencode_workspace
opencode
</syntaxhighlight>


Note: BoxBuddy does not currently support 'commit'. You MUST use the terminal for this step.
'''[HOST]''' When the session is done, delete the container and its data:


podman commit opencode-burner opencode-golden-image
<syntaxhighlight lang="bash">
distrobox rm opencode-session-1
rm -rf ~/opencode_burner_data_session1
</syntaxhighlight>
</syntaxhighlight>


'''4. Verify the Image Exists:'''
=== Multiple Parallel Sessions (Cloning) ===
Run this command to see your new "Golden Image" in the list.
 
Run several independent sessions at the same time from the same golden image:
 
'''[HOST]'''
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
podman images
mkdir -p ~/opencode_burner_data_{A,B,C}
 
distrobox create --name opencode-session-A --image localhost/opencode-golden:latest --home ~/opencode_burner_data_A
distrobox create --name opencode-session-B --image localhost/opencode-golden:latest --home ~/opencode_burner_data_B
distrobox create --name opencode-session-C --image localhost/opencode-golden:latest --home ~/opencode_burner_data_C
</syntaxhighlight>
 
Each container is completely independent. Changes in session A do not affect B or C.


You should see 'localhost/opencode-golden-image' listed here.
'''[HOST]''' List all containers:


<syntaxhighlight lang="bash">
distrobox list
</syntaxhighlight>
</syntaxhighlight>


'''5. How to Reuse It (Next Project):'''
'''[HOST]''' Clean up all sessions when done:
When you start a NEW project (e.g., Burner V2), you can skip all the installation steps. Point the new box to a NEW data folder, but use your SAVED image.
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
distrobox rm opencode-session-A opencode-session-B opencode-session-C
rm -rf ~/opencode_burner_data_{A,B,C}
</syntaxhighlight>
=== Updating the Golden Image ===


1. Create a new empty folder for the new project
'''[HOST]''' Create a temporary update container:


mkdir ~/burner_project_v2
<syntaxhighlight lang="bash">
distrobox create --name opencode-update --image localhost/opencode-golden:latest
distrobox enter opencode-update
</syntaxhighlight>


2. Create box using your GOLDEN IMAGE
'''[DISTROBOX]''' Make your changes:


distrobox create --name burner-v2 --image opencode-golden-image --home ~/burner_project_v2
<syntaxhighlight lang="bash">
sudo npm update -g opencode-ai
</syntaxhighlight>


3. Enter and go!
'''[DISTROBOX]''' Exit:


distrobox enter burner-v2
<syntaxhighlight lang="bash">
exit
</syntaxhighlight>


(Opencode is already installed!)
'''[HOST]''' Commit and clean up:


<syntaxhighlight lang="bash">
distrobox stop opencode-update
podman commit opencode-update localhost/opencode-golden:latest
distrobox rm opencode-update
</syntaxhighlight>
</syntaxhighlight>


== Part 5: Automated Launcher (Optional) ==
== Part 6: Automated Launcher (Optional) ==


If you get tired of typing <code>distrobox enter</code> every time, you can use the <code>launch_burner.sh</code> script (provided separately) from your '''HOST TERMINAL'''. It handles the context switching automatically.
If you get tired of typing <code>distrobox enter</code> every time, you can use the <code>launch_burner.sh</code> script (provided separately) from your '''[HOST]''' terminal. It handles the context switching automatically.


== Troubleshooting ==
== Troubleshooting ==
Line 365: Line 404:


'''Cause:''' This is a "Nest Isolation" conflict. Firejail is trying to create a sandbox inside a container that has already virtualized the system files.
'''Cause:''' This is a "Nest Isolation" conflict. Firejail is trying to create a sandbox inside a container that has already virtualized the system files.
'''Fix:''' Use the "Clean Room" method (Part 4, Step 2). This creates a container where the ''entire'' home directory is fake, so you don't need Firejail to protect your files—they simply aren't there.
'''Fix:''' Use the <code>--home</code> custom directory method (Part 4, Step 2). This creates a container where the ''entire'' home directory is separate, so you don't need Firejail to protect your files—they simply aren't there.


=== "WARN: failed to kill all processes / cgroup not exist" ===
=== "WARN: failed to kill all processes / cgroup not exist" ===
When stopping a container, you may see this scary warning:
When stopping a container, you may see this warning:


<pre>
<pre>
WARN
WARN[0000] failed to kill all processes... error="cgroup not exist"
opencode-burner
</pre>


$$0000$$
'''Verdict:''' It worked. This is a common warning in rootless containers where Distrobox cannot access system-level cgroups to force-kill background processes. The container name printed on the last line confirms it stopped successfully.


failed to kill all processes... error="cgroup not exist"
== See Also ==
u260217
</pre>


'''Verdict:''' It worked. This is a common warning in rootless containers where Distrobox cannot access the deep system-level "cgroups" to force-kill background processes. The fact that the container name (e.g., u260217 or opencode-burner) is printed on the last line indicates the container stopped successfully.
* [[Claude_Code_Isolation_and_Burner_Workflow_260211]] — Claude Code version of this workflow with Firejail
* [[Creating_a_Distrobox_from_a_Golden_Image]] — Detailed golden image reference

Revision as of 13:36, 20 February 2026

OpenCode "Burner" Workflow & Hardware Reality Check

This guide establishes a Distrobox-based isolation workflow for running OpenCode. This prevents AI agents from accidentally modifying your host system files and allows you to "nuke" the environment if it gets corrupted or compromised.

Command Context

Every command in this guide is prefixed with where it must be run:

Prefix Meaning
[HOST] Run this in a terminal on your normal Linux desktop, outside any container
[DISTROBOX] Run this inside the Distrobox container after entering it

Part 1: The "Burner" Philosophy

The Goal: Run OpenCode in a disposable container (opencode-burner) that shares only specific project folders, not your entire home directory.

Simpler than Claude Code: This workflow is significantly more streamlined than typical Claude Code isolation setups. We rely on Distrobox Custom Homes instead of Firejail for stability.

No Re-Authentication Loop: Unlike Claude, which often forces you to re-login via browser or copy keys every session, this container persists your "Burner Identity" (Git credentials & Configs).

Zero Boot Time: Distrobox shares your host kernel. There is no VM overhead; it launches instantly.

One-Step Launch: You don't need to manually start a Docker daemon, attach a shell, and then run a binary. The launcher script handles the context switch automatically.

The Loop:

Spin up a fresh Ubuntu container with a Custom Home.

Inject the necessary tools (NodeJS, Git, OpenCode CLI).

Mount only the target project.

Burn it (delete the container) when the project is done or the environment gets messy.

Part 2: The Hardware Reality (VRAM is the Limit)

Running local coding agents requires massive Context Windows. Codebases are large. The standard 4k or 8k context is useless for an agent reading multiple files.

The Golden Rule: You need at least 32k Context for a usable agent.

GPU Tier List (Discrete VRAM)

GPU Class VRAM Price (PHP) Practical Limit Verdict
RX 7600 8 GB ~₱18,000 8k - 16k
(32k Unstable)
Entry Level.
8GB is the hard floor. You can run a 7B model, but 32k context "sometimes works" and often crashes (OOM) because the OS + Model leaves almost no room for the cache.
RX 9070 XT 16 GB ~₱50,000 64k (Unstable) The Danger Zone.
16GB is tight. You can force a 64k context, but it requires creating a custom Modelfile and is unstable. The model weights (~5GB) + OS (~4GB) leave little room for the KV cache. Expect OOM crashes.
RX 7900 XT 20 GB ~₱80,000 64k - 80k The Sweet Spot.
That extra 4GB VRAM is crucial. It creates enough headroom to run a quantized 7B or 14B model with a healthy 64k context window comfortably.
Workstation
(e.g., W7800/R9700)
32 GB High 128k+ The AI King.
Required if you want to run full 128k context locally. 32GB VRAM allows for uncompressed cache or running larger parameters (e.g., 32B models) with decent context.

Unified Memory & Workstation Architectures (Massive Capacity, Slower Speed)

Use these if you need to run Huge Models (70B, 405B) that won't fit on any consumer GPU.

Trade-off: While capacity is massive, Tokens Per Second (T/s) is significantly lower (slower generation) compared to the Discrete GPUs above due to lower memory bandwidth.

System / Chip RAM (Unified) Est. Cost (PHP) Capability Verdict
AMD Ryzen AI Max+ PRO 395
(Strix Halo)
128 GB
(allocates ~112GB to AI)
~₱135,000
(Framework/MiniPC)
Llama 3 70B @ Q8
DeepSeek V2 Lite
The Compact Beast.
Allows running 70B models comfortably. Excellent value for capacity, but slower inference than a dGPU.
Apple Mac Studio
(M3/M4 Ultra)
Up to 512 GB ~₱400,000 - ₱600,000+
(Max Config)
Llama 3 405B @ Q4
DeepSeek V3 671B
The Whale.
One of the few ways to run "Frontier" models locally. Extremely expensive and slower generation speeds, but unparalleled privacy for massive models.

Select the model that fits your GPU tier.

7-8 Billion Parameter Models (Best for 12GB - 16GB VRAM)

Qwen2.5-Coder-7B-Instruct: The current gold standard. Supports up to 128k natively. Excellent for bug fixing and large codebase understanding on consumer hardware.

YaRN-Mistral-7b-64k: Specifically configured for 64k context using the YaRN extension method. Benchmarks show stable perplexity at long lengths.

OpenCodeReasoning-Nemotron-7B: Supports 64k context. Excels specifically at reasoning tasks for code generation.

14-16 Billion Parameter Models (Best for 20GB - 24GB VRAM)

Qwen2.5-Coder-14B-Instruct: The heavy hitter. Supports 128k natively. Provides significantly more capacity for complex, multi-file project analysis and agentic workflows than the 7B version.

DeepCoder-14B-Preview: Supports 64k context. Uses reinforcement learning to achieve performance comparable to much larger proprietary models.

The "DeepSeek V3" Alternative

Before spending ₱80k on hardware, consider the DeepSeek API.

Context: 64k (Output) / 128k (Input) natively.

Intelligence: DeepSeek V3 (671B MoE) is vastly smarter than any local Qwen 7B/14B.

Cost: ~₱7.80 ($0.14) per 1 Million tokens.

Strategy: Use Local 7B for small, private edits. Use DeepSeek V3 for "Build" agent tasks requiring long context.

Part 3: GitHub Burner Identity

Agents need to pull/push code. Do not give them your main GitHub credentials (SSH keys) that have access to your private company/client repos.

The Strategy:

Start by testing with your main account (carefully) to verify the tool works.

IMMEDIATELY switch to a Burner GitHub Account for daily agentic work.

Generating a Token (PAT): You cannot use a simple password for Git over HTTPS. You need a Personal Access Token.

Log in to your Burner GitHub Account.

Click your Profile Picture (top right) → Settings.

Scroll to the very bottom left sidebar → Developer settings.

Click Personal access tokensTokens (classic).

Click Generate new token (classic).

    • Note: You may be asked for 2FA or Email authentication.

Scopes: Select repo (Full control of private repositories) and workflow.

Expiration: Set to 90 days. (This is fine; we want these to expire so we don't leave loose ends).

Copy the token immediately. You will not see it again.

Inside the Burner Container: When OpenCode asks for Git authentication, use your Burner Username and paste this Token as the password.

Part 4: Setup Instructions

Step 1: Install Distrobox

[HOST]

curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh

Step 2: Create the Burner Container

[HOST]

We create a container with a custom home directory. This is the key isolation step.

On your host, this folder will be ~/opencode_burner_data.

Inside the container, this folder will be seen as /home/username.

The AI cannot see your real SSH keys or Documents because they literally do not exist in this folder.

# Create the storage folder on your host first
mkdir -p ~/opencode_burner_data

# Create the container mapped to this folder
distrobox create --name opencode-burner --image ubuntu:24.04 --home ~/opencode_burner_data

Step 3: Enter the Container

[HOST] Run this to step inside. Your prompt will change.

distrobox enter opencode-burner

Step 4: Install Dependencies

[DISTROBOX]

sudo apt update && sudo apt install -y nodejs npm git build-essential python3

Step 5: Install OpenCode

[DISTROBOX]

sudo npm install -g opencode-ai

Step 6: Configure OpenCode

[DISTROBOX]

mkdir -p ~/.config/opencode
nano ~/.config/opencode/opencode.json

Nano Shortcuts to Clear File: If the file already has content, use this sequence to clear it quickly:

Alt +  : Go to the very first line (Top).

Alt + A : 'Mark' the text (Start selection).

Alt + / : Go to the very last line (End).

Ctrl + K : Cut/Remove the selected text.

Paste the Configuration:

{
  "provider": {
    "ollama": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Ollama Local",
      "options": {
        "baseURL": "http://127.0.0.1:11434/v1"
      },
      "models": {
        "qwen2.5-coder:7b": { "name": "Qwen 2.5 Coder (7B)" }
      }
    },
    "deepseek": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "DeepSeek API",
      "options": {
        "baseURL": "https://api.deepseek.com/v1",
        "apiKey": "sk-YOUR_API_KEY"
      },
      "models": {
        "deepseek-chat": { "name": "DeepSeek V3 (Fast & Smart)" },
        "deepseek-reasoner": { "name": "DeepSeek R1 (Thinking Model)" }
      }
    }
  }
}

Save and Exit: Ctrl+O → Enter → Ctrl+X

Step 7: Create Workspace

[DISTROBOX]

mkdir -p ~/opencode_workspace
cd ~/opencode_workspace

Step 8: Launch OpenCode

[DISTROBOX]

Because we isolated the entire home directory in Step 2, we don't need complex Firejail commands. The AI is already in a padded cell.

opencode

Step 9: Save as a Golden Image

Once the container is fully configured, save it as a reusable golden image so future sessions start pre-installed without repeating Steps 4–7.

[DISTROBOX] Exit the container first:

exit

Your prompt should return to the host (e.g., justin@hostname).

[HOST] Stop the container:

distrobox stop opencode-burner

[HOST] Commit the container state to a named Podman image:

podman commit opencode-burner localhost/opencode-golden:latest

[HOST] Verify the image was created:

podman image ls | grep opencode-golden

You should see output like:

localhost/opencode-golden   latest   a1b2c3d4e5f6   2 minutes ago   1.1 GB

Part 5: Starting Sessions from the Golden Image

Each new working session creates a throwaway container from the golden image. When the session ends, delete the container — leaving no trace.

Single Session

[HOST] Create a new session container:

mkdir -p ~/opencode_burner_data_session1
distrobox create --name opencode-session-1 --image localhost/opencode-golden:latest --home ~/opencode_burner_data_session1

[HOST] Enter it:

distrobox enter opencode-session-1

[DISTROBOX] Start working immediately — everything is pre-installed:

cd ~/opencode_workspace
opencode

[HOST] When the session is done, delete the container and its data:

distrobox rm opencode-session-1
rm -rf ~/opencode_burner_data_session1

Multiple Parallel Sessions (Cloning)

Run several independent sessions at the same time from the same golden image:

[HOST]

mkdir -p ~/opencode_burner_data_{A,B,C}

distrobox create --name opencode-session-A --image localhost/opencode-golden:latest --home ~/opencode_burner_data_A
distrobox create --name opencode-session-B --image localhost/opencode-golden:latest --home ~/opencode_burner_data_B
distrobox create --name opencode-session-C --image localhost/opencode-golden:latest --home ~/opencode_burner_data_C

Each container is completely independent. Changes in session A do not affect B or C.

[HOST] List all containers:

distrobox list

[HOST] Clean up all sessions when done:

distrobox rm opencode-session-A opencode-session-B opencode-session-C
rm -rf ~/opencode_burner_data_{A,B,C}

Updating the Golden Image

[HOST] Create a temporary update container:

distrobox create --name opencode-update --image localhost/opencode-golden:latest
distrobox enter opencode-update

[DISTROBOX] Make your changes:

sudo npm update -g opencode-ai

[DISTROBOX] Exit:

exit

[HOST] Commit and clean up:

distrobox stop opencode-update
podman commit opencode-update localhost/opencode-golden:latest
distrobox rm opencode-update

Part 6: Automated Launcher (Optional)

If you get tired of typing distrobox enter every time, you can use the launch_burner.sh script (provided separately) from your [HOST] terminal. It handles the context switching automatically.

Troubleshooting

"Failed to mount /sys" or Immediate Exit

If you try to run Firejail inside Distrobox, you may see:

Warning: failed to mount /sys
Child process initialized in 91.91 ms
(Prompt returns immediately)

Cause: This is a "Nest Isolation" conflict. Firejail is trying to create a sandbox inside a container that has already virtualized the system files. Fix: Use the --home custom directory method (Part 4, Step 2). This creates a container where the entire home directory is separate, so you don't need Firejail to protect your files—they simply aren't there.

"WARN: failed to kill all processes / cgroup not exist"

When stopping a container, you may see this warning:

WARN[0000] failed to kill all processes... error="cgroup not exist"
opencode-burner

Verdict: It worked. This is a common warning in rootless containers where Distrobox cannot access system-level cgroups to force-kill background processes. The container name printed on the last line confirms it stopped successfully.

See Also