forked from fletchgqc/agentbox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
224 lines (193 loc) · 8.15 KB
/
Dockerfile
File metadata and controls
224 lines (193 loc) · 8.15 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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# AgentBox - Simplified multi-language development environment for Claude
FROM debian:trixie
# Prevent interactive prompts during installation
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
# Install system dependencies and essential tools
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
rm -f /etc/apt/apt.conf.d/docker-clean && \
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache && \
apt-get update && \
apt-get install -y --no-install-recommends \
# Essential tools
ca-certificates curl wget gnupg lsb-release sudo \
# Development tools
git vim nano tmux htop tree direnv \
# Build tools
build-essential gcc g++ make cmake pkg-config \
# Shell and utilities
zsh bash-completion locales \
# Network tools
openssh-client netcat-openbsd socat dnsutils iputils-ping \
# Archive tools
zip unzip tar gzip bzip2 xz-utils \
# JSON/YAML tools
jq yq \
# Process management
procps psmisc \
# Python build dependencies
python3-dev python3-pip python3-venv \
libssl-dev libffi-dev \
# Java dependencies
default-jdk maven gradle \
# Search tools
ripgrep fd-find && \
# Setup locale
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen && \
# Cleanup
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Install GitHub CLI
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | \
gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg && \
chmod 644 /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" \
> /etc/apt/sources.list.d/github-cli.list && \
apt-get update && \
apt-get install -y gh && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Install GitLab CLI
RUN ARCH=$(dpkg --print-architecture) && \
GLAB_VERSION=$(curl -sL "https://gitlab.com/api/v4/projects/34675721/releases/permalink/latest" | sed -n 's/.*"tag_name":"v\?\([^"]*\)".*/\1/p') && \
echo "Installing glab version ${GLAB_VERSION} for ${ARCH}" && \
curl -fsSL -o /tmp/glab.deb \
"https://gitlab.com/gitlab-org/cli/-/releases/v${GLAB_VERSION}/downloads/glab_${GLAB_VERSION}_linux_${ARCH}.deb" && \
dpkg -i /tmp/glab.deb || apt-get install -f -y && \
rm /tmp/glab.deb && \
glab --version
# Install Docker CLI
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | \
gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \
chmod 644 /usr/share/keyrings/docker-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list && \
apt-get update && \
apt-get install -y docker-ce-cli && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
docker --version
# Create non-root user
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=agent
RUN groupadd -g ${GROUP_ID} ${USERNAME} || true && \
useradd -m -u ${USER_ID} -g ${GROUP_ID} -s /bin/zsh ${USERNAME} && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME}
# Switch to user for language installations
USER ${USERNAME}
WORKDIR /home/${USERNAME}
# Install uv for Python package management
RUN curl -LsSf https://astral.sh/uv/install.sh | sh && \
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && \
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
# Install Node.js via NVM
ENV NVM_DIR="/home/${USERNAME}/.nvm"
RUN NVM_VERSION=$(curl -s https://api.github.com/repos/nvm-sh/nvm/releases/latest | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') && \
echo "Installing nvm version ${NVM_VERSION}" && \
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh | bash && \
. "$NVM_DIR/nvm.sh" && \
nvm install --lts && \
nvm alias default node && \
nvm use default
# Setup NVM in bash only (zsh will be set up after oh-my-zsh)
RUN echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.bashrc && \
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.bashrc && \
echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> ~/.bashrc
# Install Node.js global packages
RUN bash -c "source $NVM_DIR/nvm.sh && \
npm install -g \
typescript \
@types/node \
ts-node \
eslint \
prettier \
nodemon \
yarn \
pnpm"
# Install SDKMAN for Java toolchain management
RUN curl -s "https://get.sdkman.io?rcupdate=false" | bash && \
echo 'source "$HOME/.sdkman/bin/sdkman-init.sh"' >> ~/.bashrc && \
echo 'source "$HOME/.sdkman/bin/sdkman-init.sh"' >> ~/.zshrc && \
bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && \
sdk install java 21.0.9-tem && \
sdk install gradle"
# Setup Python tools
RUN /home/${USERNAME}/.local/bin/uv tool install black && \
/home/${USERNAME}/.local/bin/uv tool install ruff && \
/home/${USERNAME}/.local/bin/uv tool install mypy && \
/home/${USERNAME}/.local/bin/uv tool install pytest && \
/home/${USERNAME}/.local/bin/uv tool install ipython && \
/home/${USERNAME}/.local/bin/uv tool install poetry && \
/home/${USERNAME}/.local/bin/uv tool install pipenv
# Install oh-my-zsh for better shell experience and setup NVM for zsh
RUN sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended && \
sed -i 's/ZSH_THEME=".*"/ZSH_THEME="robbyrussell"/' ~/.zshrc && \
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && \
echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrc && \
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.zshrc && \
echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> ~/.zshrc
# Setup direnv hooks for automatic .envrc loading
RUN echo 'eval "$(direnv hook bash)"' >> ~/.bashrc && \
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc
# Add terminal size handling for better TTY support (from ClaudeBox)
RUN cat >> ~/.zshrc <<'EOF'
if [[ -n "$PS1" ]] && command -v stty >/dev/null; then
function _update_size {
local rows cols
{ stty size } 2>/dev/null | read rows cols
((rows)) && export LINES=$rows COLUMNS=$cols
}
TRAPWINCH() { _update_size }
_update_size
fi
EOF
# Configure git
RUN git config --global init.defaultBranch main && \
git config --global pull.rebase false
# Setup tmux configuration
RUN cat > ~/.tmux.conf <<'EOF'
# Enable mouse support
set -g mouse on
# Better colors
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",xterm-256color:Tc"
# Increase history
set -g history-limit 50000
# Better window/pane management
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %
# Reload config
bind r source-file ~/.tmux.conf \; display-message "Config reloaded!"
# Status bar
set -g status-bg black
set -g status-fg white
set -g status-left '#[fg=green]#H '
set -g status-right '#[fg=yellow]%Y-%m-%d %H:%M'
EOF
# Switch back to root for entrypoint setup
USER root
# Copy entrypoint script
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# Set the user for runtime
USER ${USERNAME}
# Using BUILD_TIMESTAMP as a build arg that changes on every invocation invalidates
# Docker's cache for this layer and following layers, forcing reinstall even when
# Dockerfile hasn't changed. This ensures fresh installs on explicit rebuilds instead
# of relying on unpredictable auto-update timing.
ARG BUILD_TIMESTAMP=unknown
RUN curl -fsSL https://claude.ai/install.sh | bash -s stable && \
zsh -i -c 'which claude && claude --version'
RUN curl -fsSL https://opencode.ai/install | bash && \
zsh -i -c 'which opencode && opencode --version'
# Entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["/bin/zsh"]