# Docker host with the daemon socket exposed over the network.
#
# SECURITY: the daemon listens on plain TCP 2375 with NO TLS and NO auth. Access
# to that port is root-equivalent on this host (the Docker API can mount the
# host filesystem and run privileged containers). The ONLY thing protecting it
# is the nftables rule below, which accepts 2375 solely from the trusted LAN
# subnet. Do not widen that subnet to anything you do not fully trust. The
# secure upgrade path is mutual TLS on 2376 (--tlsverify with client certs);
# that needs out-of-band cert provisioning and is intentionally not wired here.
{ ... }:
{
  virtualisation.docker.enable = true;

  # Expose the daemon over TCP by extending systemd socket activation rather than
  # setting daemon.settings.hosts. The NixOS docker unit starts dockerd with
  # `-H fd://` and takes its listeners from this socket; putting `hosts` in
  # daemon.json as well would conflict with that and dockerd would refuse to
  # start. Adding the TCP listener here keeps a single source of truth.
  # The leading "" resets the unit's default (unix-socket-only) ListenStream list.
  systemd.sockets.docker.socketConfig.ListenStream = [
    ""
    "/run/docker.sock"
    "0.0.0.0:2375"
  ];

  # Source-restricted firewall rule for the Docker TCP port. 2375 is deliberately
  # NOT added to networking.firewall.allowedTCPPorts (that would open it to every
  # source); instead nftables accepts it only from the trusted subnet. Adjust the
  # CIDR to match the LAN that should reach the Docker API.
  networking.nftables.enable = true;
  networking.firewall.extraInputRules = ''
    ip saddr 10.187.1.0/24 tcp dport 2375 accept
  '';
}
