Added: Routes for learnlytics

This commit is contained in:
2026-02-25 11:54:11 +01:00
parent 6c842d4793
commit b204c1d133
4 changed files with 150 additions and 43 deletions

108
hosts/cyper-pi-1/nginx.nix Normal file
View File

@@ -0,0 +1,108 @@
{
pkgs,
...
}:
{
services.nginx = {
enable = true;
# ── Frontend ────────────────────────────────────────────────────────────
virtualHosts."learnlytics-frontend" = {
listen = [
{
addr = "0.0.0.0";
port = 80;
}
];
root = "/var/www/learnlytics";
locations."/" = {
tryFiles = "$uri $uri/ /index.html";
};
};
# ── API + avatars + upload ───────────────────────────────────────────────
virtualHosts."learnlytics-api" = {
listen = [
{
addr = "0.0.0.0";
port = 3002;
}
];
# PostgREST proxy (default)
locations."/" = {
proxyPass = "http://127.0.0.1:3001";
extraConfig = ''
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Prefer, Accept, Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Range, Content-Location' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Prefer, Accept, Range';
add_header 'Content-Length' '0';
add_header 'Content-Type' 'text/plain';
return 204;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_intercept_errors off;
client_max_body_size 1m;
'';
};
# Serve avatar images directly from disk
locations."/avatars/" = {
alias = "/var/lib/learnlytics/avatars/";
extraConfig = ''
expires 7d;
add_header Cache-Control "public, immutable";
add_header 'Access-Control-Allow-Origin' '*';
'';
};
# Proxy avatar uploads to the Python upload server on port 3003
locations."/upload/" = {
proxyPass = "http://127.0.0.1:3003";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 3m;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
add_header 'Content-Length' '0';
add_header 'Content-Type' 'text/plain';
return 204;
}
'';
};
};
};
# Avatar storage directory
systemd.tmpfiles.rules = [
"d /var/www/learnlytics 0755 nginx nginx -"
"d /var/lib/learnlytics 0755 postgres postgres -"
"d /var/lib/learnlytics/avatars 0755 postgres postgres -"
];
networking.firewall.allowedTCPPorts = [
3000
3001
3002
80
];
}