| When it’s best used (typical use case) | Good for simple applications that need only one runtime. | Best for applications needing custom secondary runtimes, static assets, or custom binaries/tools. | Best when you already build and ship container images outside Upsun and want to deploy them as is. |
| # of runtimes per container | One — a single runtime per container. | Zero or more — you can define multiple runtimes (or none) per container. | Defined entirely by the image itself. |
| Packages permitted / how dependencies are managed | Only the base runtime and its extensions are permitted directly. To add non-runtime packages, you must use build-phase installation via hooks or dependencies. See Keys used below. | Supports multiple runtimes, extensions, packages and services. You define everything in the stack key (runtimes + Nix packages). See Keys used below. | All dependencies are bundled inside the image. Upsun does not add or modify packages. |
| Manual configuration / setup burden | Lower: using a supported runtime means less manual setup; adding downloads, dependencies, and packages might require use of build hooks, which might complicate configuration. | Higher: you manually define the composition of the container or stack (runtimes + packages) of Nix packages. More flexible but requires more setup. | Low on the Upsun side — see Configure an app in the “Self-hosted services from public Docker images” topic. Image preparation and maintenance happen in your own build pipeline. |
| Maintenance & updates (patches, upgrades) | Upsun handles image updates (minor and patch updates; security patches) automatically on deployment | You need to redeploy often to apply Nix package updates; update cadence depends on package maintainers. Your team must be comfortable with upgrading, testing, and refactoring images promptly when Nix a channel becomes deprecated (every six months). | You are responsible for security patches. Upsun does not patch public Docker image runtimes. You must rebuild and redeploy the image to apply updates. |
| Flexibility (versions, custom binaries, tools) | Limited to supported runtimes + permitted extensions. If you require combinations not supported by Upsun, you may hit limits (e.g. certain PHP + Node.js/Python combos). | High — you can mix runtimes, pick specific package versions, and include custom binaries/tools via Nix. | Highest — full control over the image contents, runtime, and tooling. You can use any Docker image from a public registry. |
| When to reconsider / migrate | If you need many packages (beyond runtime extensions), complex dependencies, multiple runtimes, or custom tools, consider migrating to composable. | If you don’t need the complexity (just a simple runtime and minimal packages), composable may be unnecessary overhead. | If patch responsibility or storage cost is a concern. Images must be under 4 GB; larger images require a support ticket. Build hooks are not supported. |