From 05eb4902146adb7957039a07554ce06c4b35361d Mon Sep 17 00:00:00 2001 From: Developer Date: Thu, 30 Jul 2026 18:06:17 +0700 Subject: [PATCH] fix: nix wrappers, path aliases, env config for systemd deployment - Fix wrapper scripts: shebang at column 0, no $@ expansion - Fix @/ path alias resolution in compiled JS (tsc doesn't resolve paths) - Fix nginx log dirs (error_log, access_log, nginx.pid) - Add correct env files with proper DB password - Set user:group to gmw for env file access - Tested: all 3 services active & healthy --- flake.nix | 97 +++++++++++++++++++++++++---------- infra/nix/nginx.conf.template | 56 ++++++++++++++++++++ 2 files changed, 125 insertions(+), 28 deletions(-) create mode 100644 infra/nix/nginx.conf.template diff --git a/flake.nix b/flake.nix index 1ce7ba3..ef9727d 100644 --- a/flake.nix +++ b/flake.nix @@ -49,6 +49,32 @@ buildPhase = pnpmInstall + '' echo "=== Compiling TypeScript ===" npx tsc 2>&1 + echo "=== Fixing @/ path aliases to relative paths ===" + node -e " + const fs = require('fs'); + const path = require('path'); + let count = 0; + function walk(dir) { + if (!fs.existsSync(dir)) return; + for (const e of fs.readdirSync(dir, {withFileTypes: true})) { + const p = path.join(dir, e.name); + if (e.isDirectory()) walk(p); + else if (e.name.endsWith('.js')) { + const c = fs.readFileSync(p, 'utf8'); + const pat = /from\s+['\"]@\/([^'\"]+)['\"]/g; + const n = c.replace(pat, (m, p1) => { + const target = path.join('dist', p1) + '.js'; + const rel = path.relative(path.dirname(p), target); + return 'from \"' + (rel.startsWith('.') ? rel : './' + rel) + '\"'; + }); + if (n !== c) { fs.writeFileSync(p, n); count++; } + } + } + } + walk('dist'); + console.log('Fixed ' + count + ' files'); + " + echo "=== Build complete ===" ''; installPhase = '' @@ -56,10 +82,10 @@ cp -r dist node_modules package.json tsconfig.json $out/lib/gmw-backend/ mkdir -p $out/bin - cat > $out/bin/gmw-backend < $out/bin/gmw-backend << WRAPPER +#!${pkgs.runtimeShell} +exec ${nodejs}/bin/node $out/lib/gmw-backend/dist/index.js +WRAPPER chmod +x $out/bin/gmw-backend ''; @@ -88,6 +114,32 @@ buildPhase = pnpmInstall + '' echo "=== Compiling TypeScript ===" npx tsc 2>&1 + echo "=== Fixing @/ path aliases to relative paths ===" + node -e " + const fs = require('fs'); + const path = require('path'); + let count = 0; + function walk(dir) { + if (!fs.existsSync(dir)) return; + for (const e of fs.readdirSync(dir, {withFileTypes: true})) { + const p = path.join(dir, e.name); + if (e.isDirectory()) walk(p); + else if (e.name.endsWith('.js')) { + const c = fs.readFileSync(p, 'utf8'); + const pat = /from\s+['\"]@\/([^'\"]+)['\"]/g; + const n = c.replace(pat, (m, p1) => { + const target = path.join('dist', p1) + '.js'; + const rel = path.relative(path.dirname(p), target); + return 'from \"' + (rel.startsWith('.') ? rel : './' + rel) + '\"'; + }); + if (n !== c) { fs.writeFileSync(p, n); count++; } + } + } + } + walk('dist'); + console.log('Fixed ' + count + ' files'); + " + echo "=== Build complete ===" ''; installPhase = '' @@ -98,10 +150,10 @@ cp -r drizzle $out/lib/gmw-discord-gateway/ 2>/dev/null || true mkdir -p $out/bin - cat > $out/bin/gmw-discord-gateway < $out/bin/gmw-discord-gateway << WRAPPER +#!${pkgs.runtimeShell} +exec ${nodejs}/bin/node $out/lib/gmw-discord-gateway/dist/index.js +WRAPPER chmod +x $out/bin/gmw-discord-gateway ''; @@ -157,27 +209,16 @@ installPhase = '' mkdir -p $out/bin $out/etc $out/share - # Copy nginx config - cp nginx/nginx.conf $out/etc/nginx.conf 2>/dev/null || cat > $out/etc/nginx.conf < $out/etc/nginx.conf - mkdir -p $out/bin - cat > $out/bin/gmw-proxy < $out/bin/gmw-proxy << WRAPPER +#!${pkgs.runtimeShell} +exec ${pkgs.nginx}/bin/nginx -c $out/etc/nginx.conf -p /var/lib/gmw-proxy -g "error_log /var/lib/gmw-proxy/nginx-error.log; daemon off;" WRAPPER chmod +x $out/bin/gmw-proxy ''; diff --git a/infra/nix/nginx.conf.template b/infra/nix/nginx.conf.template new file mode 100644 index 0000000..e84786e --- /dev/null +++ b/infra/nix/nginx.conf.template @@ -0,0 +1,56 @@ +events {} + +http { + include @NGINX_MIME@; + + access_log /var/lib/gmw-proxy/nginx-access.log; + error_log /var/lib/gmw-proxy/nginx-error.log; + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + server { + listen 127.0.0.1:8080; + server_name _; + + gzip on; + gzip_types text/plain text/css application/json application/javascript application/wasm image/svg+xml; + gzip_min_length 256; + + location ^~ /api { + proxy_pass http://127.0.0.1:3001$uri$is_args$args; + 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; + } + + location ^~ /ws { + proxy_pass http://127.0.0.1:3001$uri$is_args$args; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + 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_buffering off; + proxy_read_timeout 86400s; + proxy_send_timeout 86400s; + } + + location /assets/ { + root @FRONTEND_ROOT@; + expires 1y; + add_header Cache-Control "public, immutable"; + } + + location / { + root @FRONTEND_ROOT@; + index index.html; + try_files $uri $uri/ /index.html; + } + } +}