mirror of
https://github.com/archtechx/nix.git
synced 2025-12-12 11:24:04 +00:00
130 lines
4.5 KiB
Nix
130 lines
4.5 KiB
Nix
{
|
|
name, # Name of the site, /srv/{name} will be based on this as well as the username if user = true
|
|
root, # The directory within /srv/{name} that should be served by nginx
|
|
user ? false, # Should a user be created. If false, static-generic is used
|
|
domains ? [], # e.g. [ "example.com" "acme.com" ]
|
|
ssl ? false, # Should SSL be used
|
|
wwwRedirect ? null, # The status code used for www-to-non-www redirects. Null means no redirect
|
|
cloudflareOnly ? false, # Should CF Authenticated Origin Pulls be used
|
|
extraNginxConfig ? null, # Extra nginx config string
|
|
sshKeys ? null, # SSH public keys used to log into the site's user for deployments
|
|
extraPackages ? [], # Any extra packages the user should have in $PATH (only used with user=true)
|
|
generateSshKey ? true, # Generate an SSH key for the user (used for GH deploy keys)
|
|
...
|
|
}:
|
|
|
|
{ lib, pkgs, ... }:
|
|
let
|
|
username = if user then "static-${name}" else "static-generic";
|
|
in {
|
|
services.nginx.enable = true;
|
|
security.acme.acceptTerms = true;
|
|
networking.firewall.allowedTCPPorts = [ 80 ] ++ lib.optionals ssl [ 443 ];
|
|
|
|
services.nginx.virtualHosts = lib.genAttrs domains (domain: {
|
|
enableACME = ssl;
|
|
forceSSL = ssl;
|
|
root = "/srv/${name}/${root}";
|
|
|
|
extraConfig = ''
|
|
${lib.optionalString cloudflareOnly ''
|
|
ssl_verify_client on;
|
|
ssl_client_certificate ${pkgs.fetchurl {
|
|
url = "https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem";
|
|
sha256 = "0hxqszqfzsbmgksfm6k0gp0hsx9k1gqx24gakxqv0391wl6fsky1";
|
|
}};
|
|
''}
|
|
${lib.optionalString (extraNginxConfig != null) extraNginxConfig}
|
|
'';
|
|
|
|
locations = {
|
|
"= /favicon.ico".extraConfig = ''
|
|
access_log off;
|
|
log_not_found off;
|
|
'';
|
|
|
|
"= /robots.txt".extraConfig = ''
|
|
access_log off;
|
|
log_not_found off;
|
|
'';
|
|
};
|
|
}) // lib.optionalAttrs (wwwRedirect != null) (lib.genAttrs (map (domain: "www.${domain}") domains) (wwwDomain: {
|
|
enableACME = ssl;
|
|
forceSSL = ssl;
|
|
|
|
locations."/" = {
|
|
return = "${toString wwwRedirect} ${if ssl then "https" else "http"}://${lib.removePrefix "www." wwwDomain}$request_uri";
|
|
};
|
|
}));
|
|
|
|
systemd.tmpfiles.rules = [
|
|
"d /srv 0751 root root - -"
|
|
"d /home 0751 root root - -"
|
|
"d /srv/${name} 0750 ${username} ${username} - -"
|
|
] ++ lib.optional user
|
|
"C /home/${username}/.bashrc 0640 ${username} ${username} - /etc/static-${name}-bashrc";
|
|
|
|
# User and group settings
|
|
users.users.${username} = {
|
|
group = username;
|
|
isSystemUser = true;
|
|
createHome = true;
|
|
home = "/home/${username}";
|
|
homeMode = "750";
|
|
shell = pkgs.bashInteractive;
|
|
packages = [ pkgs.git pkgs.unzip ] ++ lib.optionals user extraPackages;
|
|
} // lib.optionalAttrs (sshKeys != null && user) {
|
|
openssh.authorizedKeys.keys = sshKeys;
|
|
};
|
|
|
|
users.groups.${username} = {};
|
|
|
|
# Add site group to nginx service
|
|
systemd.services.nginx.serviceConfig.SupplementaryGroups = [ username ];
|
|
|
|
# SSH key generation for git deployments
|
|
# Note: keep in sync with laravel.nix
|
|
systemd.services."generate-ssh-key-${username}" = lib.mkIf generateSshKey {
|
|
description = "Generate SSH key for ${username}";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "users.target" ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
User = "root";
|
|
};
|
|
script = ''
|
|
USER_HOME="/home/${username}"
|
|
SSH_DIR="$USER_HOME/.ssh"
|
|
KEY_FILE="$SSH_DIR/id_ed25519"
|
|
|
|
if [[ ! -f "$KEY_FILE" ]]; then
|
|
echo "Generating SSH key for ${username}"
|
|
mkdir -p "$SSH_DIR"
|
|
${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f "$KEY_FILE" -N "" -C "${username}"
|
|
chown -R ${username}:${username} "$SSH_DIR"
|
|
chmod 700 "$SSH_DIR"
|
|
chmod 600 "$KEY_FILE"
|
|
chmod 640 "$KEY_FILE.pub"
|
|
echo "SSH key generated: $KEY_FILE.pub"
|
|
echo "Public key for deploy key:"
|
|
cat "$KEY_FILE.pub"
|
|
else
|
|
echo "SSH key already exists for ${username}"
|
|
fi
|
|
'';
|
|
};
|
|
|
|
# Create welcome message for user
|
|
# Note: keep in sync with laravel.nix (same block, minor changes here)
|
|
environment.etc."static-${name}-bashrc" = lib.mkIf user {
|
|
text = ''
|
|
echo "Welcome to ${name} static site!"
|
|
echo "Domains: ${lib.concatStringsSep ", " domains}"
|
|
echo "User home: /home/${username}"
|
|
echo "Site: /srv/${name}"
|
|
${lib.optionalString generateSshKey ''echo "SSH public key: cat ~/.ssh/id_ed25519.pub"''}
|
|
echo "---"
|
|
'';
|
|
} ;
|
|
}
|