Architecture & Build Pipeline¶
This document explains the technical architecture, optimization strategy, and engineering decisions behind the FileFlows Real Image build pipeline.
The Upstream Image Problem¶
Upstream FileFlows (revenz/fileflows:latest) is distributed using a single-stage container build based on Ubuntu 26.04 Resolute that retains build tools, compilers, development packages, and extraneous platform runtimes.
An inspection of upstream reveals:
- Full .NET 10 SDK (638 MB): Upstream installs
dotnet-sdk-10.0, which includes Roslyn compilers, MSBuild, project templates, and reference packs. At runtime, FileFlows only requiresaspnetcore-runtime-10.0(~96 MB). - Canonical Rockcraft
pebbleDaemon: Upstream builds on a base image containing Canonical'spebbleprocess supervisor compiled with an outdated Go standard library, introducing 1 Critical (CVE-2026-39821) and 5 High CVEs. FileFlows manages its own processes and never invokespebble. - C/C++ Header Packages (-dev packages): Unused header files (
libavcodec-dev,libssl-dev,libicu-dev,libc6-dev,linux-libc-dev) consume over 120 MB of space. - Dead Platform Runtimes: The published
/appfolder includes runtimes for Windows (win,win-x64,win-arm64) and macOS (osx,osx-x64,osx-arm64), introducing known Windows CVEs (CVE-2021-24112,CVE-2024-0056) onto a Linux container. - Startup Network Download: Upstream's entrypoint script attempts
apt-get install intel-media-va-driver-non-freeon every boot, blocking startup by 15–20 seconds and downloading 30MB+ over the network.
Multi-Stage Pipeline Design¶
The Dockerfile is completely self-contained. It pulls directly from upstream and transforms it across multiple stages without needing external files or host-side scripts.
flowchart TD
Upstream[revenz/fileflows:latest] --> Stage1[Stage 1: app-source]
Stage1 -->|Strip win* osx* runtimes| AppClean[/app cleaned]
Ubuntu[Ubuntu 26.04 Resolute] --> Stage2[Stage 2: base-builder]
AppClean --> Stage2
subgraph BaseBuilder[base-builder execution]
direction TB
B1[nosnap.pref apt pinning]
B2[apt install aspnetcore-runtime-10.0 + ffmpeg libs]
B3[Pre-bake intel-media-va-driver-non-free]
B4[Purge dev packages & build caches]
B5[Purge non-English locales & docs]
B6[Strip SUID/SGID bits]
B7[rm -rf /usr/bin/pebble /var/lib/pebble]
end
Stage2 --> BaseBuilder
BaseBuilder --> Stage3[Stage 3: production]
Stage3 -->|FROM scratch COPY --from=base-builder / /| FinalImage[ghcr.io/lusoris/fileflows-real-image:latest]
Stage 1: app-source¶
- Sources
/appand/docker-bindirectly from upstream. - Executes runtime pruning:
- Strips Windows DLLs that trigger security scanner false positives.
Stage 2: base-builder¶
- Builds a lean Ubuntu 26.04 foundation.
- Configures
/etc/apt/preferences.d/nosnap.prefto preventsnapdinstallation. - Installs
aspnetcore-runtime-10.0instead of the SDK. - Installs minimal runtime dynamic libraries (
libavcodec62,libavformat62,libswscale9,libvpl2,libicu78,libssl3). - Pre-installs
intel-media-va-driver-non-free,libze-intel-gpu1,intel-opencl-icd, andmesa-va-drivers. - Purges
git,nano,gnupg, non-English locales, man pages, and info directories. - Strips SUID and SGID permissions (
chmod a-s) across the entire root filesystem. - Completely deletes any pebble traces:
/usr/bin/pebble,/var/lib/pebble.
Stage 3: production (Rootfs Flattening)¶
- Uses
FROM scratchand copies the entire rootfs frombase-builder(COPY --from=base-builder / /). - This guarantees:
- Single Squashed Layer: 100% layer efficiency score in
dive. - Zero Deleted Layer Retention: Files removed in earlier build steps (like
pebbleor dev headers) are physically absent from all image layers, leaving zero residual vulnerabilities.
.NET 10 Performance Optimization¶
The container configures runtime flags specifically optimized for high-throughput headless container workloads:
ENV DOTNET_EnableDiagnostics=0 \
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=0 \
DOTNET_GCCallbackRunning=0 \
DOTNET_TieredPGO=1
DOTNET_EnableDiagnostics=0: Disables tracing pipes and event listener overhead.DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=0: Retains ICU library support (libicu78) for correct multi-language media filename collation.DOTNET_TieredPGO=1: Activates Tiered Profile-Guided Optimization in the .NET 10 JIT compiler, accelerating CPU-bound pipeline loops.