-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
161 lines (135 loc) · 6.9 KB
/
Dockerfile
File metadata and controls
161 lines (135 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# Agent container: Ubuntu 24.04 with all AI CLI tools and dev environment.
# Two-stage build: builder installs toolchains, runtime copies only artifacts.
# --- Stage 1: Builder ---
FROM ubuntu:24.04@sha256:d1e2e92c075e5ca139d51a140fff46f84315c0fdce203eab2807c7e495eff4f9 AS builder
# Prevent interactive prompts during package installation.
ENV DEBIAN_FRONTEND=noninteractive
# System packages needed for build-time fetches.
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends \
bash \
ca-certificates \
curl \
git \
python3 \
unzip \
wget \
zsh
# Node.js 22 LTS (required by gemini-cli, codex — need >= 20).
# hadolint ignore=DL3008
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends nodejs
# uv (Python tooling) — COPY layers are very cacheable.
COPY --from=ghcr.io/astral-sh/uv:0.10.10 /uv /usr/local/bin/uv
# AI CLI tools via npm (pinned versions — cache-friendly, install before git clones).
# Override with: docker build --build-arg CLAUDE_CODE_VERSION=2.2.0 ...
# Or: devbox rebuild (picks up latest Dockerfile defaults from devbox update).
ARG OPENCODE_VERSION=1.2.26
ARG CLAUDE_CODE_VERSION=2.1.89
ARG GEMINI_CLI_VERSION=0.33.1
ARG CODEX_VERSION=0.114.0
ARG GSD_OPENCODE_VERSION=1.22.1
ARG RALPHX_VERSION=0.1.0
RUN --mount=type=cache,target=/root/.npm,sharing=locked \
npm install -g --omit=dev opencode-ai@${OPENCODE_VERSION} \
@google/gemini-cli@${GEMINI_CLI_VERSION} @openai/codex@${CODEX_VERSION} \
@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION} \
gsd-opencode@${GSD_OPENCODE_VERSION} \
ralphx@${RALPHX_VERSION}
# GitHub CLI.
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
| dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
| tee /etc/apt/sources.list.d/github-cli.list \
&& apt-get update && apt-get install -y --no-install-recommends gh
# Oh My Zsh + common plugins (external git repos — least cacheable, last).
# p10k is deliberately excluded — the default devbox prompt is minimal.
# Users who want p10k can install it via their private overlay Dockerfile.
RUN git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git /root/.oh-my-zsh \
&& git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git \
/root/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting \
&& git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions.git \
/root/.oh-my-zsh/custom/plugins/zsh-autosuggestions
# --- Stage 2: Runtime ---
FROM ubuntu:24.04@sha256:d1e2e92c075e5ca139d51a140fff46f84315c0fdce203eab2807c7e495eff4f9
ARG DEVBOX_VERSION=0.3.0
LABEL org.opencontainers.image.title="devbox-agent" \
org.opencontainers.image.version="${DEVBOX_VERSION}"
ENV DEBIAN_FRONTEND=noninteractive
# Install curl + ca-certificates first (needed for NodeSource setup).
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl
# Node.js 22 LTS (runtime needs node for npm global binaries).
# hadolint ignore=DL3008
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends nodejs
# Runtime-only system packages.
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends \
bash \
delta \
fzf \
git \
gosu \
iproute2 \
iptables \
jq \
neovim \
python3 \
sqlite3 \
tmux \
zsh
# Create non-root user for running the agent after firewall setup.
# Fixed UID/GID 1000 — must match the tmpfs uid/gid in docker-compose.yml.
# Ubuntu 24.04 ships with a 'ubuntu' user/group at 1000; remove it first.
RUN (getent group 1000 | cut -d: -f1 | xargs -r groupdel) 2>/dev/null; \
(getent passwd 1000 | cut -d: -f1 | xargs -r userdel) 2>/dev/null; \
groupadd -g 1000 devbox && useradd -u 1000 -g devbox -m -d /home/devbox -s /bin/zsh devbox \
&& usermod -aG tty devbox
# --- Copy artifacts from builder ---
# Oh My Zsh framework — installed to /opt (read-only rootfs safe).
# The ZSH env var in .zshrc points here instead of ~/.oh-my-zsh.
COPY --from=builder /root/.oh-my-zsh /opt/oh-my-zsh
RUN chown -R devbox:devbox /opt/oh-my-zsh
# npm global packages (includes OpenCode, Gemini CLI, Codex, Claude Code, etc.).
COPY --from=builder /usr/lib/node_modules /usr/lib/node_modules
COPY --from=builder /usr/bin/opencode /usr/bin/gemini /usr/bin/codex /usr/bin/claude /usr/bin/gsd-opencode /usr/bin/
# ralphx uses relative imports — needs a wrapper that runs from its package dir.
RUN printf '#!/bin/sh\nexec node /usr/lib/node_modules/ralphx/dist/cli/index.js "$@"\n' > /usr/bin/ralphx \
&& chmod +x /usr/bin/ralphx
# GitHub CLI keyring + binary.
COPY --from=builder /usr/share/keyrings/githubcli-archive-keyring.gpg /usr/share/keyrings/githubcli-archive-keyring.gpg
COPY --from=builder /usr/bin/gh /usr/bin/gh
# uv binary.
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
# --- Shell configuration ---
# Default configs go to /etc/skel so user-setup.sh can populate the tmpfs home.
COPY templates/zshrc /etc/skel/.zshrc
COPY templates/tmux.conf /etc/skel/.tmux.conf
# --- Library scripts, profiles, and templates ---
COPY lib/firewall.sh /usr/local/lib/devbox/firewall.sh
COPY tooling/profiles/ /usr/local/lib/devbox/profiles/
COPY templates/ralphx-audit/ /usr/local/share/devbox/templates/ralphx-audit/
# --- cmux helpers (notifications via OSC 777, status via proxy) ---
COPY tooling/devbox-notify tooling/devbox-cmux-send tooling/devbox-status tooling/devbox-claude-hook /usr/local/bin/
RUN chmod +x /usr/local/bin/devbox-notify /usr/local/bin/devbox-cmux-send /usr/local/bin/devbox-status /usr/local/bin/devbox-claude-hook
# --- Default Claude Code hooks (cmux notifications on Stop, Permission, etc.) ---
COPY templates/claude-hooks.json /etc/skel/.claude/settings.json
# --- Entrypoint ---
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
COPY user-setup.sh /usr/local/bin/user-setup.sh
RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/user-setup.sh
WORKDIR /workspace
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# Default: hold container open as isolated dev environment.
# Users exec into it: docker compose exec agent gosu devbox claude