composefs turns a directory tree into a verifiable read-only filesystem image
The reliability of disk images, the flexibility of files
At a glance
- What is it?
- composefs is a Linux filesystem that combines EROFS metadata, overlayfs redirection and optional fs-verity so a directory tree can be mounted read-only with content deduplicated against a shared store. It suits container image and OSTree style systems that want image level integrity without disk images, and it does not store data itself.
- Who is it for?
- Adopt composefs when you are building container image or bootable root filesystem tooling and want deduplicated content with integrity that covers metadata as well as file data, and stay with plain overlayfs when you do not need reproducible images or verity digests.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 33 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The three kernel technologies are combined in a specific order
composefs provides a flexible mechanism to support read-only mountable filesystem trees, stacking on top of an underlying lower Linux filesystem. The key technologies it uses are overlayfs as the kernel interface, EROFS for a mountable metadata tree, and fs-verity from the lower filesystem, which is optional. What makes it work is the combination rather than any single piece. overlayfs provides the read-only mount semantics that a container runtime or a booted system expects. EROFS provides an efficient, kernel mountable format for the tree structure. fs-verity, when enabled, provides the cryptographic validation that makes a read-only tree trustworthy. The design goal is the reliability, security and Linux kernel integration of a disk image, with the flexibility of files for content, which means avoiding doubled disk usage and worrying about partition tables.
Metadata and data are stored apart, and the data is never stored by composefs
The separating idea is stated twice in the documentation for good reason. First, to emphasize: composefs does not store any persistent data itself. The underlying metadata and data files must be stored in a valid lower Linux filesystem, usually a traditional writable persistent filesystem such as ext4, xfs or btrfs. The split is between data, meaning non-empty regular files, and metadata, meaning everything else. composefs reads and writes a filesystem image which is really just an EROFS, which today is loopback mounted, but that EROFS tree is only metadata. The underlying non-empty data files live in a distinct backing store directory, and the EROFS filesystem includes trusted.overlay.redirect extended attributes that tell overlayfs how to find the real underlying files. So the image is a manifest of pointers, and the bytes live wherever you put them. A second advantage, described as the key difference from other approaches, is that data files are shared in the page cache. Because the same content-addressed file backs the same bytes in several mounted trees, the kernel keeps one copy in memory, and the documentation states that this allows launching multiple container images that will reliably share memory. That is a different kind of saving from the deduplication on disk. Disk deduplication stops you storing the same file twice. Page cache sharing stops you reading the same file into memory twice, which matters when several images derived from a common base are running at once and each of them would otherwise pull the base into RAM. The trade-off is that the guarantee depends on the content files being genuinely identical, which is exactly why the addressing scheme is a hash of the content rather than a name.
The mount helper takes an image and a base directory
composefs ships with a mount helper so that mounting an image does not require hand assembling overlayfs options. The invocation passes the image filename and the base directory that holds the content files:
mount -t composefs /path/to/image -o basedir=/path/to/content /mntThe basedir option is the pointer back to the shared store. Because files are stored content-addressed, for example using the hash of the content to name the file, a shared file only needs to be stored once while still appearing in multiple mounts. That is the property the whole design exists to provide, and it is what makes a content store cheaper than a per image copy. The targeted use case is versioned, immutable executable filesystem trees, meaning container images and bootable host systems, where several of these filesystems may share parts of their storage, so some files may differ between them but not all.
fs-verity covers metadata as well as file data
fs-verity support is where composefs improves on the standard tool. When using it, the digest of the content files is stored in the image in the trusted.overlay.metacopy extended attributes, which tell overlayfs to validate that the content file it uses has a matching enabled fs-verity digest. The backing content therefore cannot be changed in any way, by mistake or by malice, without that being detected when the file is used. You can also enable fs-verity on the image file itself and pass the expected digest as a mount option, which composefs validates. In that case there is full trust of both data and metadata of the mounted file. The documentation names the weakness this addresses: fs-verity on its own can only verify file data, not metadata such as inode bits like permissions and ownership, and directory structures.
Container images get deduplication across images, not just across layers
The container use case explains why the OCI world is a good fit. A common approach, implemented by both docker and podman, is to untar each layer separately and use overlayfs to stitch them together at runtime, and that approach does ensure that identical layers are shared. It is also a partial inspiration for composefs. The improvement comes from storing file content in a content-addressed fashion, so a composefs file can be generated for each layer and the layers can continue to be mounted with a chain of overlayfs, or alternatively a single composefs can be generated for the final merged filesystem tree. Either way, content files are shared between images even when the metadata, such as timestamps or file ownership, varies between them. Combined with something like zstd:chunked, the documentation says this will speed up pulling container images and make them available for use without needing to create the files if they are already present.
OSTree gains a root filesystem that users cannot tamper with
The bootable host system case is about closing a specific hole in OSTree. OSTree already uses a content-addressed object store, but normally it has to be checked out into a regular directory, using hardlinks into the object store for regular files, and that directory is then bind-mounted as the rootfs when the system boots. OSTree already supports enabling fs-verity on the files in the store, but nothing can protect against changes to the checkout directories, and a malicious user can add, remove or replace files there. The composefs approach is to skip the checkout directory and generate a composefs image pointing into the object store, mounting that as the root filesystem. With fs-verity enabled on the composefs image and its digest embedded in the kernel commandline that specifies the rootfs, the boot is bound to a specific tree. Because composefs generation is reproducible, the generated image can even be verified against a digest stored in the ostree metadata at build time.
Two tools do the work, and the build is Meson with several licence files
composefs installs two main tools. The first is mkcomposefs, which creates a composefs image given a directory pathname and can also compute digests and create a content store directory. The second is mount.composefs, the mount helper. The repository is written in C, with libcomposefs/ holding the library, tools/ the commands, man/ the manual pages, tests/ and ci/ the test and CI directories. The build is Meson, with meson.build and meson_options.txt at the top level, and the tree carries composefs.pc.in for pkg-config along with composefs.spec.in for RPM packaging. On the licensing side there are more files than a reader would expect: COPYING, COPYING.GPL-2.0-only, COPYING.GPL-2.0-or-later, COPYING.LGPL-2.1-or-later, LICENSE.Apache-2.0 and BSD-2-Clause.txt, which is the usual shape for a library that is meant to be embedded in larger tools under different terms. The hosting service reports the licence as a custom one it could not classify, so the COPYING files are the place to confirm the terms. The last push was on 2026-09-20, and the recent tags are v1.0.8 on 2025-01-03, v1.0.7 on 2024-11-01 and v1.0.6 on 2024-09-16.
Where composefs is the wrong choice
Two cases argue against it. The first is a workload with no need for immutability or integrity checking. If you are running a throwaway container that is rebuilt on every deploy, the overhead of generating a composefs image, computing digests and managing a content store buys you nothing, and plain overlayfs over extracted layers will do the same job with fewer moving parts. The second is a system that must run on a kernel without the overlayfs features composefs depends on, because the redirect and metacopy extended attributes are the mechanism by which the whole design works, and a kernel that ignores them produces a mount that looks fine and serves the wrong files. There is also an operational cost that does not appear in the feature list. The content store is a shared, deduplicated, content-addressed directory that must be garbage collected, and the mapping from image to backing store is external state that has to survive reboots and upgrades. A team that adopts composefs has adopted a storage layout with its own lifecycle, and the documentation does not describe a rollback procedure for a failed migration to that layout.
Editorial conclusion
Adopt composefs when you are building container image or bootable root filesystem tooling and want deduplicated content with integrity that covers metadata as well as file data, and stay with plain overlayfs when you do not need reproducible images or verity digests. Verify first that your kernel supports the overlayfs redirect and metacopy features composefs relies on, and read the LICENSE file in the repository, because the tree carries several licence files and the hosting service reports a custom one it could not classify.
Frequently asked questions
What kernel technologies does composefs build on?
composefs combines overlayfs as the kernel interface, EROFS for a mountable metadata tree and optional fs-verity from the lower filesystem. The combination provides the reliability of a disk image with the flexibility of files for content.
How do I mount a composefs image?
Use the mount helper and pass the image path, the basedir holding the content files and the mount point, for example mount -t composefs /path/to/image -o basedir=/path/to/content /mnt. The basedir option points at the shared store where the content-addressed files live.
Does composefs store the file content itself?
No. The documentation emphasizes that composefs does not store any persistent data itself. The metadata and data files must be stored in a valid lower Linux filesystem, usually ext4, xfs or btrfs, and composefs only holds the EROFS metadata tree with overlay redirect attributes.
What does fs-verity add to composefs?
The digest of the content files is stored in the image in the trusted.overlay.metacopy extended attributes, so overlayfs validates the content file it uses. Enabling fs-verity on the image itself and passing the expected digest as a mount option gives full trust of both data and metadata, covering the weakness where fs-verity alone verifies file data but not metadata such as permissions and ownership.
What tools does composefs install?
Two main tools. mkcomposefs creates a composefs image given a directory pathname, and can also compute digests and create a content store directory. mount.composefs is the mount helper used to mount images with a basedir.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/composefs-composefs)Was this useful?