Overview of ldso-cache
mainldso-cache component is responsible for the reading and writing of glibc /etc/ld.so.cache files. This is used to manage the cache of shared library locations for the dynamic linker.repository·main·Indexed 23 days ago
https://github.com/chainguard-dev/apkoapko is a tool for building OCI-compliant container images from declarative YAML configurations. It ensures reproducibility and SBOM generation by avoiding arbitrary Unix commands, instead relying on the installation of Alpine packages. The project includes go-apk, a native Go implementation of the Alpine Package Keeper (apk) utility, and provides capabilities for managing users, filesystem mutations, and image layering strategies.
ldso-cache component is responsible for the reading and writing of glibc /etc/ld.so.cache files. This is used to manage the cache of shared library locations for the dynamic linker.You can enable local caching of apk packages to speed up installations, especially for large packages or slow network environments. When enabled, the library checks the cache for requested apk files before attempting a download. If a cache miss occurs, the file is downloaded and then stored in the cache for subsequent use.
To enable caching, pass the apk.WithCache() option to the apk.New() function.
Instead of running busybox --install during the build process (which would require a runner environment and path resolution), apko manages Busybox symlinks directly using an internal list.
When apko detects /bin/busybox in an image, it performs the following steps:
/usr/lib/apk/db/installed to identify the installed Busybox version.v1.36.1-r3 to 1.36.1).apko builds OCI-compliant images from a declarative apko.yaml configuration file. Unlike traditional Dockerfiles, apko does not allow the execution of arbitrary commands; instead, all content is generated by installing apk packages.
The high-level build lifecycle is:
build.Context is created using the apko.yaml file, which is parsed into an ImageConfiguration.build.Context.BuildLayer(). This process lays out the desired filesystem in a temporary working directory and packages it into a .tar.gz layer file..tar.gz is converted into an OCI image tarball using oci.BuildImageTarballFromLayer().This approach ensures that images are reproducible and derived strictly from package management rather than imperative shell scripts.
apko uses a heuristic-based layering implementation designed to be simple and automatic. Unlike Dockerfile where users manually arrange layers, apko aims to minimize manual configuration by using internal heuristics to produce efficient layers.
Key design goals include:
The caching mechanism only applies to remote repositories.
Repositories referenced via local filesystems (e.g., ./packages/foo) are not cached because they do not provide the same performance benefits as remote downloads.
Currently, apko is primarily distributed as a CLI tool. While there are no official plans to prioritize a formal library implementation, the maintainers welcome patches to move towards this goal.
If you choose to wrap the apko CLI in your own application, be aware that breaking changes to the CLI interface are possible. Such changes will be announced in NEWS.md.
The standard Go fs.FS interface is read-only and lacks support for write operations, symlinks, hardlinks, or permission management (chmod/chown).
chainguard.dev/apko/pkg/apk/fs provides a FullFS interface that extends fs.FS with full read-write, chmod/chown, devices, and symlinks capabilities. It is fully compliant with fs.FS and can be used wherever a standard filesystem interface is required.
There are two primary implementations of FullFS:
memfs (fs.NewMemFS()): An in-memory implementation. It is fully functional but limited by available system memory when handling large files.rwosfs: An on-disk implementation. It provides full capabilities (including symlinks, devices, and case-sensitivity) even if the underlying host filesystem does not support them, by storing file metadata in-memory while keeping file contents on disk.The origin strategy partitions an image into multiple layers based on package grouping to maximize deduplication. The process follows these steps:
apko performs a virtual installation of all packages, tracking file metadata and tar offsets in memory without writing bytes to disk. This ensures the layered rootfs is identical to a single-layer rootfs.foo.yaml in Wolfi) are grouped together because they tend to change at the same time.replaces another (e.g., libxcrypt replacing libcrypt1), both are placed in the same layer to ensure correct filesystem overlay behavior.$budget - 1 groups form individual layers, and all remaining smaller packages are merged into a single "overflow" layer./etc/apk/world or /usr/lib/apk/db/installed) are written to a final "top" layer.Using apko's ability to mutate paths—such as modifying file ownership or permissions—will impact layer deduplication.
Because layers are stored as tarballs, there is no efficient way to overwrite only file metadata in the top layer without rewriting the entire layer. Consequently, if you modify the permissions of a file in one image, that layer may no longer deduplicate with similar layers in other images that do not have those same modifications.
The actual filesystem construction occurs during the BuildLayer() phase. The process follows these specific steps to ensure a valid and secure container filesystem:
ImageConfiguration and applies default values.apk directories within the working directory.apk packages.MutateAccounts() to create the specified users and groups.chmod/chown). If the underlying filesystem or user permissions prevent direct manipulation, apko tracks the intended ownership/permissions and applies them during the final tar stream creation.busybox commands, as busybox acts as a multi-call binary.ldconfig by parsing ELF headers to create necessary library symlinks./etc/os-release file.s6 supervisor and creates its configuration files.In apko, packages often share overlapping directories. If these directories have different timestamps, cross-image deduplication will fail even if the file contents are identical.
To solve this, apko uses a Timestamp Synthesis strategy: instead of dropping timestamps (which can break applications that stat files) or dropping directories (which relies on implementation-defined behavior), apko makes parent directories adopt the timestamps of their child files. This ensures that timestamps are synthesized from files that exist only within that specific layer, preventing inter-layer influence from invalidating deduplication.