.upsun/config.yaml file.
Which image type should you choose?
| Criteria / Use‑case | Single‑runtime image | Composable image |
|---|---|---|
| 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. |
| # of runtimes per container | One — a single runtime per container. | Zero or more — you can define multiple runtimes (or none) per container. |
| 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. |
| 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. |
| 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). |
| 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. |
| 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. |
Keys used in each image type
Both image types use many of the same keys. Differences in syntax or meaning are noted as needed - see the Image properties section for the topics that describe each key. Defining your app’s tech stack depends on the image type you choose:- Single-runtime image: Use the
build,dependencies, andruntimekeys - Composable image: Use the
stack.runtimesandstack.packageskeys