aboutsummaryrefslogtreecommitdiff
path: root/flake.nix
diff options
context:
space:
mode:
authorschererleander <leander@schererleander.de>2025-12-25 23:33:25 +0000
committerschererleander <leander@schererleander.de>2025-12-25 23:33:25 +0000
commitd82fb3b552d20a279efdd9408042183cfa02fb48 (patch)
tree4ffe818e591e54da71f7592506c873abf0d9d481 /flake.nix
parentd7edbf05ab0e90eedcb99e4462e3a61793b2eff9 (diff)
initial commit
Diffstat (limited to 'flake.nix')
-rw-r--r--flake.nix86
1 files changed, 47 insertions, 39 deletions
diff --git a/flake.nix b/flake.nix
index ab741a3..693c8ef 100644
--- a/flake.nix
+++ b/flake.nix
@@ -32,14 +32,23 @@
installPhase = ''
runHook preInstall
+
mkdir -p $out/share/web
- cp -r dist/* $out/share/web/
+
+ cp -r .next/standalone/* $out/share/web/
+
+ mkdir -p $out/share/web/.next
+ cp -r .next/static $out/share/web/.next/
+ cp -r public $out/share/web/
+
runHook postInstall
'';
};
in
{
- packages.default = site;
+ packages = {
+ default = site;
+ };
}
)
// {
@@ -61,64 +70,63 @@
in
{
options.services.site = {
- enable = mkEnableOption "Serve the built Vite site via nginx";
+ enable = mkEnableOption "Serve the built Next.js site using systemd";
domain = mkOption {
type = types.str;
description = "Domain to serve.";
};
- default = lib.mkOption {
- type = types.bool;
- default = false;
- description = "Make this vhost the default for nginx.";
+ port = mkOption {
+ type = types.port;
+ default = 3000;
+ description = "Port to expose on the host.";
};
package = mkOption {
type = types.package;
- description = "Package whose /share/web contains the built site.";
+ description = "The site package to run.";
default = self.packages.${pkgs.system}.default;
};
-
- sslCertificate = mkOption {
- type = types.nullOr types.path;
- default = null;
- description = "Path to TLS certificate (PEM).";
- };
- sslCertificateKey = mkOption {
- type = types.nullOr types.path;
- default = null;
- description = "Path to TLS private key (PEM).";
- };
};
config = mkIf cfg.enable {
+ systemd.services.site = {
+ description = "Next.js site service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
- assertions = [
- {
- assertion = (cfg.sslCertificate == null) == (cfg.sslCertificateKey == null);
- message = "services.site: sslCertificate and sslCertificateKey must be set together.";
- }
- ];
-
- services.nginx.enable = true;
+ serviceConfig = {
+ ExecStart = "${pkgs.nodejs}/bin/node ${cfg.package}/share/web/server.js";
+ WorkingDirectory = "${cfg.package}/share/web";
+ User = "nextjs";
+ Group = "nextjs";
+ Restart = "always";
+
+ # Hardening
+ DynamicUser = true;
+ PrivateTmp = true;
+ ProtectSystem = "strict";
+ ProtectHome = true;
+ NoNewPrivileges = true;
- services.nginx.virtualHosts.${cfg.domain} =
- let
- useTLS = (cfg.sslCertificate != null) && (cfg.sslCertificateKey != null);
- in
- {
- root = "${cfg.package}/share/web";
- default = cfg.default;
+ Environment = [
+ "NODE_ENV=production"
+ "PORT=${toString cfg.port}"
+ "HOSTNAME=127.0.0.1"
+ ];
+ };
+ };
+ services.nginx = {
+ enable = true;
+ virtualHosts.${cfg.domain} = {
locations."/" = {
- tryFiles = "$uri $uri/ /index.html";
+ proxyPass = "http://127.0.0.1:${toString cfg.port}";
+ proxyWebsockets = true;
};
-
- forceSSL = useTLS;
- sslCertificate = mkIf useTLS cfg.sslCertificate;
- sslCertificateKey = mkIf useTLS cfg.sslCertificateKey;
};
+ };
};
};
};