From 106b556ce7479acb69a8c7c7be9b046853295c11 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Wed, 13 May 2026 17:12:04 +0800 Subject: [PATCH] feat: add bare-metal deployment configs for Proxmox/LXC Provide ready-to-use nginx, systemd, and environment configs for bare-metal installs. Community Proxmox scripts currently sed-hack the Docker nginx.conf with patterns that don't match, causing broken pid/log paths and tmpfiles issues on reboot. --- deploy/guacd.conf | 3 + deploy/guacd.service | 12 + deploy/nginx.conf | 568 ++++++++++++++++++++++++++++++++++++++++++ deploy/termix.env | 4 + deploy/termix.service | 16 ++ 5 files changed, 603 insertions(+) create mode 100644 deploy/guacd.conf create mode 100644 deploy/guacd.service create mode 100644 deploy/nginx.conf create mode 100644 deploy/termix.env create mode 100644 deploy/termix.service diff --git a/deploy/guacd.conf b/deploy/guacd.conf new file mode 100644 index 00000000..94bb0be0 --- /dev/null +++ b/deploy/guacd.conf @@ -0,0 +1,3 @@ +[server] +bind_host = 127.0.0.1 +bind_port = 4822 diff --git a/deploy/guacd.service b/deploy/guacd.service new file mode 100644 index 00000000..b144e030 --- /dev/null +++ b/deploy/guacd.service @@ -0,0 +1,12 @@ +[Unit] +Description=Guacamole Proxy Daemon (guacd) +After=network.target + +[Service] +Type=simple +ExecStart=/usr/local/sbin/guacd -f -b 127.0.0.1 -l 4822 +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/deploy/nginx.conf b/deploy/nginx.conf new file mode 100644 index 00000000..d950f61a --- /dev/null +++ b/deploy/nginx.conf @@ -0,0 +1,568 @@ +worker_processes auto; +pid /run/nginx.pid; +error_log /var/log/nginx/error.log warn; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + access_log /var/log/nginx/access.log; + + sendfile on; + keepalive_timeout 65; + client_header_timeout 300s; + + set_real_ip_from 127.0.0.1; + real_ip_header X-Forwarded-For; + + map $http_x_forwarded_proto $proxy_x_forwarded_proto { + default $http_x_forwarded_proto; + '' $scheme; + } + + map $http_x_forwarded_host $proxy_x_forwarded_host { + default $http_x_forwarded_host; + '' $http_host; + } + + map $http_x_forwarded_port $proxy_x_forwarded_port { + default $http_x_forwarded_port; + '' ''; + } + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; + ssl_prefer_server_ciphers off; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + server { + listen 80; + server_name localhost; + + add_header X-Content-Type-Options nosniff always; + add_header X-XSS-Protection "1; mode=block" always; + + location = /sw.js { + root /opt/termix/html; + expires off; + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always; + try_files $uri =404; + } + + location = /manifest.json { + root /opt/termix/html; + expires off; + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always; + try_files $uri =404; + } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + root /opt/termix/html; + expires 1y; + add_header Cache-Control "public, max-age=31536000, immutable" always; + try_files $uri =404; + } + + location / { + root /opt/termix/html; + index index.html index.htm; + expires off; + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always; + try_files $uri $uri/ /index.html; + } + + location ~* \.map$ { + return 404; + access_log off; + log_not_found off; + } + + location ~ ^/users/sessions(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 $proxy_x_forwarded_proto; + } + + location ~ ^/users(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 $proxy_x_forwarded_proto; + proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; + proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host; + } + + location ~ ^/version(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/releases(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/alerts(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/rbac(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/credentials(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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_connect_timeout 60s; + proxy_send_timeout 300s; + proxy_read_timeout 300s; + } + + location ~ ^/snippets(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/c2s-tunnel-presets(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/terminal(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/database(/.*)?$ { + client_max_body_size 5G; + client_body_timeout 300s; + + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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_connect_timeout 60s; + proxy_send_timeout 300s; + proxy_read_timeout 300s; + + proxy_request_buffering off; + proxy_buffering off; + } + + location ~ ^/db(/.*)?$ { + client_max_body_size 5G; + client_body_timeout 300s; + + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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_connect_timeout 60s; + proxy_send_timeout 300s; + proxy_read_timeout 300s; + + proxy_request_buffering off; + proxy_buffering off; + } + + location ~ ^/encryption(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 /host/quick-connect { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $http_host; + proxy_cache_bypass $http_upgrade; + 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 ~ ^/host/opkssh-chooser(/.*)?$ { + proxy_pass http://127.0.0.1:30001/host/opkssh-chooser$1$is_args$args; + proxy_http_version 1.1; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host; + proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; + 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 $proxy_x_forwarded_proto; + + proxy_cache_bypass 1; + proxy_no_cache 1; + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; + } + + location ~ ^/host/opkssh-callback(/.*)?$ { + proxy_pass http://127.0.0.1:30001/host/opkssh-callback$1$is_args$args; + proxy_http_version 1.1; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host; + proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; + 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 $proxy_x_forwarded_proto; + + proxy_cache_bypass 1; + proxy_no_cache 1; + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; + } + + location /host/ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 /ssh/websocket/ { + proxy_pass http://127.0.0.1:30002/; + proxy_http_version 1.1; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host; + proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; + proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; + proxy_cache_bypass $http_upgrade; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_read_timeout 86400s; + proxy_send_timeout 86400s; + proxy_connect_timeout 10s; + + proxy_buffering off; + proxy_request_buffering off; + + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; + } + + location ^~ /guacamole/websocket/ { + proxy_pass http://127.0.0.1:30008/; + proxy_http_version 1.1; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_host; + proxy_cache_bypass $http_upgrade; + + 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_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Host $http_host; + + proxy_read_timeout 86400s; + proxy_send_timeout 86400s; + proxy_connect_timeout 10s; + + proxy_buffering off; + proxy_request_buffering off; + + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; + } + + location ~ ^/guacamole(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + 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 /host/tunnel/ { + proxy_pass http://127.0.0.1:30003; + proxy_http_version 1.1; + proxy_set_header Host $http_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 /ssh/tunnel/ { + proxy_pass http://127.0.0.1:30003; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_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_read_timeout 86400s; + proxy_send_timeout 86400s; + proxy_buffering off; + proxy_cache off; + } + + location /host/file_manager/recent { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 /host/file_manager/pinned { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 /host/file_manager/shortcuts { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 /host/file_manager/sudo-password { + proxy_pass http://127.0.0.1:30004; + proxy_http_version 1.1; + proxy_set_header Host $http_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 /ssh/file_manager/ { + client_max_body_size 5G; + client_body_timeout 300s; + + add_header Cache-Control "no-store, no-cache, must-revalidate" always; + + proxy_pass http://127.0.0.1:30004; + proxy_http_version 1.1; + proxy_set_header Host $http_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_connect_timeout 60s; + proxy_send_timeout 300s; + proxy_read_timeout 300s; + + proxy_request_buffering off; + proxy_buffering off; + } + + location /host/file_manager/ssh/ { + client_max_body_size 5G; + client_body_timeout 300s; + + add_header Cache-Control "no-store, no-cache, must-revalidate" always; + + proxy_pass http://127.0.0.1:30004; + proxy_http_version 1.1; + proxy_set_header Host $http_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_connect_timeout 60s; + proxy_send_timeout 300s; + proxy_read_timeout 300s; + + proxy_request_buffering off; + proxy_buffering off; + } + + location ~ ^/network-topology(/.*)?$ { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 /health { + proxy_pass http://127.0.0.1:30001; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/status(/.*)?$ { + proxy_pass http://127.0.0.1:30005; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/metrics(/.*)?$ { + proxy_pass http://127.0.0.1:30005; + proxy_http_version 1.1; + proxy_set_header Host $http_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_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + location ~ ^/(refresh|host-updated)$ { + proxy_pass http://127.0.0.1:30005; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/global-settings(/.*)?$ { + proxy_pass http://127.0.0.1:30005; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/uptime(/.*)?$ { + proxy_pass http://127.0.0.1:30006; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/activity(/.*)?$ { + proxy_pass http://127.0.0.1:30006; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ~ ^/dashboard/preferences(/.*)?$ { + proxy_pass http://127.0.0.1:30006; + proxy_http_version 1.1; + proxy_set_header Host $http_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 ^~ /docker/console/ { + proxy_pass http://127.0.0.1:30009/; + proxy_http_version 1.1; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_host; + proxy_cache_bypass $http_upgrade; + + 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_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Host $http_host; + + proxy_read_timeout 86400s; + proxy_send_timeout 86400s; + proxy_connect_timeout 10s; + + proxy_buffering off; + proxy_request_buffering off; + + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; + } + + location ~ ^/docker(/.*)?$ { + proxy_pass http://127.0.0.1:30007; + proxy_http_version 1.1; + proxy_set_header Host $http_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_connect_timeout 60s; + proxy_send_timeout 300s; + proxy_read_timeout 300s; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /opt/termix/html; + } + } +} diff --git a/deploy/termix.env b/deploy/termix.env new file mode 100644 index 00000000..58ab4c14 --- /dev/null +++ b/deploy/termix.env @@ -0,0 +1,4 @@ +NODE_ENV=production +DATA_DIR=/opt/termix/data +GUACD_HOST=127.0.0.1 +GUACD_PORT=4822 diff --git a/deploy/termix.service b/deploy/termix.service new file mode 100644 index 00000000..02ab41f4 --- /dev/null +++ b/deploy/termix.service @@ -0,0 +1,16 @@ +[Unit] +Description=Termix Backend +After=network.target guacd.service +Wants=guacd.service + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/termix +EnvironmentFile=/opt/termix/.env +ExecStart=/usr/bin/node /opt/termix/dist/backend/backend/starter.js +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target