nix-git/modules/docker.nix

83 lines
2.8 KiB
Nix
Raw Normal View History

2023-09-14 15:54:48 +02:00
{ config, pkgs, ... }:
{
# https://nixos.wiki/wiki/Docker#Installation
# TODO: rootless Docker. https://nixos.wiki/wiki/Docker#Rootless_docker
# TODO: run as systemd services. https://nixos.wiki/wiki/Docker#docker_containers_as_systemd_services
virtualisation = {
docker = {
enable = true;
# As we use btrfs, we enable the according storageDriver option.
storageDriver = "btrfs";
2023-10-09 12:06:15 +02:00
# Run `docker system prune -f ${autoPrune.flags}` every week.
2023-09-14 15:54:48 +02:00
autoPrune.enable = true;
autoPrune.dates = "weekly";
# https://docs.docker.com/engine/reference/commandline/system_prune/#options
autoPrune.flags = [
"--all"
# https://docs.docker.com/engine/reference/commandline/system_prune/#filter
# https://pkg.go.dev/maze.io/x/duration#ParseDuration
2023-10-09 12:06:15 +02:00
# `7d` could not be parsed, thus we use `168h`
"--filter until=168h"
# `--volumes` can't be used together with `--filter`.
# Thus we added our own service below.
#--volumes
2023-09-14 15:54:48 +02:00
];
};
};
2023-10-08 20:03:00 +02:00
2023-10-09 12:06:15 +02:00
# Prune docker volumes.
# This is a slightly modified copy of https://github.com/NixOS/nixpkgs/blob/5a237aecb57296f67276ac9ab296a41c23981f56/nixos/modules/virtualisation/docker.nix#L211C5-L226
systemd.services."docker-prune-volumes" = {
description = "Prune docker volumes";
restartIfChanged = false;
unitConfig.X-StopOnRemoval = false;
serviceConfig.Type = "oneshot";
script = ''
${pkgs.docker}/bin/docker system prune -f --all --volumes
'';
startAt = "weekly";
after = [ "docker.service" ];
requires = [ "docker.service" ];
};
2023-10-08 20:03:00 +02:00
# Monitor unhealthy Docker containers.
systemd.timers."docker-health" = {
wantedBy = [ "timers.target" ];
partOf = [ "docker-health.service" ];
timerConfig = {
OnBootSec = "0m";
OnUnitInactiveSec = "3m";
AccuracySec = "15s";
RandomizedDelaySec = "15s";
};
};
systemd.services."docker-health" = {
serviceConfig = {
Type = "oneshot";
PrivateTmp = true;
# `docker` requires root access.
User = "root";
Nice = 19;
IOSchedulingClass = "idle";
};
path = with pkgs; [
docker
];
# If there are no unhealthy Docker containers, the output of `docker ps -f health=unhealthy` is just one line:
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# We filter this line with `grep -v`.
# As a result, grep returns exit code 1 if there are no unhealthy containers (as not a single line is printed).
# Thus, we prefix the whole command with `!`.
# Lastly, we redirect stdout to stderr with `1>&2` so that unhealthy containers are written to stderr.
script = ''
set -eu -o pipefail
! sudo docker ps -f health=unhealthy | grep -v 'CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES' 1>&2
'';
};
2023-09-14 15:54:48 +02:00
}