diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index dde70459b..ef91f572e 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -23,7 +23,7 @@ jobs: host: ${{ secrets.SSH_HOST }} username: root key: ${{ secrets.SSH_KEY }} - script: bash /opt/openisle/deploy-staging.sh + script: bash /opt/openisle/OpenIsle/deploy_staging.sh deploy-docs: needs: build-and-deploy diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 28c013027..5a799da8e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -19,4 +19,4 @@ jobs: host: ${{ secrets.SSH_HOST }} username: root key: ${{ secrets.SSH_KEY }} - script: bash /opt/openisle/deploy.sh + script: bash /opt/openisle/OpenIsle/deploy.sh diff --git a/nginx/openisle b/nginx/openisle new file mode 100644 index 000000000..2ee2fe9fb --- /dev/null +++ b/nginx/openisle @@ -0,0 +1,174 @@ +server { + listen 443 ssl; + server_name open-isle.com www.open-isle.com; + + ssl_certificate /etc/letsencrypt/live/open-isle.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/open-isle.com/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + + location / { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + add_header Cache-Control "no-store" always; + add_header X-Upstream $upstream_addr always; + } + + location ^~ /api/ws { + proxy_pass http://127.0.0.1:8080; + proxy_http_version 1.1; + + # 升级所需 + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + # 统一透传这些头(你在 /api/ 有,/api/ws 也要有) + 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_set_header X-Forwarded-Host $host; + + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + proxy_cache off; + } + + # 2) SockJS(包含 /info、/iframe.html、/.../websocket 等) + location ^~ /api/sockjs { + proxy_pass http://127.0.0.1:8080; + 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_set_header X-Forwarded-Host $host; + + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + proxy_cache off; + + # 如要同源 iframe 回退,下面两行二选一(或者交给 Spring Security 的 sameOrigin) + # proxy_hide_header X-Frame-Options; + # add_header X-Frame-Options "SAMEORIGIN" always; + } + + location /api/ { + proxy_pass http://127.0.0.1:8080/api/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0" always; + proxy_no_cache 1; + proxy_cache_bypass 1; + } + + # 通过 https://open-isle.com/rabbitmq/ 访问管理界面 + location ^~ /rabbitmq/ { + # 关键点:proxy_pass 以 "/" 结尾,保留后缀子路径映射 + proxy_pass http://127.0.0.1:15672/; + 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; + + proxy_read_timeout 300s; + proxy_send_timeout 300s; + + # 把上游返回的绝对重定向 /... 改写为 /rabbitmq/... + proxy_redirect ~^(/.*)$ /rabbitmq$1; + + # 为了做 HTML/CSS/JS 内绝对路径替换,需要关闭压缩 + proxy_set_header Accept-Encoding ""; + + # 将页面中以 "/" 开头的 src/href 替换为 "/rabbitmq/..." + sub_filter_types text/html text/css application/javascript; + sub_filter 'href="/' 'href="/rabbitmq/'; + sub_filter 'src="/' 'src="/rabbitmq/'; + sub_filter_once off; + + # 建议对管理台再加一道保护(可选) + # auth_basic "RabbitMQ Console"; + # auth_basic_user_file /etc/nginx/.htpasswd; + } + + # 通过 https://open-isle.com/docker/ 访问 Portainer(上游是自签名 HTTPS) + location ^~ /docker/ { + proxy_pass https://127.0.0.1:19000/; # 末尾 / 保留子路径 + proxy_http_version 1.1; + + # 上游是自签证书,关闭校验(仅内网/自签场景) + proxy_ssl_verify off; + + # 透传头 + 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_set_header X-Forwarded-Host $host; + + # WebSocket/事件流(Portainer 某些功能会用到) + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + proxy_cache off; + + # 把上游返回的绝对重定向 /... 改写为 /docker/... + proxy_redirect ~^(/.*)$ /docker$1; + + # 为了替换 HTML/CSS/JS 中的绝对路径,需要关闭压缩 + proxy_set_header Accept-Encoding ""; + + # 将页面中以 "/" 开头的 src/href 替换为 "/docker/..." + sub_filter_types text/html text/css application/javascript; + sub_filter 'href="/' 'href="/docker/'; + sub_filter 'src="/' 'src="/docker/'; + sub_filter_once off; + + # 可选:再加一道基本认证 + # auth_basic "Portainer"; + # auth_basic_user_file /etc/nginx/.htpasswd; + } + + + # ---------- WEBSOCKET GATEWAY TO :8082 ---------- + location ^~ /websocket/ { + proxy_pass http://127.0.0.1:8082/; + 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_set_header X-Forwarded-Host $host; + + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + proxy_cache off; + add_header Cache-Control "no-store" always; + } +} +server { + listen 80; + server_name open-isle.com www.open-isle.com; + return 301 https://$host$request_uri; +} diff --git a/nginx/openisle-staging b/nginx/openisle-staging new file mode 100644 index 000000000..951a9b4cf --- /dev/null +++ b/nginx/openisle-staging @@ -0,0 +1,133 @@ +# 放在 http { } 里一次定义 +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 443 ssl; + server_name staging.open-isle.com www.staging.open-isle.com; + + + ssl_certificate /etc/letsencrypt/live/staging.open-isle.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/staging.open-isle.com/privkey.pem; + # ssl_certificate /etc/letsencrypt/live/open-isle.com/fullchain.pem; + # ssl_certificate_key /etc/letsencrypt/live/open-isle.com/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + + # ---------- SSR ---------- + location / { + proxy_pass http://127.0.0.1:3001; + proxy_http_version 1.1; + + # 正确的升级头(仅在有 Upgrade 时) + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + # 透传真实主机/协议/源 IP + 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_set_header X-Forwarded-Host $host; + + # 合理超时,避免 SSR 首屏慢查询导致 502/504 + proxy_read_timeout 120s; + proxy_send_timeout 120s; + + add_header Cache-Control "no-store" always; + add_header X-Upstream $upstream_addr always; + } + + # 1) 原生 WebSocket + location ^~ /api/ws { + proxy_pass http://127.0.0.1:8081; # 不要尾随 /,保留原样 URI + proxy_http_version 1.1; + + # 升级所需 + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + # 统一透传这些头(你在 /api/ 有,/api/ws 也要有) + 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_set_header X-Forwarded-Host $host; + + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + proxy_cache off; + } + + # 2) SockJS(包含 /info、/iframe.html、/.../websocket 等) + location ^~ /api/sockjs { + proxy_pass http://127.0.0.1:8081; + 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_set_header X-Forwarded-Host $host; + + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + proxy_cache off; + + # 如要同源 iframe 回退,下面两行二选一(或者交给 Spring Security 的 sameOrigin) + # proxy_hide_header X-Frame-Options; + # add_header X-Frame-Options "SAMEORIGIN" always; + } + + # ---------- API ---------- + location /api/ { + proxy_pass http://127.0.0.1:8081/api/; + 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_set_header X-Forwarded-Host $host; + + proxy_read_timeout 120s; + proxy_send_timeout 120s; + + add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0" always; + proxy_no_cache 1; + proxy_cache_bypass 1; + } + + # ---------- WEBSOCKET GATEWAY TO :8083 ---------- + location ^~ /websocket/ { + proxy_pass http://127.0.0.1:8083/; + 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_set_header X-Forwarded-Host $host; + + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + proxy_cache off; + add_header Cache-Control "no-store" always; + } + +}