Software delivery format — SquashApp

Dmitry Olshansky
2 min readJun 24, 2023


The idea is to package application as a minimal squashfs image.

squash — a command line tool (simple, portable shell script) used to paxk, examine, sign/validate and repack such images. Relies on gpg for signatures, and other fs command-line tools for repacking.

Then we carefully designe such image structure to be able to run or with trivial unpacked/repack step as:

  • the rootfs should have Docker and OCI compatible format (have the right meta files, have a /bin/init entry point loader binary as ELF Linux binary for the platform)
  • - simply mount the image as loop device (a-la iso images) and run /mount-point/bin/init “optional-args-here” from any *NIX system
  • - as a variation of the above as a fallback cramapp run image.cramapp will unpack it to to ~/.cramapps/<name-version>/… and run
  • - run by linux kernel by passing as initrd if packaged with the right drivers for the hardware
  • - have a minimal bootloader + linux kernel prepended to run app as initrd
  • - have a bootloader prepanded to. initramfs and run as a unikernel — in this scenario, /bin/init is bypassed and bootloader executes user’s binary directly (by parsing /etc/rc)

The squash app structure:


— /bin

— — /init.os.arch (entry point for the target arch, if using a VM — the VM launcher)

… (optional — any other binaries that are part of the app)

— /etc

— — /rc.conf (startup env vars file inspired by BSD rc system — bootloader sets environment vars for the user app, supports os-specific and arch-specific vars)

— — /… (resolv.conf, hosts — and a few others that are bind-mounted by docker and related tools)

— /usr/bin

— — /app (symlink to the main application ELF binary in /bin)

— — / … (any other optional binaries)

— — /lib

— — — / (dynamic loader for os/arch)

— — — / (specially built libc for particular arch that also includes pthread and stuff i.e. it’s musl on Linux, and default BSD libc on BSD)

— /var

— — /local (binded to host fs and is cwd for the app at start)

— — /home (optionally binded to host and HOME env for the app at start)

— /tmp (binded to subdir in /tmp on host fs at start)

— /dev (partially binded to host fa at start)

— /proc (optionally binded to host at start)



Predefined standard ones:

  • baremetal (needs drivers packaged and bloats the image, not recommended)
  • - hypervisor (virtio capable unikernel loader)
  • - linux
  • - linux-initrd
  • - freebsd
  • - openbsd
  • - netbsd
  • - solaris
  • - any user-defined name


named platform_name_exec — binary image to exec

platform_name_args — variable defines a set of default options passed before any user provided ones