Just the source code for my personal website.
1{
2 description = "Personal website flake.";
3 inputs = {
4 nixpkgs.url = "nixpkgs/nixos-unstable";
5 naersk.url = "github:nix-community/naersk";
6 naersk.inputs.nixpkgs.follows = "nixpkgs";
7 };
8 outputs =
9 {
10 self,
11 nixpkgs,
12 naersk,
13 }:
14 let
15 supportedSystems = [
16 "x86_64-linux"
17 "aarch64-linux"
18 "x86_64-darwin"
19 "aarch64-darwin"
20 ];
21 forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
22 cargoConfig = builtins.fromTOML (builtins.readFile ./Cargo.toml);
23 pkgName = cargoConfig.package.name;
24 in
25 {
26 packages = forAllSystems (
27 system:
28 let
29 pkgs = (import nixpkgs) {
30 inherit system;
31 };
32 naersk' = pkgs.callPackage naersk { };
33 app = naersk'.buildPackage {
34 src = ./.;
35 postInstall = ''
36 cp -r ./templates ./static $out
37 '';
38 };
39 in
40 {
41 default = app;
42 docker = pkgs.dockerTools.streamLayeredImage {
43 name = "localhost/${pkgName}";
44 tag = "latest";
45 contents = [
46 app
47 pkgs.bash
48 ];
49 config.Cmd = [ "${app}/bin/${pkgName}" ];
50 };
51 }
52 );
53
54 nixosModules.default =
55 {
56 config,
57 pkgs,
58 lib,
59 ...
60 }:
61 let
62 cfg = config.crashkeys.services.${pkgName};
63 in
64 {
65 options = {
66 crashkeys.services.${pkgName} = {
67 enable = lib.mkEnableOption "Enables the crashkeys.dev web server.";
68 package = lib.mkOption {
69 type = lib.types.package;
70 default = self.packages.${pkgs.system}.default;
71 description = "The Nix package corresponding to the web server to run.";
72 };
73 public_url = lib.mkOption {
74 type = lib.types.str;
75 example = "https://crashkeys.dev";
76 description = ''
77 The base public URL the site will be available at.
78 Note that this value is only used to generate OpenGraph tags.
79 '';
80 };
81 address = lib.mkOption {
82 type = lib.types.str;
83 default = "127.0.0.1";
84 example = "127.0.0.1";
85 description = "The IP address which the web server will bind to.";
86 };
87 port = lib.mkOption {
88 type = lib.types.port;
89 default = 8000;
90 example = 8000;
91 description = "The TCP port on which the web server will be exposed.";
92 };
93 };
94 };
95 config =
96 let
97 # The generated systemd service unit's name
98 serviceName = "crashkeys.${pkgName}";
99 in
100 lib.mkIf cfg.enable {
101 systemd.services."${serviceName}" = {
102 wantedBy = [ "multi-user.target" ];
103 serviceConfig =
104 let
105 pkg = cfg.package;
106 in
107 {
108 Restart = "on-failure";
109 ExecStart = "${pkg}/bin/${pkgName}";
110 DynamicUser = "yes";
111
112 # The package includes the web server's static assets,
113 # so we must run it at its output directory in the Nix store
114 WorkingDirectory = "${pkg}";
115 RuntimeDirectory = "${serviceName}";
116 RuntimeDirectoryMode = "0755";
117 StateDirectory = "${serviceName}";
118 StateDirectoryMode = "0700";
119 CacheDirectory = "${serviceName}";
120 CacheDirectoryMode = "0750";
121 BindReadOnlyPaths = [
122 "${pkg}"
123 ];
124 Environment = [
125 "ROCKET_ADDRESS=${cfg.address}"
126 "ROCKET_PORT=${builtins.toString cfg.port}"
127 "ROCKET_PUBLIC_URL=${cfg.public_url}"
128 ];
129
130 NoNewPrivileges = true;
131 PrivateDevices = true;
132 ProtectClock = true;
133 CapabilityBoundingSet = ""; # Clear all capabilities
134 RestrictSUIDSGID = true;
135 ProtectKernelLogs = true;
136 ProtectControlGroups = true;
137 ProtectKernelModules = true;
138 PrivateMounts = true;
139 RestrictNamespaces = true;
140 ProtectHostname = true;
141
142 RestrictAddressFamilies = [
143 "AF_INET"
144 "AF_INET6"
145 "AF_UNIX"
146 ];
147 ProtectSystem = "full";
148 ProtectProc = "noaccess";
149 ProcSubset = "pid";
150 PrivateUsers = true;
151 PrivateTmp = true;
152 ProtectKernelTunables = true;
153 LockPersonality = true;
154 RestrictRealtime = true;
155 MemoryDenyWriteExecute = true;
156 };
157 };
158 };
159 };
160
161 # For `nix develop` (optional, can be skipped):
162 devShells = forAllSystems (
163 system:
164 let
165 pkgs = (import nixpkgs) {
166 inherit system;
167 };
168 in
169 {
170 default = pkgs.mkShell {
171 nativeBuildInputs = with pkgs; [
172 rustc
173 cargo
174 jujutsu
175 just
176 ];
177 };
178 }
179 );
180
181 formatter = forAllSystems (
182 system:
183 let
184 pkgs = (import nixpkgs) {
185 inherit system;
186 };
187 in
188 pkgs.nixfmt-tree
189 );
190 };
191}