Docker: Difference between revisions

From NixOS Wiki
imported>Jooooscha
mNo edit summary
imported>Jooooscha
(Restructure and add information)
Line 3: Line 3:
== Installation ==
== Installation ==


Inside your <code>configuration.nix</code>:
To install docker, add the following to your your NixOS configuration:


<syntaxHighlight lang=nix>
<syntaxHighlight lang=nix>
Line 19: Line 19:
</syntaxHighlight>
</syntaxHighlight>


Note: In the [[btrfs]] filesystem you might need to set the storageDriver option, like so <code>virtualisation.docker.storageDriver = "btrfs"</code>
Note: If you use the [[btrfs]] filesystem, you might need to set the storageDriver option:
 
<syntaxHighlight lang=nix>
virtualisation.docker.storageDriver = "btrfs"
</syntaxHighlight>
 
=== Rootless docker ===
 
To use docker in [https://docs.docker.com/engine/security/rootless/ rootless mode], you can activate the <code>rootless</code> option:
 
<syntaxHighlight lang=nix>
virtualisation.docker.rootless = {
  enable = true;
  setSocketVariable = true;
};
</syntaxHighlight>
 
The <code>setSocketVariable</code> option sets the <code>DOCKER_HOST</code> variable to the rootless Docker instance for normal users by default.


== Building a docker image with nixpkgs ==
== Building a docker image with nixpkgs ==


There is [https://nixos.org/nixpkgs/manual/#sec-pkgs-dockerTools an entry for dockerTools in the nixpkgs manual] for reference.
There is an entry for [https://nixos.org/nixpkgs/manual/#sec-pkgs-dockerTools dockerTools] in the nixpkgs manual for reference.
In the nixpkgs repo some [https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/docker/examples.nix examples] can be found.
In the linked page they give the following example config:
 
<syntaxHighlight lang=nix>
buildImage {
  name = "redis";
  tag = "latest";
 
  fromImage = someBaseImage;
  fromImageName = null;
  fromImageTag = "latest";
 
  copyToRoot = pkgs.buildEnv {
    name = "image-root";
    paths = [ pkgs.redis ];
    pathsToLink = [ "/bin" ];
  };


Also check out the excellent article by lethalman about [http://lethalman.blogspot.de/2016/04/cheap-docker-images-with-nix_15.html building minimal docker images with nix].  
  runAsRoot = ''
    #!${pkgs.runtimeShell}
    mkdir -p /data
  '';
 
  config = {
    Cmd = [ "/bin/redis-server" ];
    WorkingDir = "/data";
    Volumes = { "/data" = { }; };
  };
 
  diskSize = 1024;
  buildVMMemorySize = 512;
}
</syntaxHighlight>
 
More examples can be found in the [https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/docker/examples.nix nixpkgs] repo.
 
Also check out the excellent article by [http://lethalman.blogspot.de/2016/04/cheap-docker-images-with-nix_15.html lethalman] about building minimal docker images with nix.


=== Reproducible image dates ===
=== Reproducible image dates ===
Line 34: Line 84:
An alternative, if using [[flakes]], is to do <code>created = builtins.substring 0 8 self.lastModifiedDate</code>, which uses the commit date, and is therefore reproducible.
An alternative, if using [[flakes]], is to do <code>created = builtins.substring 0 8 self.lastModifiedDate</code>, which uses the commit date, and is therefore reproducible.


== How to calculate the <code>sha256</code> of a pulled image ==
=== How to calculate the <code>sha256</code> of a pulled image ===


The <code>sha256</code> argument of the <code>dockerTools.pullImage</code> function is the checksum of the archive generated by Skopeo. Since the archive contains the name and the tag of the image, Skopeo arguments used to fetch the image have to be identical to those used by the <code>dockerTools.pullImage</code> function.
The <code>sha256</code> argument of the <code>dockerTools.pullImage</code> function is the checksum of the archive generated by Skopeo. Since the archive contains the name and the tag of the image, Skopeo arguments used to fetch the image have to be identical to those used by the <code>dockerTools.pullImage</code> function.
Line 60: Line 110:
1x00ks05cz89k3wc460i03iyyjr7wlr28krk7znavfy2qx5a0hfd
1x00ks05cz89k3wc460i03iyyjr7wlr28krk7znavfy2qx5a0hfd
</syntaxHighlight>
</syntaxHighlight>
== Using Nix in containers ==
While [https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-dockerTools dockerTools] allows to build lightweight containers, it requires <code>nix</code> to be installed on the host system. An alternative are docker images with nix preinstalled:
* [https://hub.docker.com/r/nixos/nix/tags nixos/nix] (official)
* [https://hub.docker.com/r/nixpkgs/nix nixpkgs/nix] (built from https://github.com/nix-community/docker-nixpkgs)


== Docker Compose with Nix ==
== Docker Compose with Nix ==
Line 74: Line 117:
To use Arion, you first need to add its module to you NixOS configuration:
To use Arion, you first need to add its module to you NixOS configuration:


  modules = [ arion.nixosModules.arion ];
<syntaxHighlight lang=nix>
modules = [ arion.nixosModules.arion ];
</syntaxHighlight>


After that you can access its options under
After that you can access its options under
 
<syntaxHighlight lang=nix>
  virtualisation.arion = {}
virtualisation.arion = {}
 
</syntaxHighlight>


A config for a simple container could look like this:
A config for a simple container could look like this:


  virtualisation.arion = {
<syntaxHighlight lang=nix>
    backend = "docker";
virtualisation.arion = {
    projects = {
  backend = "docker";
      "db" = settings.services."db".service = {
  projects = {
        image = "";
    "db" = settings.services."db".service = {
        restart = "unless-stopped";
      image = "";
        environment = { POSTGRESS_PASSWORD = "password"; };
      restart = "unless-stopped";
      };
      environment = { POSTGRESS_PASSWORD = "password"; };
     };
     };
   };
   };
};
</syntaxHighlight>
== Using Nix in containers ==
While [https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-dockerTools dockerTools] allows to build lightweight containers, it requires <code>nix</code> to be installed on the host system. An alternative are docker images with nix preinstalled:
* [https://hub.docker.com/r/nixos/nix/tags nixos/nix] (official)
* [https://hub.docker.com/r/nixpkgs/nix nixpkgs/nix] (built from https://github.com/nix-community/docker-nixpkgs)


== See also ==
== See also ==

Revision as of 22:28, 27 December 2022

Docker is a utility to pack, ship and run any application as a lightweight container.

Installation

To install docker, add the following to your your NixOS configuration:

virtualisation.docker.enable = true;

More options are available.

Adding users to the docker group will provide them access to the socket:

Warning: Beware that the docker group membership is effectively equivalent to being root!
users.users.<myuser>.extraGroups = [ "docker" ];

Note: If you use the btrfs filesystem, you might need to set the storageDriver option:

virtualisation.docker.storageDriver = "btrfs"

Rootless docker

To use docker in rootless mode, you can activate the rootless option:

virtualisation.docker.rootless = {
  enable = true;
  setSocketVariable = true;
};

The setSocketVariable option sets the DOCKER_HOST variable to the rootless Docker instance for normal users by default.

Building a docker image with nixpkgs

There is an entry for dockerTools in the nixpkgs manual for reference. In the linked page they give the following example config:

buildImage {
  name = "redis";
  tag = "latest";

  fromImage = someBaseImage;
  fromImageName = null;
  fromImageTag = "latest";

  copyToRoot = pkgs.buildEnv {
    name = "image-root";
    paths = [ pkgs.redis ];
    pathsToLink = [ "/bin" ];
  };

  runAsRoot = ''
    #!${pkgs.runtimeShell}
    mkdir -p /data
  '';

  config = {
    Cmd = [ "/bin/redis-server" ];
    WorkingDir = "/data";
    Volumes = { "/data" = { }; };
  };

  diskSize = 1024;
  buildVMMemorySize = 512;
}

More examples can be found in the nixpkgs repo.

Also check out the excellent article by lethalman about building minimal docker images with nix.

Reproducible image dates

The manual advises against using created = "now", as that prevents images from being reproducible.

An alternative, if using flakes, is to do created = builtins.substring 0 8 self.lastModifiedDate, which uses the commit date, and is therefore reproducible.

How to calculate the sha256 of a pulled image

The sha256 argument of the dockerTools.pullImage function is the checksum of the archive generated by Skopeo. Since the archive contains the name and the tag of the image, Skopeo arguments used to fetch the image have to be identical to those used by the dockerTools.pullImage function.

For instance, the sha of the following image

pkgs.dockerTools.pullImage{
  imageName = "lnl7/nix";
  finalImageTag = "2.0";
  imageDigest = "sha256:632268d5fd9ca87169c65353db99be8b4e2eb41833b626e09688f484222e860f";
  sha256 = "1x00ks05cz89k3wc460i03iyyjr7wlr28krk7znavfy2qx5a0hfd";
};

can be manually generated with the following shell commands

skopeo copy docker://lnl7/nix@sha256:632268d5fd9ca87169c65353db99be8b4e2eb41833b626e09688f484222e860f docker-archive:///tmp/image.tgz:lnl7/nix:2.0
nix-hash --base32 --flat --type sha256 /tmp/image.tgz
1x00ks05cz89k3wc460i03iyyjr7wlr28krk7znavfy2qx5a0hfd

Docker Compose with Nix

Arion is created for running Nix-based projects in Docker Compose. It uses the NixOS module system for configuration, it can bypass docker build and lets you use dockerTools or use the store directly in the containers. The images/containers can be typical dockerTools style images or full NixOS configs.

To use Arion, you first need to add its module to you NixOS configuration:

modules = [ arion.nixosModules.arion ];

After that you can access its options under

virtualisation.arion = {}

A config for a simple container could look like this:

virtualisation.arion = {
  backend = "docker";
  projects = {
    "db" = settings.services."db".service = {
      image = "";
      restart = "unless-stopped";
      environment = { POSTGRESS_PASSWORD = "password"; };
    };
  };
};

Using Nix in containers

While dockerTools allows to build lightweight containers, it requires nix to be installed on the host system. An alternative are docker images with nix preinstalled:

See also

Workgroup:Container

As of 22.05 rootless docker is available. Alternatively you can use Podman.