In Praise of Alpine and APK
whynothugo.nl
whynothugo.nl
I praise the author for taking this work upon himself. As for me I don’t want anything to do with being a bug canary for other developers. I’ll take time tested and stable thank you.
Personally, I value a lean and simple OS enough that I am willing to risk finding these bugs.
Alternatively, you can try Void Linux. It is similar, except that you can choose between a glibc or a musl install. I've not used it yet because it is rolling-release only and that doesn't fit with what I need it for currently.
However sometimes it may be worth to venture out a bit in exchange for reducing code, or for using code that aligns more with your philosophies.
A comment here last year (https://news.ycombinator.com/item?id=27113914) mentioned that the information would be available "in apk3", but I don't follow development to know whether this has been implemented already.
APK has become my favorite package manager - so far I've had zero breakage with it, unlike apt and pacman which have lots of sharp corners. The same can be said about Alpine Linux in general.
For the last 6 months I have been experimenting with running a zero-maintenance weekly upgrade+reboot cronjob on my Alpine server. Obviously a bad idea but I just want to see how long it takes for something to break.
[FTA:]
> I was very pleased to learn about apk’s /etc/apk/world.
> In essence, this file is a list of desired packages, and apk will install and uninstall packages so that the system state converges to the list. Exactly what I’d been looking for, but built right into the package manager. Actually it’s not just built into the package manager: it’s the very foundation of how it works. apk add actually adds a package to that list, and then installs any that are not present. apk del removes a package from that list, and only uninstalls it if it’s not a dependency for anything else.
This is fairly standard for how package managers work, afaik. From memory, Debian-based systems (in /var/lib/dpkg/status, IIRC) and Gentoo systems both work that way: constraints for the dependency solver (desired versions) are written to a persistent file in a plaintext format before the depsolver runs. In Gentoo's case, the language is also the same— the file is 'the world file' and it lives at /var/lib/portage/world.
I don't have an Arch system in front of me but I imagine it also stores its package selection database in a (perhaps compressed) plaintext format like this.
The novelty here is actually in encouraging users to edit the file directly by directing attention to it in the docs and by storing it under /etc, where one expects admin-facing configuration files.
Definitely an improvement over the norm on Linux, imo.
> apt and pacman which have lots of sharp corners
I'd love to hear more about these!
Now, it is nice that "apk del" and such automatically takes care of removing unused packages, such that you never need an "autoremove" step or similar.
> This is fairly standard for how package managers work, afaik.
i don't think there is a similar concept as that of `/etc/apk/world` in archlinux. from the article it seems that it is a list of packages that i want, and then you let `apk` run its course, installing everything (and its dependencies) mentioned therein.
not sure about debian, but for gentoo `/var/lib/portage/world` see this: https://wiki.gentoo.org/wiki/Selected-packages_set_(Portage)... regarding editing that file by hand. it will be overwritten (and _aggresively_ at that)
I sometimes wonder if it is like that, because XBPS and APK were designed and built by C hackers while apt where done by system administrators maybe. With dnf/rpm I attribute it to this quirkiness I often feel diving into some of Red Hat's tech. Not trying to offend, just wondering and I acknowledge that I am biased.
A lot of that is due to aggressive use of fsync. apt tries hard to be robust against power failures when changing the system.
When using it for something ephemeral (say, part of a CI workflow) you can disable fsync and let it rip. It's still not as fast as apk but it's several times faster than normal.
apt-get -yq install eatmydata
eatmydata apt-get -yq install (all the other things)I tried apt install ffmpeg in a debian:sid docker container on two different docker hosts: one with slow IO (a cheap VPS with slow, contentious storage); and one with much faster, less over subscribed IO.
Fast IO: 27s -> 26s with eatmydata. Basically the same.
Slow IO: 280s -> 140s with eatmydata. Literally twice as fast.
This is likely because the desktop environment depended on what you had to uninstall and reinstall.
The package manager will normally only offer to migrate your system to states where all dependencies are resolved. If the selections you have don't have any solutions, the best it can do will be to offer solutions to (hopefully only slightly) amended selections and try to explain those alternative selections and solutions to you. This is the default behavior of aptitude when you decline a proposed solution for a package management operation; it starts computing other selections and solutions and offers them to you in turn, after it computes each.
When performing dependency resolution like this, a package manager will usually consider whatever operation you're trying to do your most important preference. So if the contents of the world file or equivalent are unresolvable, when it makes amendments to your selections, the package manager 'prefers' to offer you solutions to selections that do include whatever addition or removal you've requested, but may not include some other packages that are marked as manually installed (i.e., members of your previous selection).
To recover from this error non-destructively (which kinda looks like a corrupt package archive on disk), I'd first try
- re-downloading both the old and new udev packages, then
- manually reinstalling the old version via dpkg directly (skipping dependency checks)
- manually installing the new version directly (again skipping version checks)
- seeing what aptitude dist-upgrade and aptitude install -f (equivalent to apt-get install --fix-broken, but with aptitude's noisier interactive resolver) offer you
But you might be able to get away with just using aptitude instead of the normal apt CLI here, and declining proposals until you see what you like.Generally speaking, using the high-level packaging tools' basic subcommands like install and uninstall in these situations will likely result in at least temporarily uninstalling a ton of stuff. For corrupt packages or depsolver brokenness, it's often better to remove the problematic package with the lower-level tools and/or bypassing dependency resolution, and then ask the high-level tool to fix the world. The naive approach of using the high-level tool to perform the uninstallation is likely to lead to those surprising proposals, because it wants to be helpful and avoid transitioning you to a state where some dependencies are unresolved— even at the cost of offering to uninstall those packages' reverse dependencies.
Sometimes that tree of reverse dependencies extends all the way to the ubuntu-desktop metapackage or whatever, and BANG: you just spammed 'y' to a proposal to remove your desktop environment.
Using the high-level defaults that way can also complicate future dependency resolution or just lead to the accrual of cruft by marking what are actually transitive dependencies of user package selections as manually installed. If you carelessly apt-get install some library you already have, you've just marked it as manually resolved and changed how the dependency resolver will treat that library in the future.
At the end of the day, the package manager can either try to be 'smart' about satisfying your current requests by imposing them at the cost of revising your either your past selections (what dist-upgrade does) or your current selections (what install --fix-broken does), or it can just sometimes break down and tell you 'no, that set of package selections is not satisfiable'. If it does the former, when there's breakage you get 'sharp edges' (i.e., you have to reason about the package manager's dependency resolution and transition behavior to get the cleanest outcome sometimes). If it does the latter, you have to reason about your dependencies in order to amend your world file (and you might still have to reason about transition behaviors), but in some ways it shrinks the behavior puzzle you're looking at with the botched upgrade.
I kind of like the more explicit failure mode, and I don't mind editing text until it makes a computer happy; that's a familiar kind of puzzle for me. I think that's part of why something like a world file is appealing to this crowd, including me. :)
That's not quite so obvious to me. First, I don't immediately recall ever having any problems resulting from upgrading within a release (i.e. if I'm on 3.16, I don't remember `apk upgrade` ever causing a problem, but going to 3.17 might). Second, it works on other distros - the Debian family treats https://wiki.debian.org/UnattendedUpgrades as a totally normal supported thing to do, and I don't think Alpine is noticeably less stable than them.
I have something similar for my dotfiles, a list of packages, their manager and version in a TOML file: https://github.com/kdeldycke/dotfiles/blob/main/packages.tom...
I then feed this to meta-package-manager[1] to install:
$ mpm restore ./packages.toml
[1] https://github.com/kdeldycke/meta-package-manager[1] https://holocm.org [2] https://github.com/holocm/holo-build [3] https://github.com/majewsky/system-configuration/blob/master...
From what I can see, there still isn't any security contact listed. There's at least now a CVE tracker, but there's no stable package versions in alpine, which means you have to choose between upgrading everything and breaking, or keeping insecure packages around.
Debian may lead to larger images, but overall it's considerably more secure.
With that said, I got some random DNS issues with alpine docker images apparently due limitations of musl, so I now avoid it, as saving a little disk space is not worth the hassle.
i run alpine on my laptop and arch on my desktop. i wish it was alpine on both.
while there are minor differences moving from glibc to musl, and the odd failure to compile, it’s vastly overblown.
This is true and real, and we as a community should stop saying "yeah, it's a weird distro". We should look at it and say "Alpine (and Gentoo, and Nix, and Arch, ...) is a separate OS". Closely related to the OSes of other Linux distributions, but still separate, because of a different ABI and API.
I have written about it here: https://dottedmag.net/blog/linux-is-not-os/