From: Shane Jaroch Date: Mon, 19 Jan 2026 08:18:36 +0000 (-0500) Subject: wip X-Git-Url: https://git.nutra.tk/v2?a=commitdiff_plain;h=f14e8499f28f79ae5b680b89c230ef207cec1267;p=nutratech%2Fvps-root.git wip --- diff --git a/.env b/.env index 22eca3c..26e3b79 100644 --- a/.env +++ b/.env @@ -1,4 +1,7 @@ -VPS_HOST=dev.nutra.tk +VPS_HOST_DEV=dev.nutra.tk +VPS_HOST_PROD=nutra.tk +VPS_HOST=$(VPS_HOST_DEV) +#VPS_HOST=$(VPS_HOST_PROD) VPS_USER=gg export SUDO_USER=gg export OWNER="Shane J" diff --git a/Makefile b/Makefile index 3e0d556..8837b9a 100644 --- a/Makefile +++ b/Makefile @@ -40,9 +40,18 @@ VPS_USER ?= gg VPS := $(VPS_USER)@$(VPS_HOST) +# Detect Environment +ifeq ($(VPS_HOST),$(VPS_HOST_DEV)) + ENV := dev +else ifeq ($(VPS_HOST),$(VPS_HOST_PROD)) + ENV := prod +else + ENV := dev +endif + .PHONY: stage/nginx stage/nginx: ##H @Remote Stage files on the remote VPS - @echo "Staging files on $(VPS_HOST)..." + @echo "Staging files on $(VPS_HOST) (ENV=$(ENV))..." python3 scripts/gen_services_map.py ssh $(VPS) 'rm -rf ~/.nginx-staging && mkdir -p ~/.nginx-staging/etc/nginx/conf.d ~/.nginx-staging/scripts/gitweb-simplefrontend' scp -q -r etc/nginx/conf.d/*.conf $(VPS):~/.nginx-staging/etc/nginx/conf.d/ @@ -60,7 +69,7 @@ diff/nginx: ##H @Remote Show diff between local and remote deploy/nginx: ##H @Remote Deploy staged files to remote deploy/nginx: stage/nginx test/nginx diff/nginx @echo "Deploying checked-in nginx config to $(VPS_HOST)..." - ssh -t $(VPS) "bash ~/.nginx-staging/scripts/deploy.sh" + ssh -t $(VPS) "bash ~/.nginx-staging/scripts/deploy.sh $(ENV)" .PHONY: test/nginx test/nginx: ##H @Remote Test staged configuration without deploying diff --git a/etc/nginx/conf.d/default.conf b/etc/nginx/conf.d/default.conf deleted file mode 100644 index b866859..0000000 --- a/etc/nginx/conf.d/default.conf +++ /dev/null @@ -1,203 +0,0 @@ -# API -server { - # Service: API | https://api.dev.nutra.tk - server_name api-dev.nutra.tk api.dev.nutra.tk; - #listen 80; - listen 443 ssl; - listen 443 quic; - listen [::]:443 quic; - http2 on; - http3 on; - add_header Alt-Svc 'h3=":443"; ma=86400' always; - # HSTS - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; - - # Sanic - location / { - proxy_pass http://127.0.0.1:20000; # API server - # Allow fast streaming HTTP/1.1 pipes (keep-alive, unbuffered) - proxy_http_version 1.1; - proxy_request_buffering off; - proxy_buffering off; - # Proxy forwarding (password configured in app.config.FORWARDED_SECRET) - # and stored in: /etc/nginx/conf.d/secrets.conf - proxy_set_header forwarded "$proxy_forwarded;secret=\"$proxy_secret_key\""; - # Allow websockets and keep-alive (avoid connection: close) - proxy_set_header connection "upgrade"; - proxy_set_header upgrade $http_upgrade; - } - - # default favicon - location /favicon.ico { - alias /var/www/favicon.gif; - } -} - - -# Store Front (MedusaJS) -server { - # Service: Store | https://store.nutra.tk - server_name store.nutra.tk; - #listen 80; - listen 443 ssl; - listen 443 quic; - listen [::]:443 quic; - http2 on; - http3 on; - add_header Alt-Svc 'h3=":443"; ma=86400' always; - location / { - proxy_pass http://localhost:8000; - } -} - -# Store [Admin UI] (MedusaJS) -server { - # Service: Store Admin | https://store-admin-8b56411b.nutra.tk - server_name store-api.nutra.tk store-admin-8b56411b.nutra.tk; - #listen 80; - listen 443 ssl; - listen 443 quic; - listen [::]:443 quic; - http2 on; - http3 on; - add_header Alt-Svc 'h3=":443"; ma=86400' always; - location / { - proxy_pass http://localhost:9000; - } -} - - -# UI, blog, favicon, default server -server { - server_name dev.nutra.tk; - - # HTTP/3 (QUIC) - UDP - listen 443 quic reuseport default_server; - listen [::]:443 quic reuseport default_server; - - # HTTP/2 & 1.1 (Fallback) - TCP - listen 443 ssl default_server; - listen [::]:443 ssl default_server; - - # Enable protocols - http2 on; - http3 on; - - # Advertise HTTP/3 availability - add_header Alt-Svc 'h3=":443"; ma=86400' always; - - client_max_body_size 50m; - - # HSTS - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; - ssl_trusted_certificate /etc/ssl/private/ca-certs.pem; - # OCSP stapling (NOTE: Responders disabled by letsencrypt as of Q3 2025) - #ssl_stapling on; - #ssl_stapling_verify on; - - # Services Map (Homepage) - location / { - alias /var/www/homepage.html; - default_type text/html; - } - -# # Blog / Sphinx -# location /blog { -# alias /var/www/blog; -# index index.html; -# } - - # default favicon - location = /favicon.ico { - alias /var/www/favicon.gif; - } - - # Other - location ~ /.well-known { - allow all; - } - - # CV paths - location ~ ^/cv/(~?swe|swe~/resume\.pdf)$ { - alias /var/www/cv/swe/resume.pdf; - default_type application/pdf; - } - location ~ ^/resume(\.pdf|/swe\.pdf)$ { - alias /var/www/cv/swe/resume.pdf; - default_type application/pdf; - } - - # public folder - location /public { - root /var/www; - autoindex on; - #index index.html index.htm; - #try_files $uri $uri/ /index.html =404; - } - - # HTTPS / SSL - ssl_certificate /etc/letsencrypt/live/dev.nutra.tk/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/dev.nutra.tk/privkey.pem; # managed by Certbot - include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot -} - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Redirect www.dev.nutra.tk -> dev.nutra.tk -server { - listen 443 ssl; - listen 443 quic; - listen [::]:443 quic; - http2 on; - http3 on; - server_name www.dev.nutra.tk; - - ssl_certificate /etc/letsencrypt/live/dev.nutra.tk/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/dev.nutra.tk/privkey.pem; - include /etc/letsencrypt/options-ssl-nginx.conf; - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - - return 301 https://dev.nutra.tk$request_uri; -} - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Listen on 443 with matrix / synapse -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -server { - listen 443 ssl; - listen 443 quic; - http2 on; - http3 on; - add_header Alt-Svc 'h3=":443"; ma=86400' always; - server_name matrix.nutra.tk chat.nutra.tk; - - location / { - # Service: Matrix Chat | https://chat.nutra.tk - proxy_pass http://127.0.0.1:8008; - proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; - proxy_set_header X-Forwarded-For $remote_addr; - } - - location /favicon.ico { - alias /var/www/favicon.gif; - } -} - -# Open matrix chat on 8448 -server { - listen 8448 ssl default_server; - listen [::]:8448 ssl default_server; - server_name dev.nutra.tk; - - location / { - proxy_pass http://127.0.0.1:8008; - proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; - proxy_set_header X-Forwarded-For $remote_addr; - } - - # HTTPS / SSL - ssl_certificate /etc/letsencrypt/live/dev.nutra.tk/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/dev.nutra.tk/privkey.pem; # managed by Certbot - include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot -} diff --git a/etc/nginx/conf.d/default.prod.conf b/etc/nginx/conf.d/default.prod.conf index b866859..cf6bb9b 100644 --- a/etc/nginx/conf.d/default.prod.conf +++ b/etc/nginx/conf.d/default.prod.conf @@ -1,7 +1,15 @@ +# Redirect all HTTP to HTTPS with no-WWW +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name ~^(?:www\.)?(.*)$; + return 301 https://$1$request_uri; +} + # API server { - # Service: API | https://api.dev.nutra.tk - server_name api-dev.nutra.tk api.dev.nutra.tk; + # Service: API | https://api.nutra.tk + server_name api.nutra.tk; #listen 80; listen 443 ssl; listen 443 quic; @@ -69,7 +77,7 @@ server { # UI, blog, favicon, default server server { - server_name dev.nutra.tk; + server_name nutra.tk; # HTTP/3 (QUIC) - UDP listen 443 quic reuseport default_server; @@ -117,14 +125,9 @@ server { allow all; } - # CV paths - location ~ ^/cv/(~?swe|swe~/resume\.pdf)$ { - alias /var/www/cv/swe/resume.pdf; - default_type application/pdf; - } - location ~ ^/resume(\.pdf|/swe\.pdf)$ { - alias /var/www/cv/swe/resume.pdf; - default_type application/pdf; + # CV paths - Redirect to Dev (only hosted there) + location ~ ^/(cv/(~?swe|swe~/resume\.pdf)|resume(\.pdf|/swe\.pdf))$ { + return 301 https://dev.$server_name/resume.pdf; } # public folder @@ -136,28 +139,28 @@ server { } # HTTPS / SSL - ssl_certificate /etc/letsencrypt/live/dev.nutra.tk/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/dev.nutra.tk/privkey.pem; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/nutra.tk/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/nutra.tk/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Redirect www.dev.nutra.tk -> dev.nutra.tk +# Redirect www.nutra.tk -> nutra.tk server { listen 443 ssl; listen 443 quic; listen [::]:443 quic; http2 on; http3 on; - server_name www.dev.nutra.tk; + server_name www.nutra.tk; - ssl_certificate /etc/letsencrypt/live/dev.nutra.tk/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/dev.nutra.tk/privkey.pem; + ssl_certificate /etc/letsencrypt/live/nutra.tk/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/nutra.tk/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - return 301 https://dev.nutra.tk$request_uri; + return 301 https://nutra.tk$request_uri; } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -187,7 +190,7 @@ server { server { listen 8448 ssl default_server; listen [::]:8448 ssl default_server; - server_name dev.nutra.tk; + server_name nutra.tk; location / { proxy_pass http://127.0.0.1:8008; @@ -196,8 +199,8 @@ server { } # HTTPS / SSL - ssl_certificate /etc/letsencrypt/live/dev.nutra.tk/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/dev.nutra.tk/privkey.pem; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/nutra.tk/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/nutra.tk/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 3c78b7e..1529978 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -77,14 +77,34 @@ if sudo ls "$DEST_CONF_DIR"/*.conf >/dev/null 2>&1; then fi [ -f /etc/gitweb.conf ] && sudo cp /etc/gitweb.conf "$BACKUP_DIR/gitweb.conf" +# ENV is passed as first argument if not diff/test, default to dev +ENV="${1:-dev}" +echo "Deploying for environment: $ENV" + echo "Installing new configurations..." for FILE in "$NGINX_CONF_SRC"/*.conf; do BASENAME=$(basename "$FILE") + + # Skip encrypted secrets if [ "$BASENAME" = "secrets.conf" ] && ! is_text_file "$FILE"; then echo "Skipping encrypted secrets.conf..." continue fi - sudo cp "$FILE" "$DEST_CONF_DIR/" + + # Handle default configuration switching + if [[ "$BASENAME" == "default.dev.conf" || "$BASENAME" == "default.prod.conf" || "$BASENAME" == "default.conf" ]]; then + if [ "$BASENAME" == "default.${ENV}.conf" ]; then + echo "Installing $BASENAME as default.conf..." + sudo cp "$FILE" "$DEST_CONF_DIR/default.conf" + else + # Skip other environment configs and the raw default.conf if it exists + echo "Skipping mismatch/raw config: $BASENAME" + continue + fi + else + # Install all other configs as-is + sudo cp "$FILE" "$DEST_CONF_DIR/" + fi done echo "Verifying configuration..." diff --git a/scripts/gen_services_map.py b/scripts/gen_services_map.py index ca62bb2..3b5f22d 100755 --- a/scripts/gen_services_map.py +++ b/scripts/gen_services_map.py @@ -68,7 +68,19 @@ def get_all_services(): services_git = parse_file(NGINX_CONF, version_pattern, is_version=True) - DEFAULT_CONF = REPO_ROOT / "etc/nginx/conf.d/default.conf" + # Locate default.conf + # On Server: Read the live deployed config + live_default = Path("/etc/nginx/conf.d/default.conf") + # On Local: Read default.dev.conf + local_dev = REPO_ROOT / "etc/nginx/conf.d/default.dev.conf" + + if live_default.exists(): + DEFAULT_CONF = live_default + print(f"Using live config: {DEFAULT_CONF}") + else: + DEFAULT_CONF = local_dev + print(f"Using local config: {DEFAULT_CONF}") + services_other = parse_file(DEFAULT_CONF, service_pattern, is_version=False) return services_git, services_other