diff --git a/DEPLOY.md b/DEPLOY.md index 62420e59..2a984a68 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -157,14 +157,20 @@ ln -sf /etc/nginx/sites-available/biztaghavi /etc/nginx/sites-enabled/biztaghavi nginx -t && systemctl reload nginx ``` -Then issue SSL with Certbot (HTTP must be working first): +**SSL (ArvanCloud CDN — recommended):** The repo nginx config listens on **80 and 443** with the shared NODE Cloud self-signed cert (same as khanehbaan.ir). ArvanCloud terminates public HTTPS. + +```bash +bash scripts/nginx-ssl-setup.sh +``` + +In **ArvanCloud dashboard**: SSL mode = **Full**, origin = `193.105.234.35`, purge cache. + +**SSL (direct DNS only):** If the domain does *not* use ArvanCloud, use certbot instead of the self-signed block: ```bash certbot --nginx -d biztaghavi.com -d www.biztaghavi.com ``` -In **ArvanCloud dashboard**: SSL mode = "Full (strict)", origin = `193.105.234.35`, purge cache. - > Port **3009** must match the `ports` binding in `docker-compose.yml` — verify it's `"127.0.0.1:3009:3000"`. --- diff --git a/nginx/biztaghavi.conf b/nginx/biztaghavi.conf index 53e0abc2..31a6fc71 100644 --- a/nginx/biztaghavi.conf +++ b/nginx/biztaghavi.conf @@ -1,3 +1,7 @@ +# biztaghavi.com — NODE Cloud origin (ArvanCloud CDN in front) +# Public SSL: ArvanCloud dashboard → SSL mode "Full", origin 193.105.234.35 +# Origin SSL: shared self-signed cert (required so nginx does not serve Gitea on :443) + gzip on; gzip_vary on; gzip_proxied any; @@ -8,11 +12,12 @@ gzip_types text/plain text/css text/xml application/json application/javascript server { listen 80; listen [::]:80; + listen 443 ssl; + listen [::]:443 ssl; server_name biztaghavi.com www.biztaghavi.com; - # Certbot will insert HTTPS redirect and SSL block here automatically. - # After first HTTP deploy, run: - # certbot --nginx -d biztaghavi.com -d www.biztaghavi.com + ssl_certificate /etc/ssl/certs/nodecloud-selfsigned.crt; + ssl_certificate_key /etc/ssl/private/nodecloud-selfsigned.key; client_max_body_size 50M; @@ -32,7 +37,7 @@ server { access_log off; } - # Next.js HMR / WebSocket (needed for dev; harmless in prod) + # Next.js HMR / WebSocket (dev only; harmless in prod) location /_next/webpack-hmr { proxy_pass http://127.0.0.1:3009; proxy_http_version 1.1; @@ -50,7 +55,6 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - # WebSocket support proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; diff --git a/scripts/nginx-ssl-setup.sh b/scripts/nginx-ssl-setup.sh new file mode 100755 index 00000000..f457fc00 --- /dev/null +++ b/scripts/nginx-ssl-setup.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Install nginx site + origin SSL for ArvanCloud CDN. Run on server as root. +set -euo pipefail + +APP_DIR="/srv/nodecloud/apps/biztaghavisite" +CONF_SRC="$APP_DIR/nginx/biztaghavi.conf" +CONF_DST="/etc/nginx/sites-available/biztaghavi" + +if [[ ! -f "$CONF_SRC" ]]; then + echo "ERROR: $CONF_SRC not found. git pull first." + exit 1 +fi + +if [[ ! -f /etc/ssl/certs/nodecloud-selfsigned.crt ]]; then + echo "ERROR: /etc/ssl/certs/nodecloud-selfsigned.crt missing (NODE Cloud self-signed cert)." + exit 1 +fi + +echo "==> Install nginx config" +cp "$CONF_SRC" "$CONF_DST" +ln -sf "$CONF_DST" /etc/nginx/sites-enabled/biztaghavi + +echo "==> Test and reload nginx" +nginx -t +systemctl reload nginx + +echo "==> Origin checks" +curl -sf -o /dev/null -w "HTTP :80 → %{http_code}\n" -H "Host: biztaghavi.com" http://127.0.0.1/ +curl -skf -o /dev/null -w "HTTPS :443 → %{http_code}\n" -H "Host: biztaghavi.com" https://127.0.0.1/ + +echo "" +echo "Done. In ArvanCloud: SSL = Full, origin = 193.105.234.35, then purge cache." +echo "Test: curl -sI https://biztaghavi.com/admin/login" diff --git a/scripts/server-deploy.sh b/scripts/server-deploy.sh index 8e33fd92..13177e4b 100755 --- a/scripts/server-deploy.sh +++ b/scripts/server-deploy.sh @@ -77,6 +77,11 @@ else fi curl -sI -H "Host: biztaghavi.com" "http://127.0.0.1/" | head -5 +if curl -sf -H "Host: biztaghavi.com" "http://127.0.0.1:${PORT}/admin/login" -o /dev/null; then + echo "OK: /admin/login responds" +else + echo "WARN: /admin/login not OK — rebuild after proxy.ts excludes /admin" +fi docker compose -f "$COMPOSE_FILE" ps echo "" echo "Done. Test https://biztaghavi.com (purge ArvanCloud cache if needed)." diff --git a/src/proxy.ts b/src/proxy.ts index 6029a328..09c9cc73 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -4,5 +4,6 @@ import { routing } from "./lib/i18n/routing"; export default createMiddleware(routing); export const config = { - matcher: ["/((?!_next|_vercel|studio|api|.*\\..*).*)"], + // Exclude admin panel and APIs — they live outside [locale] routes + matcher: ["/((?!_next|_vercel|studio|api|admin|.*\\..*).*)"], };