# Minimal Base Image Patterns

> Minimal Base Image Patterns

- Skill: `yanacuti1121/minimal-base-image-patterns` (Agent Skill)
- Install (CLI): `npx skillmds@latest add yanacuti1121/minimal-base-image-patterns`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yanacuti1121/minimal-base-image-patterns/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: yanacuti1121 (https://skillmd.com/u/yanacuti1121)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/yanacuti1121/minimal-base-image-patterns

---


# /minimal-base-image-patterns

## When to Use

- Sandbox needs a minimal rootfs with zero attack surface
- Reducing container startup time (< 500ms cold start)
- Building agent execution environments from scratch
- Auditing exactly which binaries are available in a sandbox

## Do NOT use for

- Environments requiring full OS tooling (use a slim distro base instead)
- Development containers (comfort > minimal attack surface there)

---

## BusyBox rootfs in 30 lines

```dockerfile
FROM busybox:1.36-uclibc AS builder

# Stage 1: assemble minimal rootfs
RUN mkdir -p /rootfs/{bin,lib,lib64,etc,proc,sys,dev,tmp,workspace} && \
    cp /bin/busybox /rootfs/bin/sh && \
    cp /bin/busybox /rootfs/bin/busybox && \
    # Install all busybox applets as symlinks
    /rootfs/bin/busybox --list | xargs -I{} ln -sf /bin/busybox /rootfs/bin/{} && \
    echo "nobody:x:65534:65534::/:/bin/sh" > /rootfs/etc/passwd && \
    echo "nobody:x:65534:"                 > /rootfs/etc/group

FROM scratch
COPY --from=builder /rootfs /
USER nobody
WORKDIR /workspace
ENTRYPOINT ["/bin/sh"]
```

---

## Distroless pattern (no shell at all)

```dockerfile
FROM golang:1.22 AS build
WORKDIR /src
COPY . .
# Build fully static binary
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /agent ./cmd/agent

FROM gcr.io/distroless/static:nonroot
COPY --from=build /agent /agent
ENTRYPOINT ["/agent"]
# No shell → shell injection impossible
# No package manager → no apt/yum install path
# Only /agent binary in PATH
```

---

## Static binary with musl (Node alternative)

```bash
# Build node binary into static executable via vercel/pkg
npx pkg \
  --targets node18-linux-x64 \
  --output agent-static \
  src/agent.js

# Package into scratch container
cat > Dockerfile.static <<'EOF'
FROM scratch
COPY agent-static /agent
COPY --from=alpine:3 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
ENTRYPOINT ["/agent"]
EOF
docker build -f Dockerfile.static -t agent:static .
```

---

## Attack surface audit

```bash
# List all binaries in an image (sorted by potential risk)
docker run --rm --entrypoint sh agent:latest -c 'find / -type f -executable 2>/dev/null | sort'

# Check dynamic libs linked (static should show nothing)
docker run --rm --entrypoint sh agent:latest -c 'ldd /agent 2>&1'

# Count attack surface (lower is better)
docker run --rm --entrypoint sh agent:latest -c 'find / -type f 2>/dev/null | wc -l'
```

---

## Size comparison

```
Approach                 Size    Shell    Package mgr
-----------------------------------------------------
Ubuntu:22.04             77MB    bash     apt
Alpine:3.19               8MB    ash      apk
BusyBox:1.36              4MB    sh       none
Distroless/static:nonroot 2MB    none     none
scratch (pure static)    ~5MB    none     none
```

---

## Anti-Fake-Pass Checklist

```
❌ Shell in final image → allows command injection via environment variables
❌ Package manager retained → attacker can install tools after entry
❌ Dynamic linking → depends on host library versions (supply chain risk)
❌ Running as root in container → UID 0 maps to root if namespace misconfigured
❌ No USER directive → defaults to root in most base images
❌ /tmp world-writable without nosuid → SUID escalation possible
❌ ca-certificates not copied → TLS validation fails, agent skips cert checks
```

