Could it be that docker is missing something, maybe the Dockerfile isn't easily reproducible? Maybe the ephemeral status of all containers is quite some effort to work with?
Maybe it's just not the one true answer to the question of software packaging.
I love Docker for the simplicity it offers, but the gigabytes of storage wasted on yet another slightly different version of Debian every time I pull a container irks me to no end. Sadly, it's the only way some software is distributed.
Where are you seeing distros using docker for containerization? If anything, I'd say Flatpak is the one you're most likely to find installed in a 2021 workstation linux.
Docker's killing features are the same as they always were: usability and ecosystem. 'docker run thingamajig' is simple and DockerHub is very likely to have thingamajig in its repos.
Of the ones you listed, I'd say flatpak is the only one that compares favorably to Docker on both aspects ('flatpak install thingamajig'). And since flatpak is more designed for desktop applications, it's actually the one gaining ground. Docker or other containerd-based solutions should remain the preferred choice for servers, since they're designed for that.
Nix is vastly less user friendly. Snaps, last I checked, still don't have an open-source repository implementation, meaning that Canonical has absolute control over them. I don't know much about AppImage, but AFAICT it's just a file format and not a full package manager.
Another problem is that you want to run an application on differen platforms, not only Linux. Again the proper solution would be to write a cross-paltform application and install it using a cross-platform package manager.
Docker doesn't offer a proper solution; instead it suggests that you create a virtual machine, install a whole operating system (without a kernel) there and then write a bash script that will download and build dependencies. As docker image configuration file is an executable script, it means that it cannot be processed with automated tools; it can only be read by a human.
Also, docker requires a daemon running as a root. This increases potential attack surface.
Docker is not good for desktop applications because it doesn't have portals which can restrict access to DBus, audio daemons, file system etc.
me too. I broke my system a bunch of times, and eventually just gave up. I remembered the other day that I have a lot of programs installed with it that I don't even want to think about updating. rofi changed it's configuration file format recently, and that was tied up in nix. I am too lazy to fight with it for now, so I've just disabled my config file. It bothers me every time I use it.
If the system evaluates it'll most likely work, if it doesn't you roll back a generation.
I have an Ubuntu container around if I quickly wanna mess with something.
But the downside is that debugging is impossble.
Guix uses guile, which is a Lisp so we could accomplish the same with other languages.
Reproducibility. You need a pure (side effect-free) language to ensure that a package expression always evaluates to the same value [1]. If you have a non-pure language, external factors (e.g. environment variables or a server returning a different response) can influence/change what a package expression evaluates to.
[1] That said, Nix was not completely free of side-effects either. Though this is one of the issues that Nix Flakes attempt to solve.
Pick any programming language. Now, remove access to I/O (except standard input and output), networking, time, random number generators, threads, OS syscalls, etc.
Given an input, the program will always generate the same output, i.e. it is deterministic. However, the program is still allowed to have global mutable state; the state is just encapsulated to the program's memory and execution time.
A trivial example is Brainfuck. It is most certainly not a functional programming language, but it is deterministic.
The devil is in the details, and if you miss even one case then the problems are just as bad as if you hadn't bothered at all. For example, comparing two URLs in Java is not deterministic. For another example, iterating through a set in Python will give you the elements in a different order on 32- versus 64-bit systems.
In practice it's just not practical to retrofit deterministic behaviour onto a language that was not designed for it. Even your "trivial example" isn't; Brainfuck does not standardize overflow behaviour and so the same program may behave differently on different systems.
Well, it does network access, so it would excluded.
> For another example, iterating through a set in Python will give you the elements in a different order on 32- versus 64-bit systems.
This is a good counter-point.
> Brainfuck does not standardize overflow behaviour and so the same program may behave differently on different systems.
Different implementations of Nix might have the same issue in some places. In this case, whether the language is fully defined is orthogonal to whether its behavior is deterministic; here, a particular implementation will continue to be as such.
As far as I know, Nix doesn't have a formal specification; it is defined by its reference implementation.
After all you need to be non-constant over architecture, since you need to download the correct binaries for 32-bit and 64-bit architectures.
The problem is Nixpkgs, the largest Nix program. Nix-the-language doesn't lend itself too well to programming in the large. It's a bit like writing a large JavaScript SPA without frameworks or strict coding standards.
The biggest difficulty comes from the fact that it is a dynamic, weakly-typed language, which can lead error messages in configuration to point you toward library code rather than your config file. This is a pitfall shared by many of the languages that are commonly suggested as replacements or alternatives.
There's been work to solve this by adding gradual typing (like in Typescript) to Nix, whose most promising iteration atm is (imo) a Nix-like language called Nickel, which is almost ready for preview by the community.
The other, more minor, issue is tooling, which is being addressed by emerging LSP work for Nix.
(Scripting is done in Nixpkgs, mostly via Bash.)
The beauty of Nixlang, imo, is that for simple use cases it really feels like a dead simple configuration language, which is only possible with a declarative language.
The functional character and Nix's laziness were important in the early design of Nix. The latter may still give Nix some nice performance characteristics. But since the initial Nix design, Nix has become eager in some places, and Guix is implemented as a lazy DSL embedded in an eager language, so I guess we could implement something like Nix on top of an eager scripting language.
Imperative scripting languages might not be as well suited for the kinds of overrides that Nixpkgs and NixOS use, afaict. But imo aside from its novelty, the Nix language is nice to use because it's really simple and totally declarative, which is what you expect from a configuration language.
> You don't need all values of your language to have lazy semantics
Once upon a time (no longer, I think), Nix was 'maximally lazy', so I think historically at least, there has been a question of how essential laziness is to the design of package managers in the functional paradigm. Since then I guess we've seen what you describe (some targeted laziness) is all that's required in both DSLs.
I've edited my comment above to better reflect Guix's design and stop spreading the 'Guix is eager' meme. :)
There’s an open RFC/PR to bring NixOS style modules to Nixpkgs for package management (with derivations being the primitive).
Here's the paper from Eelco Dolstra (founder of the Nix project) https://edolstra.github.io/pubs/nspfssd-lisa2004-final.pdf
I don't see him mentioning configuration an awful lot in there, it seems to be mostly about dependencies and multiple versions of things.
> > How does GoboLinux compare to Nix & Guix these days? Why would one use the former vs the latter?
> This blogpost has a comparison of Gobolinux and Nix:
systemd compliant?
./configure && make
without grokking Nix, and have it work. Or where you can install Linuxbrew and Pkgsrc and have them just work, as additional, non-sandboxed escape hatches.And such a downstream system could benefit from mimicking GoboLinux in a few ways, imo.
{ pkgs ? import <nixpkgs> {} }:
pkgs.stdenv.mkDerivation {
name = "foo-1.0";
src = ./.;
buildInputs = [ pkgs.libfoo pkgs.libbar ];
}
You could make a CLI that does the templating for you, but there's nothing fundamental here that would require a fork of Nix (or Nixpkgs/NixOS) itself.But I think impurity could be a different kind of on-ramp. See things like envfs or the reverted PR for the LSB module in NixOS.
I'd rather look into how to make the Nix-native workflow be as appealing and welcoming as the impure one, than compromise and end up with a system ultimately just that has the downsides of both.
That's why I say this would be a downstream distro, because then
> and the unreliability of the produced frankenbuilds [can] scare newcomers away
to NixOS proper, which can remain pure, principled, and a little difficult. :)
The idea is a workstation/desktop-centric downstream where people can
* use NixOS modules to configure the base system (which is super convenient)
* learn the Nix language ‘by immersion’ and tooling without *immediately* having to choose between packaging and giving up any proprietary/oddball software they might already be using that isn't already in Nixpkgs
* try Nix in its most attractive form (fully declarative OOTB and in control of a full operating system, unlike Nix on macOS or foreign Linux distros)
* start out with all of the commonsense community goodies (flakes, flake-utils-plus, Home-Manager, NUR, and extra binary caches enabled when relevant) pre-enabled and configured in the simplest possible way
* comes with a reset button (like a slightly gentler NIXOS_LUSTRATE) that users can easily use to remove any impurely installed software
While many users have had success diving into NixOS head-first, many others have reported that they found it easier and more productive to first learn the Nix language and Nix tools on macOS. Those users report that they have an easier time because it allows them to learn more gradually or in smaller chunks according to the availability of their free time, with the macOS base system and impure tooling built on top of it providing an escape hatch for when they get stuck or frustrated, or want to quickly try something that's not packaged in Nixpkgs.There's no reason that Nix itself couldn't be used to create the same kind of stable, impurely accessible, compatible (with traditional tools), kind of base system. I think it'll happen some time in the next few years. There's much wider interest in NixOS than their used to be, and with that has come increased interest in making it even more accessible to new users.
Now admittedly actually doing this is pretty rare in these days, but I still like having the option. I believe he does address this talking about "union mounts" and "overlay filesystems". I'm really not too familiar with either or how production ready they are, but it may address my concerns.
It’s pretty frequent! When Atlassian launched their Cloud offerings in 2013, they installed Confluence and Jira on their own servers (1.5GB each), one per customer, and set /bin and /etc as read-only.
Then they mounted /etc and /bin from the network. 1.5GB saved per instance!
So it makes sense not because you can set them as read-only, but because you can mount them separately.