{"record":{"id":"9c94552384104928","repo":"jdx/mise","slug":"mise-oci-needs-apk-on-path-to-install-apk-system","errorCode":null,"errorMessage":"mise oci needs `apk` on PATH to install apk system packages into the image","messagePattern":"mise oci needs `apk` on PATH to install apk system packages into the image","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/oci/packages.rs","lineNumber":137,"sourceCode":"            .iter()\n            .map(ToString::to_string)\n            .collect::<Vec<_>>()\n            .join(\", \")\n    );\n    Ok(Some(SystemPackagesLayer {\n        blob: layer::build_layer_from_dir_preserve_metadata(&diff_dir, \"\")?,\n        manager: manager.name(),\n    }))\n}\n\nfn validate_host_requirements(manager: OciPackageManager) -> Result<()> {\n    match manager {\n        OciPackageManager::Apk => {\n            if std::env::consts::OS != \"linux\" {\n                bail!(\"mise oci needs a Linux host to install apk system packages into an image\");\n            }\n            if file::which(\"apk\").is_none() {\n                bail!(\"mise oci needs `apk` on PATH to install apk system packages into the image\");\n            }\n            if !crate::system::sudo::is_root() {\n                bail!(\n                    \"mise oci needs to run as root to install apk system packages because apk \\\n                     executes package scripts in a chroot\"\n                );\n            }\n        }\n        OciPackageManager::Apt => {\n            if file::which(\"apt-get\").is_none() {\n                bail!(\n                    \"mise oci needs `apt-get` on PATH to install apt system packages into the image\"\n                );\n            }\n            if file::which(\"dpkg\").is_none() {\n                bail!(\n                    \"mise oci needs `dpkg` on PATH to install apt system packages into the image\"\n                );","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/oci/packages.rs#L119-L155","documentation":"Even on Linux, apk-based packages require the actual apk binary on PATH because mise shells out to it to install into the image rootfs. Hosts that are not Alpine (Ubuntu, Fedora, Arch) have no apk, so the check fails before any rootfs work starts.","triggerScenarios":"mise oci build on a non-Alpine Linux host (e.g. Ubuntu CI runner) with apk/[alpine-base] package entries; file::which(\"apk\") returns None.","commonSituations":"ubuntu-latest GitHub runners used to build alpine images; a debian dev box; apk removed from an alpine dev container.","solutions":["Run the build from an Alpine environment (alpine container with docker mounted, or an alpine CI runner).","Switch packages to the apt manager and use a debian/ubuntu base when your build host is debian-based.","Or use a real container engine path (docker build) for system packages instead of mise's native layer."],"exampleFix":"# before (ubuntu runner, alpine base)\n[bootstrap]\nbase = \"alpine:3.20\"\n\n# after (match manager to host)\n[bootstrap]\nbase = \"debian:bookworm-slim\"   # host is ubuntu -> apt path works","handlingStrategy":"validation","validationCode":"import shutil, sys\nif apk_entries(config) and shutil.which(\"apk\") is None:\n    sys.exit(\"host has no apk; use an alpine builder or switch to apt/debian base\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match the build host distro to the base image distro (alpine host for alpine images).","Check `command -v apk` (and apt-get/dpkg for apt) as a CI preflight step.","Consider docker build for system packages when the host cannot match the image."],"tags":["oci","packages","apk","missing-binary"],"backgroundTag":"missing-system-tool","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}