Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If you like Nix than probably try GNU Guix [1] and if possible use Guix System on server side. This is one of the most modern development in operating systems.

In the modern security conscious world where most companies run their workloads on virtual machines controlled by other companies, it's imperative that applications are deployed on such predictable, secure and reproducible operating systems.

Guix supports transactional upgrades and roll-backs, unprivileged package management, and more. When used as a standalone distribution, Guix supports declarative system configuration for transparent and reproducible operating systems.

I still think Amazon, Google and Azure will take a decade or two to build and offer something like this to it's customers. Indeed Google's Fuschia is trying to do the same, but I feel it's at least a decade away.

It has one of the best wonderful documentation [2] to get started and explore with all the details.

[1] https://guix.gnu.org/

[2] https://guix.gnu.org/manual/en/html_node/



As a Nix user, Guix interests me but I have three concerns, namely my pain points with Nix:

1. Small package base.

My workflow includes running Julia on CUDA, editing from VS Code. Remarkably, Guix has both Julia and (on a third-party PKG repo) CUDA. What it's missing is VS Code. I understand that VS Code is non-free (like Chrome, it attaches trademarks on its branding), but there's no VS Codium I could find either. I also can't find Atom. Am I missing something?

2. Package index mirroring.

Nix has an issue where Python, Node and other "third-party" packages have to be manually added to nixpkgs. If you want celery or requests, you're in luck because those are popular. If you want something more obscure, like pywikibot, you have to add it yourself (or run pip/npm yourself, and forego the benefits of Nix/Guix.) Does Guix address this?

3. Ease of scripting.

This might be a plus for Guix, since Nix design patterns are arcane (the language is easy, things like overrides and needing to replace broken URLs is hard), but how easy is it to debug failing builds? Is there something like a debugger, or at least a way to shell-in and call things yourself?

Bonus #4: broken URLs. is there a cache? what can be done?


The solution to Python packages is the 'pypi2nix' tool. This is an alternate approach that you see also used in the blog post, this time with vgo2nix. These tools take a set of dependencies (e.g. requirements.txt) and generate Nix expressions to build all of them from source.


You may also want to take a look at https://github.com/nix-community/poetry2nix

Disclaimer: I am the author (and also the author of vgo2nix).


Guix has `guix import pypi PACKAGE`, which spits out a complete definition that you can pop into a file or the main Guix repository.

'guix import' also takes a --recursive argument, which makes it recursively consider any dependencies and produce package definitions for those not already available.


For #4, Guix integrates with the Software Heritage archive[0] and will look there if the upstream server is unavailable.

The CI servers also act like content-addressed mirrors, so in practice you won't notice when the upstream disappears.

[0] https://www.softwareheritage.org/


I don't think you can get away from explicit package mirroring without compromising having a nixpkgs pinned to a rev.

Luckily it's pretty automatable and painless if your language has a decent packaging syste - the way Hackage is mirrored is very nice and automated. And then you can just ask for "vector version X.Y.Z" and if that version is there (probably is if nixpkgs is recent and the library is on Hackage), it finds it. And if you don't want to wait for nixpkgs to maintain the Hackage hashes, you can pretty easily maintain it yourself.


I'd really love to use GuixSD. I'd much prefer Lisp to Nix. But the strict licensing is just too much of a handicap. You've really got to build your system around the underlying licenses. I've tried installing it on 3 or 4 systems, and was always tripped up by some critical missing driver.

I admire the ideological purity, but it kinda renders it irrelevant to me.


Add non-pure channels, e.g. https://gitlab.com/nonguix/nonguix


If I could trouble you for the common discourse here, would you mind summarizing why one may prefer to use Guix in the place of Nix? They seem to be based on the very same ideas and Guix even admits to being inspired by Nix.


Scheme instead of a bespoke programming language, and more focus on reducing the bootstrap set that compromises the goal of reproducibility shared by both systems.


But the bespoke language has some benefits. It’s concise and specifically designed for the problem. Also Nix has more contributors and that is very important to have a large collection of recipes to start from.


Scheme, being a Lisp, is exceptionally well-suited to serve as a base for DSLs.


Ok I’ll give another reason. Nix community is more relaxed and doesn’t downvote just because they don’t like some comment or somebody disagrees with them.


I bet you the irony of your downvotes is lost on the people downvoting.


For sure they are pilling on ... for what I don’t get. Relax people.


Do Nix and Guix expressions not interoperate? Is that a fundamental limitation of the system (at lest as fundamental as, say, dpkg and rpm) or could one write a source-level translator?


It's a good question. They don't interoperate now.


Yes, Scheme is a bit verbose for my taste.


There are obviously some differences between the two, but I'm not really perceiving any real verbosity gap between the two, one way or the other.

Here is a guix package declaration for tmux:

[Edit: fixed indentation]

    (define-module (gnu packages tmux)
      #:use-module ((guix licenses) #:prefix license:)
      #:use-module (guix packages)
      #:use-module (guix download)
      #:use-module (guix git-download)
      #:use-module (guix build-system gnu)
      #:use-module (guix build-system trivial)
      #:use-module (gnu packages)
      #:use-module (gnu packages bash)
      #:use-module (gnu packages libevent)
      #:use-module (gnu packages ncurses))
    (define-public tmux
      (package
       (name "tmux")
       (version "3.0a")
       (source (origin
                (method url-fetch)
                (uri (string-append
                      "https://github.com/tmux/tmux/releases/download/"
                      version "/tmux-" version ".tar.gz"))
                (sha256
                 (base32
                  "1fcdbw77nz918f7gqc1ga7zlkp1g112in1h8kkjnkadgnhldzlaa"))))
       (build-system gnu-build-system)
       (inputs
        `(("libevent" ,libevent)
          ("ncurses" ,ncurses)))
       (home-page "https://tmux.github.io/")
       (synopsis "Terminal multiplexer")
       (description
        "tmux is a terminal multiplexer: it enables a number of terminals (or
    windows), each running a separate program, to be created, accessed, and
    controlled from a single screen.  tmux may be detached from a screen and
    continue running in the background, then later reattached.")
       (license license:isc)))

Here is (roughtly) the equivalent in Nix:

    { stdenv, fetchFromGitHub, autoreconfHook, ncurses, libevent, pkgconfig, makeWrapper }:
    
    let
    
      bashCompletion = fetchFromGitHub {
        owner = "imomaliev";
        repo = "tmux-bash-completion";
        rev = "fcda450d452f07d36d2f9f27e7e863ba5241200d";
        sha256 = "092jpkhggjqspmknw7h3icm0154rg21mkhbc71j5bxfmfjdxmya8";
      };
    
    in
    
    stdenv.mkDerivation rec {
      pname = "tmux";
      version = "2.9a";
    
      outputs = [ "out" "man" ];
    
      src = fetchFromGitHub {
        owner = pname;
        repo = pname;
        rev = version;
        sha256 = "040plbgxlz14q5p0p3wapr576jbirwripmsjyq3g1nxh76jh1ipg";
      };
    
      nativeBuildInputs = [ pkgconfig autoreconfHook ];
    
      buildInputs = [ ncurses libevent makeWrapper ];
    
      configureFlags = [
        "--sysconfdir=/etc"
        "--localstatedir=/var"
      ];
    
      postInstall = ''
        mkdir -p $out/share/bash-completion/completions
        cp -v ${bashCompletion}/completions/tmux $out/share/bash-completion/completions/tmux
      '';
    
      meta = {
        homepage = http://tmux.github.io/;
        description = "Terminal multiplexer";
    
        longDescription =
          '' tmux is intended to be a modern, BSD-licensed alternative to programs such as GNU screen. Major features include:
              * A powerful, consistent, well-documented and easily scriptable command interface.
              * A window may be split horizontally and vertically into panes.
              * Panes can be freely moved and resized, or arranged into preset layouts.
              * Support for UTF-8 and 256-colour terminals.
              * Copy and paste with multiple buffers.
              * Interactive menus to select windows, sessions or clients.
              * Change the current window by searching for text in the target.
              * Terminal locking, manually or after a timeout.
              * A clean, easily extended, BSD-licensed codebase, under active development.
          '';
    
        license = stdenv.lib.licenses.bsd3;
    
        platforms = stdenv.lib.platforms.unix;
        maintainers = with stdenv.lib.maintainers; [ thammers fpletz ];
      };
    }


I feel like (inputs `(("libevent" ,libevent) ("ncurses" ,ncurses))) is pretty bad compared to buildInputs = [ ncurses libevent makeWrapper ]; even if you go by token count. (I think it's 16 vs. 8.) A different problem is that syntactically the Scheme version looks like a call to a function called “inputs” and I don't think it is; that depends on context. In general in Lisps the interpretation of everything depends on syntactic context, so you have to do a lot of processing consciously that you can do subconsciously in languages that have a syntax.

(There's an indentation error in either your example or my browser that makes that input clause appear to belong to the origin clause rather than the package clause, btw. The extra redundancy of the different kinds of delimiters makes that error harder to make in Nix. I wrote about this more at length in http://www.paulgraham.com/redund.html )

The module imports at the top are a lot more egregious but that's because they're using Guile’s module system naked; it's not really the fault of Scheme's syntax per se and I think you could hack together some kind of macrological solution.

I think Scheme is brilliant and probably a better choice, but I think the syntactic cost is pretty heavy in your example.

When it comes to Nix and Guix, though, these are kind of minor details. More important questions are things like “does it have the software I want in it” and “how reproducible is it” and “how do I figure out what's broken”.


On the other hand you've got 'stdenv' all over the place in the Nix example, e.g. stdenv.lib.licenses.bsd3 vs license:bsd3. Also stdenv.mkDerivation is kind of an eyesore compared to define-public / package.

One is nicer than the other in a few different minor ways, but overall I think it's basically a wash. I'd not consider verbosity a factor if choosing between the two.

>(There's an indentation error in either your example or my browser that makes that input clause appear to belong to the origin clause rather than the package clause, btw.

Sorry about that, I botched the indentation when I pasted that into my scratch buffer, which had unbalanced parens in it. That's on me.


That sounds like a reasonable point of view.


Those two package descriptions don't appear equivalent. The Nix one includes tmux-bash-completion and some extra build configuration compared to the Guix one, as well as a much more verbose description.


I meant both to be examples of the general look and feel of each DSL. They aren't precisely equivalent, but I do think they're illustrative examples of the two DSLs.


I think the differences are small.


After deleting the bash completion stuff and replacing the verbose description with Guix's, it cut the package from 63 lines down to 36. Deleting the blank lines cut it down to a further 27. For comparison the Guix package (which had no blank lines to begin with) is 35 lines.

Here's the trimmed Nix derivation:

  { stdenv, fetchFromGitHub, autoreconfHook, ncurses, libevent, pkgconfig, makeWrapper }:
  stdenv.mkDerivation rec {
    pname = "tmux";
    version = "2.9a";
    outputs = [ "out" "man" ];
    src = fetchFromGitHub {
      owner = pname;
      repo = pname;
      rev = version;
      sha256 = "040plbgxlz14q5p0p3wapr576jbirwripmsjyq3g1nxh76jh1ipg";
    };
    nativeBuildInputs = [ pkgconfig autoreconfHook ];
    buildInputs = [ ncurses libevent makeWrapper ];
    meta = {
      homepage = http://tmux.github.io/;
      description = "Terminal multiplexer";
      longDescription =
        '' tmux is a terminal multiplexer: it enables a number of terminals (or
  windows), each running a separate program, to be created, accessed, and
  controlled from a single screen.  tmux may be detached from a screen and
  continue running in the background, then later reattached.
        '';
      license = stdenv.lib.licenses.bsd3;
      platforms = stdenv.lib.platforms.unix;
      maintainers = with stdenv.lib.maintainers; [ thammers fpletz ];
    };
  }


Nice! I find this a lot more readable than the Scheme, and it certainly contains many fewer tokens; what do you think?


That looks almost identical to the Scheme one with the only real difference being foo=bar; vs (foo bar). Hardly enough of a difference to change anything "a lot" either way.


Guix package definitions were unreadable to me initially, as I had never used Scheme/Lisp before.

I've written a couple of them now and the definition above is extremely easy to read. Big part is just formatting & parentheses, I think my eyes just needed a little bit of adjustment time.


It’s absolutely more readable.


Guix is a GNU project which underpins today’s largest eco-system of OS, utilities, tools, apps and language related work. It has larger community as well.

So although it’s inspired by Nix, I personally will chose it as it has evolved quickly and if you look at all three aspects Guix, Guix System and documentation it’s now better than Nix. Also last but not the least I work with emacs lisp, so I feel at home with Guile Scheme so I will prefer Guix over Nix.

Personally I will like Nix also to flourish and being a non GNU project it will be able to provide closed source proprietary packages which is not part of core Guix. I think a healthy competition between the two is good, and whichever gets popular is overall good for advances in OS eco-system. Guix System is a new OS, not just package manager.

But by making Guix package manager available to other systems, it might move people who see benefits to move to transactional, predictable, secure OS like NixOS or Guix System.


> Guix is a GNU project which underpins today’s largest eco-system of OS, utilities, tools, apps and language related work. It has larger community as well.

To be clear, this is talking about the entire GNU project compared to just Nix? All metrics I can find show Nix's adoption is significantly above that of Guix.

https://news.ycombinator.com/item?id=16490027 seems like a pretty interesting comment on the benefits of Guix, albeit old.


I actually tried guix several times, and for my trouble I got my tmux sessions (and random processes on my box) killed on a box with 32 GB of ram. #guix on freenode was confused. I intend to wait until guix is a bit more stable on Ubuntu.


Guix does not have tools such as NixOps aimed at managing cloud servers (unless im mistaken), how do you manage servers with it?


You are mistaken. Granted their deployment tools are still in an early stage, but like everything else in the guix ecosystem it looks promising

Here's a tutorial for guix server deployments https://guix.gnu.org/blog/2019/managing-servers-with-gnu-gui...

Here's the docs on guix deploy. https://guix.gnu.org/manual/devel/en/html_node/Invoking-guix...


Guix is technically interesting, but as a fsf endorsed distro it makes running common hardware a challenge. Are there linux-antilibre packages out there for guix?





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: