Ever wondered how small you can make a Docker image for Free Pascal based of Docker scratch? In this article I'll show you how to create a fully functional application using Free Pascal and containerise it that fits in just 1.24MB - smaller than most profile pictures!
Why This Matters
In the world of microservices and containerised applications, image size matters:
- Faster deployments - Less data to transfer
- Reduced storage costs - Especially important at scale
- Improved security - Smaller attack surface
- Better performance - Less memory footprint
The Magic: Docker's scratch
Image
Docker's scratch
image is literally empty - it contains absolutely nothing. This makes it the ultimate starting point for minimal containers, but it also means your binary needs to be completely self-contained.
The Setup
Here's what we're working with:
hello.pas - A simple Free Pascal program that makes an HTTP request:
program hello;
uses
SysUtils,
fphttpclient;
begin
writeln(TFPCustomHTTPClient.SimpleGet('http://www.somedomain.com'));
end.
fpc.cfg - Compiler configuration for static linking:
-O4
-Os
-Xs
-XX
-XS
-k-static
-Fu/usr/lib/fpc/3.2.2/units/aarch64-linux/fcl-net
-Fu/usr/lib/fpc/3.2.2/units/aarch64-linux/fcl-web
-Fu/usr/lib/fpc/3.2.2/units/aarch64-linux/fcl-base
-Fu/usr/lib/fpc/3.2.2/units/aarch64-linux/rtl-extra
-Fu/usr/lib/fpc/
-Fu/usr/lib/fpc/3.2.2/units/aarch64-linux/rtl-objpas
Key compiler flags explained:
-
-O4 -Os
: Maximum optimization for size -
-Xs -XX -XS
: Strip symbols and create smart-linked executable -
-k-static
: Static linking (crucial for scratch containers)
The Multi-Stage Dockerfile
FROM freepascal/fpc:3.2.2-alpine-3.19-full AS build
RUN apk add --no-cache musl-dev
RUN mkdir /build
WORKDIR /build
COPY fpc.cfg /etc/
COPY hello.pas /build/
RUN fpc hello.pas
FROM scratch
COPY --from=build /build/hello /app/hello
CMD ["/app/hello"]
This uses a multi-stage build:
- Stage 1: Use the full Free Pascal Alpine image to compile
- Stage 2: Copy only the compiled binary to scratch
Building and Testing
# Build the image
docker build -t hello-fpc .
# Check the size
docker images hello-fpc
# Output: hello-fpc latest 1.24MB
# Run it
docker run hello-fpc
# Output: Full HTML response from the test site!
Why This is So Cool
-
Incredible Size Efficiency: At 1.24MB, this is smaller than:
- A single high-resolution photo
- Most JavaScript frameworks
- Basic Python/Node.js containers (often 100MB+)
-
Security Benefits:
- No shell, package manager, or unnecessary tools
- Minimal attack surface
- Only contains your application
-
Performance:
- Lightning-fast container startup
- Minimal memory usage
- Perfect for serverless/edge computing
Free Pascal Advantages
Free Pascal shines in this use case because:
- Static compilation: Creates self-contained binaries
- Small runtime: No large runtime environment needed
- Fast execution: Compiled code runs efficiently
- Rich libraries: Full HTTP client capabilities built-in
- Cross-platform: Same code works on multiple architectures
Comparison with Other Languages
Language | Typical Container Size | Notes |
---|---|---|
Free Pascal | 1.24MB | This example |
Go | 5-20MB | With scratch base |
Rust | 10-30MB | With alpine/scratch |
Node.js | 150-300MB | Even with Alpine |
Python | 100-500MB | Various base images |
Java | 200-400MB | JRE required |
Real-World Applications
This approach is perfect for:
- Microservices: Minimal overhead
- Edge computing: Fast deployment
- IoT applications: Resource constraints
- Serverless functions: Quick cold starts
- Health check services: Minimal footprint
- API gateways: High performance needs
Tips for Success
-
Always use static linking (
-k-static
flag) -
Optimize for size (
-Os
,-O4
flags) -
Strip symbols (
-Xs
,-XX
flags) - Test thoroughly - No debugging tools in scratch!
- Handle errors gracefully - No shell for troubleshooting
Conclusion
Free Pascal + Docker scratch images = Ultimate efficiency!
At just 1.24MB, we've created a fully functional web client that's:
- ✅ Secure by design
- ✅ Lightning fast
- ✅ Resource efficient
- ✅ Secured intellectual property
This approach proves that modern applications don't need to be bloated. Not bad when working with with your daddy's pascal! ;)
Thank you to our supporters!
We need your help to maintain our Sempare Template Engine (https://github.com/sempare/sempare-delphi-template-engine).
Support us via GitHub Sponsors (https://github.com/sponsors/sempare) or Stripe (https://buy.stripe.com/aEU7t61N88pffQIdQQ).
Some interesting developments are coming regarding our Sempare Boot framework with native support in Free Pascal (currently self funded).
What's the smallest Docker image you've ever created?