Skip to content

Use UPX in Docker multi-stage builds

License

Notifications You must be signed in to change notification settings

hatamiarash7/Docker-UPX

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Docker-UPX

Release License Image size Docker Pulls GitHub Container Registry

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

Supported Architectures

Architecture Tag
x86-64 amd64
ARM64 arm64
ARMv7 arm/v7
ARMv6 arm/v6
x86 386

Quick Start

Pull the Image

# From Docker Hub
docker pull hatamiarash7/upx:latest

# From GitHub Container Registry
docker pull ghcr.io/hatamiarash7/upx:latest

Basic Usage

Compress a binary in your current directory:

docker run --rm -v "$PWD:/workspace" hatamiarash7/upx --best --lzma -o /workspace/app-compressed /workspace/app

Compression Options

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

Multi-Stage Build Examples

Go Application

# 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"]

Rust Application

# 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"]

C/C++ Application

# 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"]

Compression Results

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.

Important Notes

  1. Static binaries only: UPX works best with statically linked executables
  2. Build flags: Use -ldflags="-s -w" for Go to strip debug info before compression
  3. Startup overhead: Compressed binaries have slightly longer startup times (~10-50ms)
  4. Memory usage: Decompression happens in memory at runtime
  5. Anti-virus false positives: Some AV software may flag UPX-compressed binaries

Environment Variables

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

💛 Support

Donate with Bitcoin Donate with Ethereum

ko-fi

🤝 Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

📝 Issues

Found a bug or have a suggestion? Open an issue - contributions to improve this project are always welcome! 👍

About

Use UPX in Docker multi-stage builds

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 2

  •  
  •