-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstatic.nix
More file actions
132 lines (119 loc) · 4.58 KB
/
Copy pathstatic.nix
File metadata and controls
132 lines (119 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
{
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
# Unlike laravel.nix, the key here includes username, not the site name since static-generic
# can be used for multiple sites
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 "---"
'';
} ;
}