Skip to content
Merged
27 changes: 22 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,16 @@ RUN mkdir -p /home/linuxbrew \
&& rm -rf /home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-core

# 1.5. mise — dev tool manager; pre-approved tools defined in the global config
# auto-install via Homebrew backend on first use at runtime.
# auto-install via zerobrew backend on first use at runtime.
RUN curl -fsSL https://mise.run | MISE_INSTALL_PATH=/usr/local/bin/mise sh \
&& mkdir -p /opt/mise \
&& MISE_DATA_DIR=/opt/mise mise plugins install brew https://github.com/woutermont/mise-brew
&& MISE_DATA_DIR=/opt/mise mise plugins install zerobrew https://github.com/kennyg/mise-zerobrew \
&& sed -i '/quoted_path .. " install /i\ cmd.exec(quoted_zb .. " --root " .. quoted_path .. " init")' /opt/mise/plugins/zerobrew/hooks/backend_install.lua

# 1.6. zerobrew — fast Homebrew alternative; used as mise backend
RUN sudo -u opencode HOME=/home/opencode NONINTERACTIVE=1 /bin/bash -c " \
curl -fsSL https://zerobrew.rs/install | bash -s -- --no-modify-path \
"

ARG OPENCODE_VERSION

Expand All @@ -85,7 +91,7 @@ FROM base
ARG OPENCODE_VERSION
ARG IMAGE_CREATED

ENV PATH=/home/opencode/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/opt/auto-install-shims:${PATH}
ENV PATH=/home/opencode/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/opencode/.local/share/zerobrew/prefix/bin:/opt/auto-install-shims:${PATH}
ENV HOMEBREW_NO_AUTO_UPDATE=1
ENV HOMEBREW_INSTALL_FROM_API=1
ENV MISE_DATA_DIR=/opt/mise
Expand Down Expand Up @@ -114,9 +120,14 @@ COPY --from=builder /usr/local/bin/mise /usr/local/bin/mise
COPY --from=builder --chown=opencode:opencode /opt/mise /opt/mise
COPY mise-config.toml /etc/mise/config.toml

# Zerobrew — fast Homebrew alternative; mise zerobrew backend.
COPY --from=builder /home/opencode/.local/bin/zb /usr/local/bin/zb
COPY --from=builder /home/opencode/.local/bin/zbx /usr/local/bin/zbx
COPY --from=builder --chown=opencode:opencode /home/opencode/.local/share/zerobrew /home/opencode/.local/share/zerobrew

# Verify runtime and set up login-shell PATH and auto-install handler
RUN opencode --version \
&& printf 'for d in "$HOME/.local/bin" "/home/linuxbrew/.linuxbrew/bin" "/home/linuxbrew/.linuxbrew/sbin"; do case ":$PATH:" in *":$d:"*) ;; *) PATH="$d:$PATH";; esac; done\nexport PATH\n' > /etc/profile.d/brew-path.sh \
&& printf 'for d in "$HOME/.local/bin" "/home/linuxbrew/.linuxbrew/bin" "/home/linuxbrew/.linuxbrew/sbin" "$HOME/.local/share/zerobrew/prefix/bin"; do case ":$PATH:" in *":$d:"*) ;; *) PATH="$d:$PATH";; esac; done\nexport PATH\n' > /etc/profile.d/brew-path.sh \
&& chmod 0644 /etc/profile.d/brew-path.sh \
&& printf '\neval "$(mise activate bash)"\n' >> /home/opencode/.bashrc \
&& printf '\neval "$(mise activate zsh)"\n' >> /home/opencode/.zshrc \
Expand All @@ -126,7 +137,13 @@ RUN opencode --version \
&& mkdir -p /opt/auto-install-shims \
&& grep -E '^\s*"' /etc/mise/config.toml | while IFS='=' read -r key value; do \
key="$(echo "$key" | tr -d ' "')" \
&& shim="${key#*:}" \
&& shim="$(echo "$value" | sed -n 's/.*# shim:\([^ ]*\).*/\1/p')" \
&& if [ -z "$shim" ]; then \
case "$key" in \
github:*) shim="${key##*/}" ;; \
*) shim="${key#*:}" ;; \
esac; \
fi \
&& printf '#!/usr/bin/env bash\nexec /usr/local/bin/mise exec "%s" -- %s "$@"\n' "$key" "$shim" > "/opt/auto-install-shims/$shim" \
&& chmod 0755 "/opt/auto-install-shims/$shim"; \
done \
Expand Down
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,29 @@ A general-purpose Ubuntu Docker image for running [opencode](https://github.com/
| **Build tools** | `build-essential`, `pkg-config` (for native npm addons, pip source builds) |
| **Python 3** | Lazy-installed via mise (see table below) |
| **Homebrew** | Linux-native Homebrew (`/home/linuxbrew/.linuxbrew`) — `brew` on PATH |
| **mise** | Dev tool manager — tools listed below install on first use via `brew` backend |
| **zerobrew** | Faster Homebrew alternative (`zb` on PATH) -- used as mise backend for lazy-installed tools |
| **mise** | Dev tool manager — tools listed below install on first use via `zerobrew` backend |
| **CLI utilities** | git, curl, jq, less, unzip, ssh client |
| **Init** | tini as PID 1 (zombie reaping, clean shutdown) |

### Lazy-installed tools

These tools install on first use (via mise → Homebrew):
These tools install on first use (via mise → github/zerobrew):

| Tool | Command | Backend |
|---|---|---|
| GitHub CLI | `gh` | brew |
| GitLab CLI | `glab` | brew |
| Ruby | `ruby` | brew |
| ripgrep | `rg` | brew |
| fd | `fd` | brew |
| Wget | `wget` | brew |
| Vim | `vim` | brew |
| Micro | `micro` | brew |
| Nano | `nano` | brew |
| Python 3 | `python3` | brew |
| Node.js | `node` | brew |
| GitHub CLI | `gh` | github |
| GitLab CLI | `glab` | zerobrew |
| Ruby | `ruby` | zerobrew |
| ripgrep | `rg` | github |
| fd | `fd` | github |
| Wget | `wget` | zerobrew |
| Vim | `vim` | zerobrew |
| Micro | `micro` | github |
| Nano | `nano` | zerobrew |
| Python 3 | `python3` | zerobrew |
| Node.js | `node` | github |
| Sapling | `sl` | github |

The image ships with a system config at `/etc/mise/config.toml` with these pre-approved tools. Users can add or override tools by creating `~/.config/mise/config.toml` — mise merges both.

Expand Down Expand Up @@ -109,4 +111,5 @@ Fetches the latest release from [anomalyco/opencode](https://github.com/anomalyc
- `~/.local/bin` is on PATH and user-writable, useful for dropping custom tools at runtime.
- Node version can be switched at runtime with `n <version>` (e.g. `n lts`).
- Homebrew is installed under `/home/linuxbrew/.linuxbrew` (outside the persistent volume). It uses its bundled portable Ruby — no system Ruby needed.
- **Lazy-installed tools** (see table above): run any listed tool and mise auto-installs it via Homebrew on first use. The image ships defaults in `/etc/mise/config.toml`; create `~/.config/mise/config.toml` to add your own — mise merges both.
- Zerobrew (`zb`) is installed at `/usr/local/bin/zb` with its prefix at `~/.local/share/zerobrew/prefix` on PATH for accessing formula binaries.
- **Lazy-installed tools** (see table above): run any listed tool and mise auto-installs it via zerobrew or github backend on first use. The image ships defaults in `/etc/mise/config.toml`; create `~/.config/mise/config.toml` to add your own — mise merges both.
23 changes: 12 additions & 11 deletions mise-config.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[tools]
"brew:gh" = "latest"
"brew:glab" = "latest"
"brew:ruby" = "latest"
"brew:ripgrep" = "latest"
"brew:fd" = "latest"
"brew:wget" = "latest"
"brew:vim" = "latest"
"brew:micro" = "latest"
"brew:nano" = "latest"
"brew:python" = "latest"
"brew:node" = "latest"
"github:cli/cli" = "latest" # shim:gh
"zerobrew:glab" = "latest"
"zerobrew:ruby" = "latest"
"github:BurntSushi/ripgrep" = "latest" # shim:rg
"github:sharkdp/fd" = "latest"
"zerobrew:wget" = "latest"
"zerobrew:vim" = "latest"
"github:zyedidia/micro" = "latest"
"zerobrew:nano" = "latest"
"zerobrew:python" = "latest"
"github:nodejs/node" = "latest"
"github:facebook/sapling" = "latest" # shim:sl
Loading