{ inputs = { utils.url = "github:numtide/flake-utils"; nixpkgs.url = "github:NixOS/nixpkgs/master"; nix-filter.url = "github:numtide/nix-filter"; }; outputs = { self, nixpkgs, utils, nix-filter, }: utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; filter = nix-filter.lib; nodejs = pkgs.nodejs-18_x; node_modules = pkgs.stdenv.mkDerivation { name = "node_modules"; src = filter { root = ./.; include = [ ./package.json ./package-lock.json ]; }; __noChroot = true; configurePhase = '' export HOME=$TMP ''; buildInputs = [ nodejs ]; buildPhase = '' ${nodejs}/bin/npm ci ''; installPhase = '' mkdir $out mv node_modules $out/node_modules ''; }; in { packages = { default = pkgs.stdenv.mkDerivation { name = "tempest.dev"; src = filter { root = ./.; exclude = [ ./.next ./node_modules ]; }; nativeBuildInputs = [ nodejs ]; buildPhase = ''npm run build''; configurePhase = '' ln -sf ${node_modules}/node_modules node_modules export HOME=$TMP ''; installPhase = '' # Use the standalone nextjs version mv .next/standalone $out # Copy non-generated static files if [ -d "public" ]; then cp -R public $out/public fi # Also copy generated static files mv .next/static $out/.next/static # Re-link the node_modules rm $out/node_modules mv node_modules $out/node_modules # Link cache directory ln -s /tmp $out/.next/cache # Wrap the script cat < $out/entrypoint #!${pkgs.stdenv.shell} exec "$(type -p node)" "$out/server.js" "$$@" ENTRYPOINT chmod +x $out/entrypoint ''; }; }; }) // { nixosModule = {config, lib, pkgs, ...}: with lib; let cfg = config.ashe.services."tempest.dev"; in { options.ashe.services."tempest.dev" = { enable = mkEnableOption "Enables the tempest.dev HTTP service"; port = mkOption rec { type = types.int; default = 8000; example = default; description = "The port for this service to listen on"; }; domain = mkOption rec { type = types.str; default = "tempest.dev"; example = default; description = "The domain name for tempest.dev"; }; }; config = mkIf cfg.enable { systemd.services."ashe.tempest.dev" = { wantedBy = [ "multi-user.target" ]; serviceConfig = let pkg = self.packages.${pkgs.system}.default; in { Restart = "on-failure"; ExecStart = "${pkg}/entrypoint"; DynamicUser = "yes"; PrivateTmp = "yes"; Environment = [ "PORT=${toString cfg.port}" ]; }; }; services.nginx.virtualHosts.${cfg.domain} = { locations."/" = { proxyPass = "http://127.0.0.1:${toString cfg.port}"; }; forceSSL = true; enableACME = true; }; }; }; }; }