Files
blog-service/flake.nix
T

101 lines
2.8 KiB
Nix

{
description = "Flake to build TS React App and run as a systemd service";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
};
outputs = { self, nixpkgs }: let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
reactApp = pkgs.buildNpmPackage {
name = "React Frontend";
version = "0.1.0";
src = "./.";
npmDepsHash = "";
# TODO: Configure npm building of frontend
};
nixosModule = {config, lib, pkgs, ...}:
let opts = config.services.blog-service; in
{
enableFrontend = lib.mkEnableOption "Enable Frontend of blog";
port = lib.mkOption {
type = lib.types.port;
description = "Port to host frontend";
};
credentialsFile = lib.mkOption {
type = lib.types.path;
description = "File containing secret environment variables";
};
default-nginx = {
enableNginx = lib.mkEnableOption "Enable nginx reverse proxy";
domainName = lib.mkOption {
type = lib.types.string;
description = "Domain name to host service";
};
};
config = lib.mkIf opts.enableFrontend {
systemd.services.blog-service = {
description = "Frontend of self-hosted blog";
wantedby = ["multi-user.target"];
after = ["network.target"];
environment = {
PORT = toString opts.port;
};
serviceConfig = {
ExecStart = "${reactApp}/bin/blog-service";
Restart = "always";
Type = "simple";
DynamicUser = "yes";
WorkingDirectory = "${reactApp}";
EnvironmentFile = "${opts.credentialsFile}";
};
};
services.nginx = lib.mkIf opts.default-nginx.enableNginx {
enable = true;
virtualHosts."${opts.default-nginx.domainName}" = {
forceSSL = true;
useACMEHost = let
b = builtins;
s = lib.strings;
fl = s.splitString "." "${opts.default-nginx.domainName}";
in b.concatStringsSep "." [ (b.elemAt fl (b.length fl - 2)) (b.elemAt fl (b.length fl - 1)) ];
locations."/" = {
proxyPass = "http://localhost:${toString opts.port}";
};
};
};
networking.firewall.allowedTCPPorts = lib.mkMerge [
(lib.mkIf opts.enableFrontend [ opts.port ])
(lib.mkIf opts.default-nginx.enableNginx [ 80 443 ])
];
};
};
in {
packages.${system}.default = reactApp;
apps.${system}.default = {
type = "app";
program = "${self.packages.${system}.default}/bin/blog-service";
};
nixosModules.${system}.default = nixosModule;
};
}