The smallest production-ready Bun Docker image. Multi-arch (amd64 + arm64), published to Docker Hub and GitHub Container Registry.
| Variant | Image Size | Description |
|---|---|---|
webtreeofficial/bun-nano:latest |
42.5 MB | Alpine + musl Bun binary |
webtreeofficial/bun-nano:upx |
29.8 MB | Same + UPX compression (~250ms cold start) |
Compare to official oven/bun:1: 88.8 MB (Debian), oven/bun:1-alpine: 110+ MB.
Docker Hub:
FROM webtreeofficial/bun-nano:latest
COPY package.json bun.lock* ./
RUN bun install --production
COPY . .
CMD ["bun", "run", "server.ts"]GitHub Container Registry:
FROM ghcr.io/web-tree/bun-nano:latestUPX variant (smallest):
FROM webtreeofficial/bun-nano:upxImages follow Bun's version scheme. Available on both registries:
webtreeofficial/bun-nano:<tag>(Docker Hub)ghcr.io/web-tree/bun-nano:<tag>(GHCR)
| Tag | Description |
|---|---|
1.3.12 |
Specific Bun version |
1.3 |
Latest patch in 1.3.x |
1 |
Latest in 1.x |
latest |
Latest release |
1.3.12-upx |
UPX-compressed, specific version |
1.3-upx |
UPX-compressed, latest patch in 1.3.x |
upx |
UPX-compressed, latest |
- Downloads the musl build of Bun from GitHub releases (multi-arch)
- Runs on plain
alpine:3.21with onlylibstdc++added - Non-root
bunuser (UID 1000) - UPX variant compresses the binary with LZMA (
--all-methods)
A daily cron job checks for new Bun releases. When a new version is detected:
check-bun-release.ymlcreates a git tagv{VERSION}release.ymltriggers, builds both variants for both architectures- Pushes to Docker Hub and GHCR
Manual releases: gh workflow run release.yml -f bun_version=1.3.12
Tested with real-world frameworks on the compile-scratch approach (see tests/):
| Framework | Status | Notes |
|---|---|---|
| Elysia | works | Bun-native, REST + params + JSON |
| Hono | works | Cross-runtime |
| Express 5 | works | Node.js compat layer |
| Built-in fetch | works | Outbound HTTPS (CA certs embedded) |
| WebSocket + fs | works | File I/O, WebSocket server |
- Native
.nodeaddons will not work (use pure-JS alternatives) - Runtime-computed
require()paths may silently fail withbun build --compile import.meta.urlfor asset resolution breaks in compiled binaries
If you use bun build --compile, you can skip the base image entirely and use a scratch-based approach. See dockerfiles/Dockerfile.compile-scratch-upx — this produces a 26.3 MB image for compiled apps.
# Build with docker bake
docker buildx bake local --load
# Build all variants
docker buildx bake
# Test
docker run --rm bun-nano:local --version
docker run --rm bun-nano:local -e "console.log('hello')"| Secret | Description |
|---|---|
DOCKERHUB_USERNAME |
Docker Hub username |
DOCKERHUB_TOKEN |
Docker Hub access token |
GITHUB_TOKEN is provided automatically for GHCR.
Inspired by Smallest Bun Docker Image by Dejan Gegic.