lvwerra HF Staff Claude Fable 5 commited on
Commit
77658da
·
1 Parent(s): 5bfc1c8

Bake the QoL toolchain into the image

Browse files

Everyday tools agents and humans kept missing: jq, htop, lsof, tree,
ncdu, sqlite3, vim/nano, zip/unzip, file, watch, less, ffmpeg,
imagemagick, gh (GitHub CLI), git-lfs, plus fonts so headless
screenshots don't render tofu. Git gets system-level defaults
(safe.directory for the FUSE bucket, default branch, fallback
identity) that the operator's own config still overrides.

Playwright's headless Chromium is preinstalled with system deps at a
shared world-writable PLAYWRIGHT_BROWSERS_PATH, so node and python
playwright work with zero downloads. The default python3 becomes a
dedicated /opt/py venv (system python stays PEP-668 clean) shipping
numpy, pandas, matplotlib (MPLBACKEND=Agg), seaborn, requests, pillow,
huggingface_hub and ipython; login shells keep it on PATH.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Files changed (1) hide show
  1. Dockerfile +45 -5
Dockerfile CHANGED
@@ -11,10 +11,32 @@ RUN npm run build
11
  FROM node:22-bookworm AS runtime
12
 
13
  # System deps: tmux (session durability), git, build tools (node-pty native build),
14
- # ripgrep (used by the coding CLIs), curl/ca-certs.
 
 
15
  RUN apt-get update && apt-get install -y --no-install-recommends \
16
- tmux git ca-certificates curl python3 make g++ ripgrep bubblewrap rsync \
17
- && rm -rf /var/lib/apt/lists/*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  ENV LANG=C.UTF-8
20
 
@@ -45,18 +67,36 @@ RUN env UV_TOOL_BIN_DIR=/usr/local/bin UV_TOOL_DIR=/opt/uv-tools \
45
  uv tool install --python /usr/bin/python3 "huggingface_hub[cli]" \
46
  || echo "hf cli install failed"
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  # Login shells source /etc/profile, which RESETS PATH — dropping the build-time
49
  # ~/.local/bin and the user-install dirs under $AM_LOCAL (pip --user, npm
50
  # prefix). profile.d runs after that reset, so restore them here.
51
  RUN printf '%s\n' \
52
- 'PATH="/home/node/.local/bin:$PATH"' \
53
  '[ -n "$AM_LOCAL" ] && PATH="$AM_LOCAL/py/bin:$AM_LOCAL/npm/bin:$AM_LOCAL/bin:$PATH"' \
54
  'export PATH' \
55
  > /etc/profile.d/agent-manager.sh
56
 
57
  # Non-root user: the node base image already ships uid 1000 as "node" (HF runs as uid 1000).
58
  ENV HOME=/home/node
59
- ENV PATH=/home/node/.local/bin:$PATH
60
  WORKDIR /app
61
  RUN chown node:node /app
62
 
 
11
  FROM node:22-bookworm AS runtime
12
 
13
  # System deps: tmux (session durability), git, build tools (node-pty native build),
14
+ # ripgrep (used by the coding CLIs), curl/ca-certs — plus everyday QoL tools
15
+ # agents and humans reach for (jq/htop/sqlite3/editors/media, fonts so headless
16
+ # Chromium screenshots don't render tofu).
17
  RUN apt-get update && apt-get install -y --no-install-recommends \
18
+ tmux git git-lfs ca-certificates curl python3 make g++ ripgrep bubblewrap rsync \
19
+ jq htop lsof tree ncdu sqlite3 vim nano zip unzip file procps less \
20
+ ffmpeg imagemagick fonts-liberation fonts-noto-color-emoji \
21
+ && rm -rf /var/lib/apt/lists/* \
22
+ && git lfs install --system
23
+
24
+ # Git defaults every agent benefits from: the FUSE bucket trips "dubious
25
+ # ownership" without safe.directory, and commits die without an identity —
26
+ # these are SYSTEM level, so anything the operator sets globally still wins.
27
+ RUN git config --system safe.directory '*' \
28
+ && git config --system init.defaultBranch main \
29
+ && git config --system user.name 'Agent Manager' \
30
+ && git config --system user.email 'agents@agent-manager.local'
31
+
32
+ # GitHub CLI (auths from a GH_TOKEN Space secret automatically).
33
+ RUN mkdir -p -m 755 /etc/apt/keyrings \
34
+ && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg -o /etc/apt/keyrings/githubcli-archive-keyring.gpg \
35
+ && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
36
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list \
37
+ && apt-get update && apt-get install -y --no-install-recommends gh \
38
+ && rm -rf /var/lib/apt/lists/* \
39
+ || echo "gh install failed"
40
 
41
  ENV LANG=C.UTF-8
42
 
 
67
  uv tool install --python /usr/bin/python3 "huggingface_hub[cli]" \
68
  || echo "hf cli install failed"
69
 
70
+ # Headless Chromium for Playwright, shared by every agent and both language
71
+ # bindings via PLAYWRIGHT_BROWSERS_PATH (world-writable so a binding pinned to
72
+ # a different build can add its revision without root).
73
+ ENV PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers
74
+ RUN npx -y playwright install --with-deps chromium \
75
+ && chmod -R a+rwX /opt/pw-browsers \
76
+ || echo "playwright chromium install failed"
77
+
78
+ # Batteries-included default python: a dedicated venv first on PATH (system
79
+ # python stays apt-owned/PEP-668 clean). One-off scripts get the data stack
80
+ # without setup; real projects still build their own uv env on $AM_LOCAL.
81
+ RUN uv venv /opt/py \
82
+ && uv pip install --python /opt/py/bin/python \
83
+ numpy pandas matplotlib seaborn requests pillow huggingface_hub ipython \
84
+ && chmod -R a+rX /opt/py \
85
+ || echo "python stack install failed"
86
+ ENV MPLBACKEND=Agg
87
+
88
  # Login shells source /etc/profile, which RESETS PATH — dropping the build-time
89
  # ~/.local/bin and the user-install dirs under $AM_LOCAL (pip --user, npm
90
  # prefix). profile.d runs after that reset, so restore them here.
91
  RUN printf '%s\n' \
92
+ 'PATH="/home/node/.local/bin:/opt/py/bin:$PATH"' \
93
  '[ -n "$AM_LOCAL" ] && PATH="$AM_LOCAL/py/bin:$AM_LOCAL/npm/bin:$AM_LOCAL/bin:$PATH"' \
94
  'export PATH' \
95
  > /etc/profile.d/agent-manager.sh
96
 
97
  # Non-root user: the node base image already ships uid 1000 as "node" (HF runs as uid 1000).
98
  ENV HOME=/home/node
99
+ ENV PATH=/home/node/.local/bin:/opt/py/bin:$PATH
100
  WORKDIR /app
101
  RUN chown node:node /app
102