<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Max</title>
    <description>The latest articles on Forem by Max (@mazumba).</description>
    <link>https://forem.com/mazumba</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3857557%2F6da18f7f-737d-4f81-a7e0-a79bf8e4faa6.png</url>
      <title>Forem: Max</title>
      <link>https://forem.com/mazumba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mazumba"/>
    <language>en</language>
    <item>
      <title>Run OpenCode in Docker - Clean machine, same convenience</title>
      <dc:creator>Max</dc:creator>
      <pubDate>Thu, 02 Apr 2026 12:55:03 +0000</pubDate>
      <link>https://forem.com/mazumba/run-opencode-in-docker-clean-machine-same-convenience-58ac</link>
      <guid>https://forem.com/mazumba/run-opencode-in-docker-clean-machine-same-convenience-58ac</guid>
      <description>&lt;p&gt;I didn't want another tool installed globally on my machine, so I containerized &lt;a href="https://opencode.ai" rel="noopener noreferrer"&gt;OpenCode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The result: &lt;strong&gt;&lt;a href="https://github.com/mazumba/opencode-dockerized" rel="noopener noreferrer"&gt;opencode-dockerized&lt;/a&gt;&lt;/strong&gt; - a Docker Compose setup that runs OpenCode web in a container with the Docker CLI and mounted socket, so it can still manage containers on your host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why bother Dockerizing it?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;No global installs or version conflicts on your local machine&lt;/li&gt;
&lt;li&gt;Same environment everywhere, easy to share with a team&lt;/li&gt;
&lt;li&gt;OpenCode config and auth live inside the project, not scattered across &lt;code&gt;~/.local/share&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The setup is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build once&lt;/span&gt;
make opencode-build

&lt;span class="c"&gt;# Run&lt;/span&gt;
make opencode-run
&lt;span class="c"&gt;# → http://localhost:4096&lt;/span&gt;

&lt;span class="c"&gt;# Tear down&lt;/span&gt;
make opencode-down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trickier parts are handled automatically:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker socket access&lt;/strong&gt; - The container mounts &lt;code&gt;/var/run/docker.sock&lt;/code&gt; so opencode can run Docker commands on the host. The entrypoint detects the socket's GID at runtime and adds the &lt;code&gt;opencode&lt;/code&gt; user to that group before dropping privileges. No manual config needed, works on both macOS (Docker Desktop) and Linux.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UID/GID matching&lt;/strong&gt; - The container runs as a non-root user with your host's &lt;code&gt;UID&lt;/code&gt;/&lt;code&gt;GID&lt;/code&gt;, detected automatically by the Makefile. Files created inside the container have the right ownership on the host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth persistence&lt;/strong&gt; - Credentials are written to &lt;code&gt;.opencode/share/auth.json&lt;/code&gt; (gitignored). If you're already authenticated locally, you can just copy your existing &lt;code&gt;auth.json&lt;/code&gt; in and skip the login flow entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not
&lt;/h2&gt;

&lt;p&gt;This setup does not provide meaningful isolation from the host. Mounting the Docker socket gives the container full access to the host Docker daemon.&lt;/p&gt;




&lt;h2&gt;
  
  
  Some features for my own convenience (and maybe yours?)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The RPI workflow
&lt;/h3&gt;

&lt;p&gt;The repo ships slash commands that implement a &lt;strong&gt;Research → Plan → Implement&lt;/strong&gt; workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/research &amp;lt;task&amp;gt;&lt;/code&gt; - explores the codebase, writes a research doc to &lt;code&gt;docs/thoughts/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/deep-research &amp;lt;task&amp;gt;&lt;/code&gt; - same, but uses Claude Opus for harder problems&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plan &amp;lt;artifact-folder&amp;gt;&lt;/code&gt; - turns the research doc into a numbered implementation plan&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/implement &amp;lt;artifact-folder&amp;gt;&lt;/code&gt; - executes the plan step by step and runs a quality gate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each phase is intentionally scoped: research never touches code, plan never touches code, implement follows the plan exactly.&lt;/p&gt;




&lt;h3&gt;
  
  
  Create Skills - persistent domain knowledge - via command
&lt;/h3&gt;

&lt;p&gt;Skills are folders under &lt;code&gt;.opencode/skills/&amp;lt;skill-name&amp;gt;/&lt;/code&gt; that the model loads on demand. Each one contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SKILL.md&lt;/code&gt; - reference facts: file paths, data shapes, API shapes, naming rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GOTCHAS.md&lt;/code&gt; - accumulated failure points and fixes, never deleted&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HISTORY.md&lt;/code&gt; - append-only change log, one entry per session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assets/&lt;/code&gt; and &lt;code&gt;scripts/&lt;/code&gt; - templates and helper scripts the agent can run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Scaffold a new skill with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/skill billing-lib "Internal billing library - edge cases, footguns, charge flow"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Domain knowledge accumulates over time in version-controlled files rather than disappearing at the end of a chat session.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it!
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/mazumba/opencode-dockerized
&lt;span class="nb"&gt;cp &lt;/span&gt;compose.override.yml.dist compose.override.yml
&lt;span class="c"&gt;# Set your projects path in compose.override.yml&lt;/span&gt;
make opencode-build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make opencode-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Would love feedback, especially if you run it on a setup I haven't tested. PRs and issues welcome!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
