4 ms·
Nix basically lets you compile to Docker containers, rather than running a pipeline of scripts with Dockerfiles. You can do that really fast, since you don't ha
by sterlind 5y ago
Nix basically lets you compile to Docker containers, rather than running a pipeline of scripts with Dockerfiles. You can do that really fast, since you don't have to run the container to build it, and you can make images really small, because they'll contain exactly what they need.
It's like the difference between shipping an app and shipping an OS with the app-preinstalled, except in this case neither has any external dependencies to worry about.
- fwip 5y agoAlso, the nix expression you build an image with is deterministic, unlike Dockerfiles, which by-design aren't. (Dockerfiles are not the only way to build images, of course, but they are a common one).
- throwaway984393 5y agoWell that's good that it can make container images. Sounds like the main advantage is it's faster to install packages in the container image. But I don't understand how this could prevent you from still needing a pipeline of scripts. Installing packages is only a small part of building a typical container image, especially for custom apps being built to run in the cloud. Even if you have your dependencies, you need to compile, run tests, and potentially customize the files inside the container, typically using the programs already installed in the container. So since you're already running a pipeline of scripts in a container right after installing package deps, I'm not sure why one would use Nix for this when Debian works just as well?
- aidenn0 5y ago> Sounds like the main advantage is it's faster to install packages in the container image. I think the main advantage is the builds are actually deterministic. Any Dockerfile with the equivalent of apt-get update in it becomes non-deterministic.
- sterlind 5y agoNix isn't an OS, Nix is a build system, sort of like Bazel. The way you use Nix as an OS (NixOS) is to make Nix build an OS for you. Every time you install a package or whatever, that's just an incremental recompilation. So say that you need to make a Docker container running nginx hosting a static website that you build with Jekyll. At a high level you'd write a Nix file like (very much pseudocode): with let site = buildWithJekyll src={"./src";}; let mynginx = nginx { wwwroot = site; }; docker.buildLayeredImage { inputs: mynginx, entrypoint: "./nginx" } Nix will run Jekyll to build the site, hash the build output and "site" gets that path. Then Nix takes Jekyll and writes a configuration file that sets wwwroot to the Jekyll output. Then Nix builds a container that runs nginx when it starts. If you just change the Nginx config it won't rerun Jekyll because it knows Jekyll's build inputs haven't changed. Nix is a build system that runs other build systems. Comparing Nix to Debian doesn't really make sense, it's like comparing build pipelines to makefiles.
- lom 5y agoI was building a docker image today with nix, but to my demise it ended up being over 90mb (loaded into the docker daemon). How can I make a docker image smaller?
- sterlind 5y agoMake sure you're not bringing in superfluous dependencies. Use nativeBuildInputs (like devDependencies) when appropriate rather than buildInputs (like dependencies).
- lom 5y agoCan I override stdenv to not pull in GNU stuff, but instead busybox. Or none at all? Stuff like that makes the image really small…
- sterlind 5y agostdenv shouldn't end up in the container at all. the container should literally just contain your derivation and its transitive dependencies. your app, its actual dependencies, and nothing else. it won't even contain bash unless you or something you reference adds it. stdenv stuff is just used to build, it doesn't end up in there. maybe use one of the nix tools to show the actual dependencies you're bringing in and cut the fat.