inputs: { lib, pkgs ? import , ... }: let storeDirectory = dir: let dirName = builtins.baseNameOf dir; drv = derivation { name = dirName; src = dir; builder = pkgs.writeShellScript "builder.sh" '' ${pkgs.coreutils}/bin/mkdir -p $out/${dirName} ${pkgs.coreutils}/bin/cp -rf $src/* $out/${dirName} ${pkgs.coreutils}/bin/cp -rf $src/.* $out/${dirName} ''; system = pkgs.system; }; in "${drv}/${dirName}"; # nixos oci-containers fucking suck, so we just do a one-shot # systemd service that invokes docker-compose # # not very reproducible nor declarative, but compatible with pretty much # anything, which is (imo) more important for a home server mkDockerComposeContainer = { directory , name ? builtins.baseNameOf directory , autoStart ? true , extraConfig ? { } , env ? { } , envFiles ? [ ] , extraFlags ? [ ] }: let # referencing the file directly would make the service dependant # on the entire flake, resulting in the container being restarted # every time we change anything at all storeDir = storeDirectory directory; cmdline = [ "--build" "--remove-orphans" ] ++ map (env: "--env-file ${env}") envFiles ++ map (name: "-e ${name}=${lib.escapeShellArg env.${name}}") (builtins.attrNames env) ++ extraFlags; in { systemd.services."docker-compose-${name}" = { wantedBy = if autoStart then [ "multi-user.target" ] else [ ]; after = [ "docker.service" "docker.socket" ]; serviceConfig = { WorkingDirectory = storeDir; ExecStart = "${pkgs.docker}/bin/docker compose up ${builtins.concatStringsSep " " cmdline}"; ExecStopPost = "${pkgs.docker}/bin/docker compose down"; } // (extraConfig.serviceConfig or { }); } // (builtins.removeAttrs extraConfig [ "serviceConfig" ]); }; in mkDockerComposeContainer { directory = ./.; }