Docker: Difference between revisions
imported>Eoli3n No edit summary |
m Use official nix search options |
||
(47 intermediate revisions by 27 users not shown) | |||
Line 1: | Line 1: | ||
[https://docker.com Docker] is a utility to pack, ship and run any application as a lightweight container. | |||
== | == Installation == | ||
<syntaxHighlight lang="nix"> | To install docker, add the following to your NixOS configuration: | ||
{ | |||
... | <syntaxHighlight lang=nix> | ||
virtualisation.docker. | virtualisation.docker.enable = true; | ||
} | </syntaxHighlight> | ||
[https://search.nixos.org/options?from=0&size=50&sort=alpha_asc&query=virtualisation.docker More options] are available. | |||
To get access to the docker socket, you have to be in the <code>docker</code> group:{{Warning|Beware that the docker group membership is effectively [https://github.com/moby/moby/issues/9976 equivalent to being root]! <br> Consider using rootless mode below.}} | |||
<syntaxhighlight lang="nix"> | |||
users.users.<myuser>.extraGroups = [ "docker" ]; | |||
</syntaxhighlight> | |||
After changing the group, a reboot or re-login might be required. | |||
===== Docker on btrfs ===== | |||
Note: If you use the [[btrfs]] file system, you might need to set the <code>storageDriver</code> 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. | |||
=== Changing Docker Daemon's Data Root === | |||
By default, the Docker daemon will store images, containers, and build context on the root file system. | |||
If you want to change the location that Docker stores its data, you can configure a new <code>data-root</code> for the daemon by setting the <code>data-root</code> property of the [https://search.nixos.org/options?show=virtualisation.docker.daemon.settings&from=0&size=50&sort=alpha_asc&type=packages&query=virtualisation.docker <code>virtualisation.docker.daemon.settings</code>]. | |||
<syntaxHighlight lang=nix> | |||
virtualisation.docker.daemon.settings = { | |||
data-root = "/some-place/to-store-the-docker-data"; | |||
}; | |||
</syntaxHighlight> | |||
=== Docker Containers as systemd Services === | |||
To make sure some docker containers are running as systemd services, you can use <code>oci-containers</code>: | |||
<syntaxHighlight lang=nix> | |||
virtualisation.oci-containers = { | |||
backend = "docker"; | |||
containers = { | |||
foo = { | |||
# ... | |||
}; | |||
}; | |||
}; | |||
</syntaxHighlight> | </syntaxHighlight> | ||
See [https://search.nixos.org/options?from=0&size=50&sort=alpha_asc&query=virtualisation.oci-containers oci-containers] for further options. | |||
<syntaxHighlight lang= | |||
{ | == Creating images with Nix == | ||
=== Building a docker image with nixpkgs === | |||
There is an entry for [https://nixos.org/nixpkgs/manual/#sec-pkgs-dockerTools dockerTools] in the Nixpkgs manual for reference. 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" ]; | |||
}; | |||
runAsRoot = '' | |||
#!${pkgs.runtimeShell} | |||
mkdir -p /data | |||
''; | |||
config = { | |||
Cmd = [ "/bin/redis-server" ]; | |||
WorkingDir = "/data"; | |||
Volumes = { "/data" = { }; }; | |||
}; | |||
diskSize = 1024; | |||
buildVMMemorySize = 512; | |||
} | } | ||
</syntaxHighlight> | </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 [https://lucabrunox.github.io/2016/04/cheap-docker-images-with-nix_15.html lethalman] about building minimal docker images with nix. | |||
=== Reproducible image dates === | |||
== How to calculate the <code>sha256</code> of a pulled image == | The manual advises against using <code>created = "now"</code>, as that prevents images from being 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 === | |||
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. | ||
For instance, the | |||
<syntaxHighlight lang= | For instance, the SHA of the following image | ||
<syntaxHighlight lang=nix> | |||
pkgs.dockerTools.pullImage{ | pkgs.dockerTools.pullImage{ | ||
imageName = "lnl7/nix"; | imageName = "lnl7/nix"; | ||
Line 38: | Line 127: | ||
can be manually generated with the following shell commands | can be manually generated with the following shell commands | ||
<syntaxHighlight> | |||
<syntaxHighlight lang=bash> | |||
skopeo copy docker://lnl7/nix@sha256:632268d5fd9ca87169c65353db99be8b4e2eb41833b626e09688f484222e860f docker-archive:///tmp/image.tgz:lnl7/nix:2.0 | |||
</syntaxHighlight> | |||
<syntaxHighlight lang=bash> | |||
nix-hash --base32 --flat --type sha256 /tmp/image.tgz | |||
</syntaxHighlight> | |||
<syntaxHighlight lang=shell> | |||
1x00ks05cz89k3wc460i03iyyjr7wlr28krk7znavfy2qx5a0hfd | 1x00ks05cz89k3wc460i03iyyjr7wlr28krk7znavfy2qx5a0hfd | ||
</syntaxHighlight> | </syntaxHighlight> | ||
== | === Directly Using Nix in Image Layers === | ||
Instead of copying Nix packages into Docker image layers, Docker can be configured to directly utilize the <code>nix-store</code> by integrating with [https://github.com/pdtpartners/nix-snapshotter nix-snapshotter]. | |||
This will significantly reduce data duplication and the time it takes to pull images. | |||
== Docker Compose == | |||
Currently, there are two options to use Docker Compose with NixOS: Arion or Compose2Nix. | |||
With Arion, you can specify most Docker Compose options in Nix Syntax, and Arion will generate a <code>docker-compose.yml</code> file internally. The result is a systemd service that starts and stops the container. | |||
Compose2Nix, generates all necessary configs directly from the <code>docker-compose.yml</code>, which is easier when using an already existing Docker Compose project. The result is similar to that from Arion: a systemd service is created that handles starting and stopping the container. | |||
=== Arion === | |||
[https://docs.hercules-ci.com/arion/ Arion] is created for running Nix-based projects in Docker Compose. It uses the NixOS module system for configuration, it can bypass <code>docker build</code> 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 your NixOS configuration: | |||
<syntaxHighlight lang=nix> | |||
modules = [ arion.nixosModules.arion ]; | |||
</syntaxHighlight> | |||
After that, you can access its options under | |||
<syntaxHighlight lang=nix> | |||
virtualisation.arion = {} | |||
</syntaxHighlight> | |||
A config for a simple container could look like this: | |||
<syntaxHighlight lang=nix> | |||
virtualisation.arion = { | |||
backend = "docker"; | |||
projects = { | |||
"db".settings.services."db".service = { | |||
image = ""; | |||
restart = "unless-stopped"; | |||
environment = { POSTGRESS_PASSWORD = "password"; }; | |||
}; | |||
}; | |||
}; | |||
</syntaxHighlight> | |||
=== Compose2Nix === | |||
With [https://github.com/aksiksi/compose2nix compose2nix] you can generate [https://search.nixos.org/options?query=virtualisation.oci-containers oci-containers] config from a <code>docker-compose.yaml</code>. | |||
===== Install ===== | |||
To use <code>compose2nix</code> with <code>nix-shell</code> you can use<syntaxhighlight lang="bash"> | |||
nix shell github:aksiksi/compose2nix | |||
compose2nix -h | |||
</syntaxhighlight>To install <code>compose2nix</code> to NixOS, add the repo to your flake inputs<syntaxhighlight lang="nix"> | |||
compose2nix = { | |||
url = "github:aksiksi/compose2nix"; | |||
inputs.nixpkgs.follows = "nixpkgs"; | |||
}; | |||
</syntaxhighlight>and add the package to your configuration<syntaxhighlight lang="nix"> | |||
environment.systemPackages = [ | |||
inputs.compose2nix.packages.x86_64-linux.default | |||
]; | |||
</syntaxhighlight> | |||
===== Usage ===== | |||
After you have installed <code>compose2nix</code>, you can run <code>compose2nix</code> in the directory with your <code>docker-compose.yml</code>, which will output a <code>docker-compose.nix</code>. | |||
Alternatively, you can specify the input and output files with the following flags<syntaxhighlight lang="bash"> | |||
compose2nix -inputs input.yml -output output.nix -runtime docker | |||
</syntaxhighlight>The <code>-runtime</code> flag specifies the runtime. Here, we select <code>docker</code>. Options are <code>podman</code> and <code>docker</code>. The default is <code>podman</code> | |||
== 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) | |||
NixOS can be run in containers [https://docs.hercules-ci.com/arion/#_nixos_run_full_os using Arion]. | |||
== Troubleshooting == | |||
=== Cannot connect to public Wi-Fi, when using Docker === | |||
When connecting to a public Wi-Fi, where the login page's IP-Address is within the Docker network range, accessing the Internet might not be possible. This has been [https://unix.stackexchange.com/a/539258 reported] when trying to connect to the WIFIonICE of the Deutsche Bahn (DB). They use the <code>172.18.x.x</code> address range. | |||
This can be resolved by changing the default address pool that Docker uses.<syntaxhighlight lang="nix"> | |||
virtualisation.docker = { | |||
enable = true; | |||
daemon.settings = { | |||
"default-address-pools" = [ | |||
{ "base" = "172.27.0.0/16"; "size" = 24; } | |||
]; | |||
}; | |||
}; | |||
</syntaxhighlight>Restarting, the container or Docker might be required. | |||
== See also == | == See also == | ||
[[Workgroup:Container]] | |||
[[ | Alternatively you can use [[Podman | podman]]. | ||
[[Category: | [[Category:Cookbook]] | ||
[[Category: | [[Category:Software]] | ||
[[Category: | [[Category:Server]] | ||
[[Category: | [[Category:Container]] |
Latest revision as of 15:09, 20 September 2024
Docker is a utility to pack, ship and run any application as a lightweight container.
Installation
To install docker, add the following to your NixOS configuration:
virtualisation.docker.enable = true;
More options are available.
To get access to the docker socket, you have to be in the docker
group:
users.users.<myuser>.extraGroups = [ "docker" ];
After changing the group, a reboot or re-login might be required.
Docker on btrfs
Note: If you use the btrfs file system, 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.
Changing Docker Daemon's Data Root
By default, the Docker daemon will store images, containers, and build context on the root file system.
If you want to change the location that Docker stores its data, you can configure a new data-root
for the daemon by setting the data-root
property of the virtualisation.docker.daemon.settings
.
virtualisation.docker.daemon.settings = {
data-root = "/some-place/to-store-the-docker-data";
};
Docker Containers as systemd Services
To make sure some docker containers are running as systemd services, you can use oci-containers
:
virtualisation.oci-containers = {
backend = "docker";
containers = {
foo = {
# ...
};
};
};
See oci-containers for further options.
Creating images with Nix
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
Directly Using Nix in Image Layers
Instead of copying Nix packages into Docker image layers, Docker can be configured to directly utilize the nix-store
by integrating with nix-snapshotter.
This will significantly reduce data duplication and the time it takes to pull images.
Docker Compose
Currently, there are two options to use Docker Compose with NixOS: Arion or Compose2Nix.
With Arion, you can specify most Docker Compose options in Nix Syntax, and Arion will generate a docker-compose.yml
file internally. The result is a systemd service that starts and stops the container.
Compose2Nix, generates all necessary configs directly from the docker-compose.yml
, which is easier when using an already existing Docker Compose project. The result is similar to that from Arion: a systemd service is created that handles starting and stopping the container.
Arion
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 your 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"; };
};
};
};
Compose2Nix
With compose2nix you can generate oci-containers config from a docker-compose.yaml
.
Install
To use compose2nix
with nix-shell
you can use
nix shell github:aksiksi/compose2nix
compose2nix -h
To install compose2nix
to NixOS, add the repo to your flake inputs
compose2nix = {
url = "github:aksiksi/compose2nix";
inputs.nixpkgs.follows = "nixpkgs";
};
and add the package to your configuration
environment.systemPackages = [
inputs.compose2nix.packages.x86_64-linux.default
];
Usage
After you have installed compose2nix
, you can run compose2nix
in the directory with your docker-compose.yml
, which will output a docker-compose.nix
.
Alternatively, you can specify the input and output files with the following flags
compose2nix -inputs input.yml -output output.nix -runtime docker
The -runtime
flag specifies the runtime. Here, we select docker
. Options are podman
and docker
. The default is podman
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:
- nixos/nix (official)
- nixpkgs/nix (built from https://github.com/nix-community/docker-nixpkgs)
NixOS can be run in containers using Arion.
Troubleshooting
Cannot connect to public Wi-Fi, when using Docker
When connecting to a public Wi-Fi, where the login page's IP-Address is within the Docker network range, accessing the Internet might not be possible. This has been reported when trying to connect to the WIFIonICE of the Deutsche Bahn (DB). They use the 172.18.x.x
address range.
This can be resolved by changing the default address pool that Docker uses.
virtualisation.docker = {
enable = true;
daemon.settings = {
"default-address-pools" = [
{ "base" = "172.27.0.0/16"; "size" = 24; }
];
};
};
Restarting, the container or Docker might be required.
See also
Alternatively you can use podman.