A lightweight, multi-architecture Docker image of UPX (Ultimate Packer for eXecutables) designed for compressing binaries in multi-stage Docker builds.
- Ultra-lightweight - Based on BusyBox (~4MB total)
- Multi-architecture support -
linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/386
| Architecture | Tag |
|---|---|
| x86-64 | amd64 |
| ARM64 | arm64 |
| ARMv7 | arm/v7 |
| ARMv6 | arm/v6 |
| x86 | 386 |
# From Docker Hub
docker pull hatamiarash7/upx:latest
# From GitHub Container Registry
docker pull ghcr.io/hatamiarash7/upx:latestCompress a binary in your current directory:
docker run --rm -v "$PWD:/workspace" hatamiarash7/upx --best --lzma -o /workspace/app-compressed /workspace/app| Option | Description | Compression Level |
|---|---|---|
--best |
Best compression (slowest) | Maximum |
--lzma |
Use LZMA algorithm | Better ratio |
-1 to -9 |
Compression level | Variable |
--ultra-brute |
Try even more compression | Maximum+ |
--brute |
Try more compression | High |
# Stage 1: Build
FROM golang:1.23-alpine AS builder
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app .
# Stage 2: Compress
FROM hatamiarash7/upx:latest AS compressor
COPY --from=builder /app /workspace/app
RUN upx --best --lzma -o /workspace/app-compressed /workspace/app
# Stage 3: Final
FROM scratch
COPY --from=compressor /workspace/app-compressed /app
ENTRYPOINT ["/app"]# Stage 1: Build
FROM rust:1.75-alpine AS builder
WORKDIR /src
COPY . .
RUN apk add --no-cache musl-dev && \
cargo build --release && \
strip target/release/app
# Stage 2: Compress
FROM hatamiarash7/upx:latest AS compressor
COPY --from=builder /src/target/release/app /workspace/app
RUN upx --best --lzma -o /workspace/app-compressed /workspace/app
# Stage 3: Final
FROM scratch
COPY --from=compressor /workspace/app-compressed /app
ENTRYPOINT ["/app"]# Stage 1: Build
FROM alpine:3.21 AS builder
RUN apk add --no-cache gcc musl-dev
WORKDIR /src
COPY . .
RUN gcc -static -O3 -o /app main.c && strip /app
# Stage 2: Compress
FROM hatamiarash7/upx:latest AS compressor
COPY --from=builder /app /workspace/app
RUN upx --best --lzma -o /workspace/app-compressed /workspace/app
# Stage 3: Final
FROM scratch
COPY --from=compressor /workspace/app-compressed /app
ENTRYPOINT ["/app"]Typical compression ratios for statically linked binaries:
| Language | Original | Compressed | Ratio |
|---|---|---|---|
| Go | ~10 MB | ~3-4 MB | 60-70% |
| Rust | ~5 MB | ~1-2 MB | 60-80% |
| C/C++ | ~1 MB | ~300 KB | 70-80% |
Note
Results vary based on the binary size, content, and compression options used.
- Static binaries only: UPX works best with statically linked executables
- Build flags: Use
-ldflags="-s -w"for Go to strip debug info before compression - Startup overhead: Compressed binaries have slightly longer startup times (~10-50ms)
- Memory usage: Decompression happens in memory at runtime
- Anti-virus false positives: Some AV software may flag UPX-compressed binaries
You can customize the build using build arguments:
docker build \
--build-arg UPX_VERSION=4.2.4 \
--build-arg ALPINE_VERSION=3.21 \
-t my-upx .| Build Arg | Default | Description |
|---|---|---|
UPX_VERSION |
latest |
Specific UPX version to use |
ALPINE_VERSION |
3.21 |
Alpine version for downloader stage |
BUSYBOX_VERSION |
1.37 |
BusyBox version for final image |
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
Found a bug or have a suggestion? Open an issue - contributions to improve this project are always welcome! 👍