< Back to all hacks

#28 Proot Rootfs Diet (741 -> 550 MB)

Debloat
Problem
Proot Ubuntu rootfs bloated at 741 MB. Most space wasted on things OpenClaw never touches.
Solution
Removed Node headers (65 MB), Python (52 MB), locales (37 MB), i18n (18 MB), man/docs (23 MB).
Lesson
Don't delete /usr/lib/arm-linux-gnueabihf/ — contains libc, libssl, libz needed by Node.js.

Context

The PocketClaw proot stack uses an Ubuntu 25.10 ARM rootfs installed via proot-distro. Out of the box, this rootfs weighs 741 MB on disk. The Moto E2 has approximately 4 GB of usable internal storage, and with Termux, its packages, the OpenClaw npm install, and the rootfs, disk space was critically tight.

Most of that 741 MB is dead weight. OpenClaw is a pure Node.js application. It does not compile native modules (no node-gyp), does not run Python scripts, does not display man pages, and runs headless with no locale rendering. Every MB on disk that serves no purpose is a MB that could be used for npm cache, logs, or V8 compile cache.

The rootfs lives at $PREFIX/var/lib/proot-distro/installed-rootfs/ubuntu/. All paths below are relative to this root.

Implementation

Each removal was done carefully, with a gateway restart after each to verify nothing broke.

ROOTFS="$PREFIX/var/lib/proot-distro/installed-rootfs/ubuntu"

# 1. Node.js C++ headers (65 MB)
# These are the V8 and Node.js header files for compiling native addons.
# OpenClaw uses zero native addons — everything is pure JS/WASM.
rm -rf $ROOTFS/usr/include/node/

# 2. Python 3.13 (52 MB)
# Installed by Ubuntu as a default package. OpenClaw never imports Python.
# Careful: do NOT remove /usr/bin/python3 symlink until you verify
# nothing in the boot chain uses it.
rm -rf $ROOTFS/usr/lib/python3.13/
rm -rf $ROOTFS/usr/lib/python3/
rm -f $ROOTFS/usr/bin/python3 $ROOTFS/usr/bin/python3.13

# 3. Locale files (37 MB)
# Full locale definitions for every language. Inside proot there is no
# terminal locale rendering — everything is UTF-8 by default.
rm -rf $ROOTFS/usr/lib/locale/
rm -rf $ROOTFS/usr/share/locale/

# 4. i18n data (18 MB)
# Internationalization character maps and repertoire files.
# Node.js uses ICU internally (compiled in), not system i18n.
rm -rf $ROOTFS/usr/share/i18n/

# 5. Man pages (11 MB)
# No one runs man on a headless phone server.
rm -rf $ROOTFS/usr/share/man/

# 6. Documentation (12 MB)
# Package documentation, changelogs, READMEs.
rm -rf $ROOTFS/usr/share/doc/

Verification

# Check new rootfs size:
du -sh $ROOTFS
# Expected: ~550 MB (down from 741 MB)

# Verify Node.js still runs:
proot-distro login ubuntu -- node --version
# Expected: v22.12.0

# Verify the gateway boots:
proot-distro login ubuntu -- bash -c ". /root/.openclaw/env && node dist/cli.js gateway run --port 9000" &
sleep 30
curl -s http://localhost:9000/api/status
# Expected: JSON response

# Verify no broken shared library deps:
proot-distro login ubuntu -- ldd /usr/local/bin/node | grep "not found"
# Expected: no output (all libs resolved)

Gotchas

  • NEVER delete /usr/lib/arm-linux-gnueabihf/. This directory contains the ARM shared libraries that Node.js dynamically links against: libc, libpthread, libssl, libcrypto, libz, libstdc++. Deleting it kills Node.js instantly with a linker error
  • Do not remove /usr/share/zoneinfo/ (3 MB). Node.js uses system timezone data for Intl.DateTimeFormat and Date operations. Removing it causes timezone-dependent code to fall back to UTC silently
  • Do not remove /etc/ files carelessly. /etc/resolv.conf is needed for DNS resolution inside proot, and /etc/ssl/certs/ is needed for HTTPS connections to LLM providers
  • Python removal breaks apt inside the rootfs (apt is Python-based in modern Ubuntu). After removing Python, you can no longer install new packages via apt. This is acceptable if the rootfs is finalized, but make sure everything you need is already installed
  • The 195 MB savings is on disk, not RAM. Proot does not load the entire rootfs into memory. However, less disk usage means less inode overhead and faster du/find operations that some monitoring tools may trigger

Result

Component RemovedSize FreedRisk Level
Node.js C++ headers65 MBNone (no native addons)
Python 3.1352 MBLow (breaks apt only)
Locale files37 MBNone (no locale rendering)
i18n data18 MBNone (Node uses ICU)
Man pages11 MBNone (headless)
Documentation12 MBNone (headless)
Total195 MB

Rootfs went from 741 MB to 550 MB. This was later followed by Hack #29 (Deep Rootfs Diet) which cut even further. Eventually the entire proot rootfs became obsolete when the native node22-icu build (Hack #12) eliminated the need for proot entirely. The rootfs is now a 967 MB legacy artifact scheduled for deletion.