1{ config, pkgs, lib, ... }:
2
3{
4 # Basic system config
5 networking.firewall.allowedTCPPorts = [ 80 443 ];
6
7 # Rust toolchain for building docs
8 environment.systemPackages = with pkgs; [
9 rustup
10 git
11 cargo
12 ];
13
14 # Build script to generate docs
15 environment.etc."rustdoc-build.sh" = {
16 text = ''
17 #!/usr/bin/env bash
18 set -euo pipefail
19
20 REPO_URL="''${1:-https://github.com/orual/jacquard.git}"
21 BRANCH="''${2:-main}"
22 BUILD_DIR="/var/www/rustdoc/build"
23 OUTPUT_DIR="/var/www/rustdoc/docs"
24
25 echo "Building docs from $REPO_URL ($BRANCH)..."
26
27 # Clean and clone
28 rm -rf "$BUILD_DIR"
29 git clone --depth 1 --branch "$BRANCH" "$REPO_URL" "$BUILD_DIR"
30 cd "$BUILD_DIR"
31
32 # Build docs with all features for jacquard-api
33 export RUSTDOCFLAGS="--html-in-header /etc/rustdoc-analytics.html"
34 cargo doc \
35 --no-deps \
36 --workspace \
37 --all-features \
38 --document-private-items
39
40 # Copy to serving directory
41 rm -rf "$OUTPUT_DIR"
42 cp -r target/doc "$OUTPUT_DIR"
43
44 # Create index redirect
45 cat > "$OUTPUT_DIR/index.html" <<EOF
46 <!DOCTYPE html>
47 <html>
48 <head>
49 <meta http-equiv="refresh" content="0; url=jacquard/index.html">
50 <title>Jacquard Documentation</title>
51 </head>
52 <body>
53 <p>Redirecting to <a href="jacquard/index.html">jacquard documentation</a>...</p>
54 </body>
55 </html>
56 EOF
57
58 chown -R nginx:nginx "$OUTPUT_DIR"
59 echo "Build complete! Docs available at $OUTPUT_DIR"
60 '';
61 mode = "0755";
62 };
63
64 # Optional analytics snippet (empty by default)
65 environment.etc."rustdoc-analytics.html" = {
66 text = ''
67 <!-- Add analytics/plausible/umami script here if desired -->
68 '';
69 };
70
71 # Nginx to serve the docs
72 services.nginx = {
73 enable = true;
74 recommendedGzipSettings = true;
75 recommendedOptimisation = true;
76 recommendedProxySettings = true;
77 recommendedTlsSettings = true;
78
79 virtualHosts."docs.example.com" = {
80 # Set this to your actual domain
81 # serverName = "docs.jacquard.dev";
82
83 # For cloudflare tunnel, you don't need ACME here
84 # If you want direct HTTPS:
85 # enableACME = true;
86 # forceSSL = true;
87
88 root = "/var/www/rustdoc/docs";
89
90 locations."/" = {
91 tryFiles = "$uri $uri/ =404";
92 extraConfig = ''
93 # Cache static assets
94 location ~* \.(css|js|woff|woff2)$ {
95 expires 1y;
96 add_header Cache-Control "public, immutable";
97 }
98
99 # CORS headers for cross-origin font loading
100 location ~* \.(woff|woff2)$ {
101 add_header Access-Control-Allow-Origin "*";
102 }
103 '';
104 };
105 };
106 };
107
108 # Create serving directory
109 systemd.tmpfiles.rules = [
110 "d /var/www/rustdoc 0755 nginx nginx -"
111 "d /var/www/rustdoc/build 0755 nginx nginx -"
112 "d /var/www/rustdoc/docs 0755 nginx nginx -"
113 ];
114
115 # Optional: systemd service for periodic rebuilds
116 systemd.services.rustdoc-build = {
117 description = "Build Jacquard documentation";
118 serviceConfig = {
119 Type = "oneshot";
120 ExecStart = "${pkgs.bash}/bin/bash /etc/rustdoc-build.sh";
121 User = "nginx";
122 };
123 };
124
125 # Optional: timer to rebuild daily
126 systemd.timers.rustdoc-build = {
127 wantedBy = [ "timers.target" ];
128 timerConfig = {
129 OnCalendar = "daily";
130 Persistent = true;
131 };
132 };
133
134 # Optional: webhook receiver for rebuild-on-push
135 # Uncomment if you want webhook triggers
136 # services.webhook = {
137 # enable = true;
138 # hooks = {
139 # rebuild-docs = {
140 # execute-command = "/etc/rustdoc-build.sh";
141 # command-working-directory = "/tmp";
142 # };
143 # };
144 # };
145}