Utilizando Nix/NixOS como substituto do Docker

who?

  • Kaleb Alves
  • SRE at
  • Brinco com SDR e DSP
  • Fã do mundo open source, Tolkien, Sci-Fi e Neil Gaiman, Jazz e MMA
   @forgondolin
    @kalves_rohan
 

e...

Tanta complexidade no software vem de tentar fazer uma coisa executar duas coisas.

Ryan Singer

 @rjs

Evolução da "agilidade" e redução de "toil" nas entregas

físico

1990

virtualização

 

 

2000

2010

- Apache HTTP

 

- Windows IIS

conteinerização

- XAMPP

- NGINX

- VmWare

- Cloud

 

- Serverless

 Interplanetary

O "estado da arte" hoje

DevOps e o surgimento do IaC

Conteinerização e Orquestração

Pacotes, plugins, versões...

https://xkcd.com/2347/

Antes e depois dos package manager's

GNU/Linux

Linguagens de programação

Instalar dependências.

Baixar aplicação, rodar script shell e make...

antes
depois
depois
antes

pacman, apt, yum...

bibliotecas privadas;

escrever dll's do zero

cargo, npm, yarn...

"Tem flatpack, appImage, Snap... por que       ?"

Nix

"NixOS: A Purely Functional Linux Distribution"

É uma linguagem? Um package manager? Uma distro?

2003

Nix & nixpkgs (linguagem e pacotes)

NixOS Distro

2007

2009

Hydra CI

2011

NixOps

2013

 1ª Branch estável do NixOs

Nix não "suja" seu OS

$ find /bin /sbin /usr \! -type d -ls
lrwxrwxrwx 1 root root 63 Jan 23 12:51 /bin/sh -> /nix/store/r83lb76j1kyx5irkymcvci61fwyswbc0-bash-4.3-p30/bin/sh
`/sbin': No such file or directory
lrwxrwxrwx 1 root root 66 Jan 23 12:51 /usr/bin/env -> /nix/store/wc472nw0kyw0iwgl6352ii5czxd97js2-coreutils-8.23/bin/env
systemd.services.testground = {
    enable = true;
    description = "testground";
    unitConfig = {
      Type = "simple";
    };
    serviceConfig = {
      ExecStart = "/root/go/bin/testground daemon";
      User = "root";
      Group = "root";
    };
    wantedBy = [ "multi-user.target" ];
  };
}
services = {
      grafana = {
        enable = true;
        port = 2342;
        addr = "0.0.0.0";
      };
$ pgrep -lfa /sshd
1096 /nix/store/m5m4w52wnn733cd4islqgqr8hxa22i9q-openssh-6.7p1/sbin/sshd -f /nix/store/gql0wpr0m574r283vgad6m39gfxszvza-sshd_config
$ ls -l /nix/store/gql0wpr0m574r283vgad6m39gfxszvza-sshd_config
-r--r--r-- 2 root nixbld 506 Jan  1  1970 /nix/store/gql0wpr0m574r283vgad6m39gfxszvza-sshd_config
services.openssh = {
  enabled = true;
  allowSFTP = false;
};

"Legal, mas é mais fácil fazer deploy usando docker..."

...Será?

Nix Store

  • Pacotes ficam dentro de  /nix/store/<inputs-hash>-nome-versao
  • inputs-hash é determinado por todos os inputs
  • Input fixo => output fixo
  • Python v2.7.8 => /nix/store/jwnhidzlb8g0cscyi459v3k1hfd3qbar-python-2.7.8/
  • Python v2.7.9 => /nix/store/rhghn8brqrz4j5ndkhwnm4afqjvk7zi8-python-2.7.9/
ldd /nix/store/jwnhidzlb8g0cscyi459v3k1hfd3qbar-python-2.7.8/bin/python2.7
  linux-vdso.so.1 (0x00007fffda7b0000)
  libgcc_s.so.1 => /nix/store/n2zcibvfxg6k2wpiipd8bzmc46q0vjy6-gcc-4.8.3/lib64/libgcc_s.so.1 (0x00007fd6cca76000)
  libpython2.7.so.1.0 => /nix/store/jwnhidzlb8g0cscyi459v3k1hfd3qbar-python-2.7.8/lib/libpython2.7.so.1.0 (0x00007fd6cc66e000)
  libpthread.so.0 => /nix/store/i11d0d4015p0vbdnjq7lb509v9pwp049-glibc-2.19/lib64/libpthread.so.0 (0x00007fd6cc450000)

Nix Store

with import <nixpkgs> {};

stdenv.mkDerivation {
  name = "file-5.38";

  src = fetchurl {
    url = "ftp://ftp.astron.com/pub/file/file-5.38.tar.gz";
    sha256 = "0d7s376b4xqymnrsjxi3nsv3f5v89pzfspzml2pcajdk5by2yg2r";
  };

  buildInputs = [ zlib ];

  meta = {
    homepage = https://darwinsys.com/file;
    description = "A program that shows the type of files";
  };
}

Dockerfile

#!/bin/bash -e

mkdir -p /build
cd /build

wget ftp://ftp.astron.com/pub/file/file-5.38.tar.gz

tar xfv file-5.38.tar.gz
cd file-5.38
./configure --prefix=/opt/file
make
make install

tar cfvz /out/file-5.38-binaries.tar.gz /opt/file
FROM debian:buster

RUN apt-get update
RUN apt-get install -y wget gcc make libz-dev
ADD ./build.sh /
CMD /build.sh
$ docker build . -t buildenv
$ docker run -v $(pwd)/out:/out --rm -t buildenv

Dockerfile

FROM debian:buster

RUN apt-get update
RUN apt-get install -y apache2
ADD index.html /var/www/html
CMD ["apachectl", "-D", "FOREGROUND"]
EXPOSE 80/tcp
$ docker history debian-nginx:latest
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
a72c04bd48d6        About an hour ago   /bin/sh -c #(nop)  EXPOSE 80/tcp                0B                  
325875da0f6d        About an hour ago   /bin/sh -c #(nop)  CMD ["apachectl" "-D" "FO…   0B                  
35d9a1dca334        About an hour ago   /bin/sh -c #(nop) ADD file:18aed37573327bee1…   129B                
59ee7771f1bc        About an hour ago   /bin/sh -c apt-get install -y apache2           112MB               
c355fe9a587f        2 hours ago         /bin/sh -c apt-get update                       17.4MB              
ae8514941ea4        33 hours ago        /bin/sh -c #(nop)  CMD ["bash"]                 0B                  
<missing>           33 hours ago        /bin/sh -c #(nop) ADD file:89dfd7d3ed7

Nix Channels

A mesma configuração para todos seus ambientes de trabalho.

{ config, pkgs, ... }:

let

  unstable = import
    (builtins.fetchTarball {
      # url = https://github.com/NixOS/nixpkgs/tarball/f930ea227cecaed1f1bdb047fef54fe4f0721c8c; # nixpkgs-unstable 5 July 2021
      url = https://github.com/NixOS/nixpkgs/tarball/14b0f20fa1f56438b74100513c9b1f7c072cf789; # nixpkgs-unstable 20 Aug 2021
    }) {
      # config.allowBroken = true;
      config.allowUnfree = true;
    };

in
  {
    home = {
         homeDirectory = "/home/forgondolin";
       packages = [
       # Utilidades
        pkgs.git
        pkgs.gitAndTools.gh
        pkgs.awscli2
        pkgs.pulumi-bin        
        .
        .
        .]}} 

Flakes

O "docker-compose" do Nix
nix flake new -t templates#go-hello .
git init && git add .
$ ls
flake.lock  flake.nix  go.mod  main.go

devShell = forAllSystems (system:
  let pkgs = nixpkgsFor.${system};
  in {
    default = pkgs.mkShell {
      buildInputs = with pkgs; [ go gopls gotools go-tools ];
    };
  });
$ nix develop

[forgondolin@pop-os:~/tmp/gohello]$ go version
go version go1.16.9 linux/amd64

Better Together

{ config, lib, pkgs, ... }:

{
  # Using an webhook container to connect alertmanager and Discord
  virtualisation.oci-containers = {
    containers = {
      alertmanager-discord = {
        image = "benjojo/alertmanager-discord";
        environment = {DISCORD_WEBHOOK="";};
      };
    };
  };
}

Better Together

with import <nixpkgs> {};

dockerTools.buildImage {
  name = "nginxexp";
  tag = "test";

  contents = nginx;

  runAsRoot = ''
    ${dockerTools.shadowSetup}
    groupadd -r nogroup
    useradd -r nobody -g nogroup -d /dev/null
    mkdir -p /var/log/nginx /var/cache/nginx /var/www
    cp ${./index.html} /var/www/index.html
  '';

  config = {
    Cmd = [ "${nginx}/bin/nginx" "-g" "daemon off;" "-c" ./nginx.conf ];
    Expose = {
      "80/tcp" = {};
    };
  };
}

Outras ferramentas interessantes da "família" Nix

  • Disnix
  • Morph
  • Hydra
  • Niv
  • Lorri

Por que Nix como package manager?

  • Rollback fácil
  • Mudanças atômicas
  • Multi env
  • lazy

Por que Nix como ferramenta de deploy?

  • "Traceability"
  • Troca de versões simples
  • Nix como cache de binário

Por que Nix(Os) como distribuição?

  • Muitos mantenedores
  • Leve
  • Customização quase a nível Arch. Ex: trocar LVM para ZFS é muito simples

Pontos negativos do Nix

  • Documentação
  • Curva de aprendizado
  • Não é um gerenciador de dependência

Onde aprender mais sobre Nix

Obrigado!

  • https://lucasvr.gobolinux.org/publications/2019-PLOS-TaxonomyPackageManagement.pdf
  • https://edolstra.github.io/pubs/nixos-icfp2008-final.pdf
    
  • https://news.ycombinator.com/item?id=31580763

Nix

By Kaleb Alves

Nix

  • 184