From 24b42352b3042b96e61fea09788cad97aa480cc4 Mon Sep 17 00:00:00 2001 From: efim Date: Sun, 6 Aug 2023 13:40:21 +0000 Subject: [PATCH] nix: nixos module for backend installation systemd to run service, nginx config bundled in --- flake.nix | 148 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 112 insertions(+), 36 deletions(-) diff --git a/flake.nix b/flake.nix index 0eea249..216dc4a 100644 --- a/flake.nix +++ b/flake.nix @@ -1,47 +1,123 @@ { - description = "Planning Poker web app. Trying to build something and learn new things"; + description = + "Planning Poker web app. Trying to build something and learn new things"; inputs.nixpkgs.url = "github:nixos/nixpkgs"; inputs.flake-utils.url = "github:numtide/flake-utils"; inputs.sbt-derivation.url = "github:zaninime/sbt-derivation/master"; inputs.sbt-derivation.inputs.nixpkgs.follows = "nixpkgs"; outputs = { self, nixpkgs, flake-utils, sbt-derivation }: - flake-utils.lib.eachDefaultSystem - (system: - let - pkgs = nixpkgs.legacyPackages.${system}; - packageName = "blanning-poker-kazbegi"; - version = "0.1.1"; - in { - devShells.default = pkgs.mkShell { - buildInputs = [ - pkgs.nodejs - pkgs.sbt - pkgs.scalafmt - pkgs.jdk - # pkgs.nodePackages.tailwindcss - # pkgs.nodePackages.postcss - ]; - shellHook = '' - echo "dev env for planning poker BWARGH started" - ''; - }; - packages.backend = sbt-derivation.lib.mkSbtDerivation rec { - inherit pkgs version; + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + packageName = "blanning-poker-kazbegi"; + backendName = "${packageName}-backend"; + version = "0.1.1"; + backendPackage = sbt-derivation.lib.mkSbtDerivation rec { + inherit pkgs version; - # ...and the rest of the arguments - pname = "${packageName}-backend"; - depsSha256 = "sha256-7MNlMeljYqXY4/kK4BXoycp9xUz0tGwCQvPTlE1RIQU="; - src = pkgs.nix-gitignore.gitignoreSource [] ./.; - buildPhase = '' - sbt backend/assembly - ''; - installPhase = '' - mkdir -p $out/bin - cp backend/target/scala-*/backend-assembly-*.jar $out/bin/ - ''; + # ...and the rest of the arguments + pname = "${backendName}"; + depsSha256 = "sha256-7MNlMeljYqXY4/kK4BXoycp9xUz0tGwCQvPTlE1RIQU="; + src = pkgs.nix-gitignore.gitignoreSource [ ] ./.; + buildPhase = '' + sbt backend/assembly + ''; + installPhase = '' + mkdir -p $out/bin + cp backend/target/scala-*/backend-assembly-*.jar $out/bin/${pname}.jar + ''; + }; + in { + # Development shell with things required for local dev + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.nodejs + pkgs.sbt + pkgs.scalafmt + pkgs.jdk + # pkgs.nodePackages.tailwindcss + # pkgs.nodePackages.postcss + ]; + shellHook = '' + echo "dev env for planning poker BWARGH started" + ''; + }; + # Just the backend jar + packages.backend = backendPackage; + # Module for NixOS to allow starting backend as SystemD service + nixosModules.backendApp = { config, pkgs, ... }: + let + cfg = config.services.${backendName}; + lib = pkgs.lib; + in { + options.services.${backendName} = { + enable = + lib.mkEnableOption "My frontendmentor exercise ${backendName}"; + + port = lib.mkOption { + type = lib.types.int; + default = 8080; + description = "Port to listen on."; + }; + + host = lib.mkOption { + type = lib.types.str; + default = "localhost"; + description = "Host to bind to."; + }; + + useNginx = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether to use Nginx to proxy requests."; + }; + }; + config = lib.mkIf cfg.enable { + users.groups."${backendName}-group" = { }; + users.users."${backendName}-user" = { + isSystemUser = true; + group = "${backendName}-group"; + }; + + systemd.services.${backendName} = + let serverHost = if cfg.useNginx then "localhost" else cfg.host; + in { + description = "Exercise app ${backendName}"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + startLimitIntervalSec = 30; + startLimitBurst = 10; + serviceConfig = { + ExecStart = + "${pkgs.jdk}/bin/java -jar ${backendPackage}/bin/${backendName}.jar -p ${ + toString cfg.port + } --host ${serverHost}"; + WorkingDirectory = "${backendPackage}/bin"; + Restart = "on-failure"; + User = "${backendName}-user"; + Group = "${backendName}-group"; + }; + }; + # this is only backend. Front end still configured and installed separately. + services.nginx.virtualHosts.${cfg.host}.locations."/api" = { + proxyPass = "http://127.0.0.1:${toString cfg.port}"; + # this is config for websocket + extraConfig = '' + rewrite ^/api/(.*)$ /$1 break; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Add the following lines for WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + ''; + }; + }; }; - } - ); + }); # see https://serokell.io/blog/practical-nix-flakes }