diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..c6d2e2b --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1778672786, + "narHash": "sha256-Blg88K1jwG+P0Mr27+rKMFCufdrWkV3wWh9AdYtz0FQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eef00dfd8a712b34af845f9350bac681b1228bd1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..73f2f8e --- /dev/null +++ b/flake.nix @@ -0,0 +1,168 @@ +{ + description = "Local Docker Development DNS"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = + { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + packages = { + ldddns = pkgs.buildGo126Module { + pname = "ldddns"; + version = self.shortRev or self.dirtyShortRev or "dev"; + + src = self; + + # Relax the go directive to match the Go version available in nixpkgs. + prePatch = '' + substituteInPlace go.mod --replace-fail "go 1.26.3" "go 1.26" + ''; + + vendorHash = "sha256-FI7kSIn1QNDcEqDECiGNVLZ5z7LWPxxunK6eKH3D46Y="; + + # Tests require /etc/protocols which is unavailable in the Nix sandbox. + doCheck = false; + + env.CGO_ENABLED = 0; + + ldflags = [ + "-s" + "-w" + "-X main.version=${self.shortRev or self.dirtyShortRev or "dev"}" + ]; + + buildFlags = [ "-trimpath" ]; + + postInstall = '' + mv $out/bin/ldddns.arnested.dk $out/bin/ldddns + ''; + + meta = { + description = "Local Docker Development DNS"; + homepage = "https://ldddns.arnested.dk"; + license = pkgs.lib.licenses.mit; + maintainers = [ ]; + platforms = pkgs.lib.platforms.linux; + }; + }; + + default = self.packages.${system}.ldddns; + }; + + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + go_1_26 + gopls + goreleaser + ]; + }; + } + ) + // { + nixosModules.default = + { + config, + lib, + pkgs, + ... + }: + let + cfg = config.services.ldddns; + in + { + options.services.ldddns = { + enable = lib.mkEnableOption "ldddns - Local Docker Development DNS"; + + package = lib.mkPackageOption pkgs "ldddns" { + default = self.packages.${pkgs.system}.ldddns; + }; + + hostnameLookup = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ + "env:VIRTUAL_HOST" + "containerName" + ]; + description = "Methods for looking up hostnames for containers."; + }; + + ignoreDockerComposeOneoff = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to ignore docker-compose oneoff containers."; + }; + + gops = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Whether to enable the Google gops diagnostics agent."; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.ldddns = { + description = "Local Docker Development DNS"; + documentation = [ "https://ldddns.arnested.dk" ]; + bindsTo = [ + "docker.service" + "avahi-daemon.service" + ]; + after = [ + "docker.service" + "avahi-daemon.service" + ]; + wantedBy = [ "docker.service" ]; + + environment = { + LDDDNS_HOSTNAME_LOOKUP = lib.concatStringsSep "," cfg.hostnameLookup; + LDDDNS_IGNORE_DOCKER_COMPOSE_ONEOFF = + if cfg.ignoreDockerComposeOneoff then "true" else "false"; + LDDDNS_GOPS = if cfg.gops then "true" else "false"; + }; + + serviceConfig = { + Type = "notify"; + ExecStart = "${cfg.package}/bin/ldddns start"; + Restart = "on-failure"; + SupplementaryGroups = [ "docker" ]; + CapabilityBoundingSet = ""; + DevicePolicy = "closed"; + IPAddressDeny = "any"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateNetwork = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RestrictAddressFamilies = [ "AF_UNIX" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + SystemCallErrorNumber = "EPERM"; + SystemCallFilter = [ "@system-service" ]; + UMask = "0777"; + }; + }; + }; + }; + }; +}