【基本环境】nginx home

This commit is contained in:
yuejiajun 2025-08-20 16:00:41 +08:00
parent bc0fdd14fd
commit f9e471aa37
7 changed files with 719 additions and 19 deletions

View File

@ -7,6 +7,15 @@ server {
listen 18080; listen 18080;
server_name _; server_name _;
root html;
error_page 404 /404.html;
error_page 500 /50x.html?error=500;
error_page 502 /50x.html?error=502;
error_page 503 /50x.html?error=503;
error_page 504 /50x.html?error=504;
gzip on; gzip on;
gzip_min_length 1k; gzip_min_length 1k;
gzip_comp_level 9; gzip_comp_level 9;
@ -14,19 +23,26 @@ server {
gzip_vary on; gzip_vary on;
gzip_disable "MSIE [1-6]\."; gzip_disable "MSIE [1-6]\.";
proxy_set_header Host $host; # 传递用户请求的原始Host域名或IP+端口)
# proxy_set_header Host $host;
proxy_set_header Host $http_host;
# 传递用户真实IP
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
# 传递真实IP包含整个代理链路的IP信息
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 传递用户请求的原始协议 (http 或 https)
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
# 用户原始的Cookie等完整请求头
proxy_set_header Cookie $http_cookie;
add_header X-Content-Type-Options "nosniff"; add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "SAMEORIGIN"; add_header X-Frame-Options "SAMEORIGIN";
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Connection ""; proxy_set_header Connection "";
proxy_read_timeout 60s; proxy_read_timeout 10s;
proxy_connect_timeout 5s; proxy_connect_timeout 5s;
proxy_send_timeout 30s; proxy_send_timeout 10s;
proxy_buffering off; proxy_buffering off;
@ -34,28 +50,40 @@ server {
rewrite ^ /home permanent; rewrite ^ /home permanent;
} }
location = /404.html {
root html;
internal;
}
location = /50x.html {
root /usr/share/nginx/html;
internal;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Real-IP $remote_addr;
}
location / { location / {
proxy_pass http://portal/; proxy_pass http://portal/;
proxy_intercept_errors on;
} }
location /assets/ { location /assets/ {
proxy_pass http://portal/assets/; proxy_pass http://portal/assets/;
expires 30d; expires 30d;
access_log off; access_log off;
proxy_intercept_errors on;
} }
location /api/ { location /api/ {
proxy_pass http://portal/api/; proxy_pass http://portal/api/;
client_max_body_size 100M; client_max_body_size 100M;
proxy_intercept_errors on;
} }
location /dev-api/ { location /dev-api/ {
proxy_pass http://portal/dev-api/; proxy_pass http://portal/dev-api/;
client_max_body_size 100M; client_max_body_size 100M;
} proxy_intercept_errors on;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
} }
} }

View File

@ -0,0 +1,196 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面未找到 - 404错误</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #fff;
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
}
.container {
max-width: 800px;
width: 100%;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 40px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.error-code {
font-size: 120px;
font-weight: 800;
margin-bottom: 20px;
text-shadow: 3px 3px 0 rgba(0, 0, 0, 0.2);
color: #fff;
line-height: 1;
animation: pulse 2s infinite;
}
.error-title {
font-size: 32px;
margin-bottom: 20px;
color: #fff;
}
.error-message {
font-size: 18px;
margin-bottom: 30px;
line-height: 1.6;
color: rgba(255, 255, 255, 0.9);
}
.search-box {
display: flex;
max-width: 500px;
margin: 0 auto 30px;
}
.search-input {
flex: 1;
padding: 15px 20px;
border: none;
border-radius: 50px 0 0 50px;
font-size: 16px;
outline: none;
}
.search-button {
padding: 15px 25px;
background: #4CAF50;
color: white;
border: none;
border-radius: 0 50px 50px 0;
cursor: pointer;
font-size: 16px;
transition: background 0.3s;
}
.search-button:hover {
background: #3e8e41;
}
.action-buttons {
display: flex;
justify-content: center;
gap: 15px;
flex-wrap: wrap;
}
.btn {
padding: 12px 25px;
background: rgba(255, 255, 255, 0.2);
color: white;
text-decoration: none;
border-radius: 50px;
transition: all 0.3s;
border: 1px solid rgba(255, 255, 255, 0.3);
}
.btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.nginx-brand {
margin-top: 40px;
opacity: 0.7;
font-size: 14px;
}
/* 动画效果 */
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
/* 响应式设计 */
@media (max-width: 600px) {
.error-code {
font-size: 80px;
}
.error-title {
font-size: 24px;
}
.error-message {
font-size: 16px;
}
.container {
padding: 30px 20px;
}
.search-box {
flex-direction: column;
}
.search-input {
border-radius: 50px;
margin-bottom: 10px;
}
.search-button {
border-radius: 50px;
}
}
</style>
</head>
<body>
<div class="container">
<h1 class="error-code">404</h1>
<h2 class="error-title">哎呀!页面找不到啦</h2>
<p class="error-message">您访问的页面可能已被移除、更名或暂时不可用。请检查URL是否正确或使用搜索功能查找您需要的内容。</p>
<!-- <div class="search-box">
<input type="text" class="search-input" placeholder="搜索网站内容...">
<button class="search-button">搜索</button>
</div> -->
<div class="action-buttons">
<a href="/" class="btn">返回首页</a>
<a href="javascript:history.back()" class="btn">返回上一页</a>
<a href="/sitemap" class="btn">网站地图</a>
<a href="/contact" class="btn">联系支持</a>
</div>
<div class="nginx-brand">Nginx</div>
</div>
<script>
document.querySelector('.search-button').addEventListener('click', function() {
const query = document.querySelector('.search-input').value;
if(query.trim() !== '') {
alert('执行搜索: ' + query);
}
});
document.querySelector('.search-input').addEventListener('keypress', function(e) {
if(e.key === 'Enter') {
document.querySelector('.search-button').click();
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,354 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>服务器错误 - <span id="error-code">500</span></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #ff6b6b 0%, #cc2b5e 100%);
color: #fff;
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
}
.container {
max-width: 900px;
width: 100%;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 40px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.error-code {
font-size: 120px;
font-weight: 800;
margin-bottom: 10px;
text-shadow: 3px 3px 0 rgba(0, 0, 0, 0.2);
color: #fff;
line-height: 1;
animation: pulse 2s infinite;
}
.error-title {
font-size: 32px;
margin-bottom: 15px;
color: #fff;
}
.error-description {
font-size: 18px;
margin-bottom: 25px;
padding: 15px;
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
line-height: 1.6;
}
.error-message {
font-size: 16px;
margin-bottom: 30px;
line-height: 1.6;
color: rgba(255, 255, 255, 0.9);
}
.server-status {
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
padding: 20px;
margin: 20px 0;
text-align: left;
}
.status-title {
font-size: 18px;
margin-bottom: 15px;
display: flex;
align-items: center;
}
.status-title i {
margin-right: 10px;
}
.status-item {
display: flex;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.status-label {
font-weight: 500;
}
.status-value {
font-weight: 600;
}
.status-value.down {
color: #ff6b6b;
}
.status-value.up {
color: #4CAF50;
}
.action-buttons {
display: flex;
justify-content: center;
gap: 15px;
flex-wrap: wrap;
margin: 30px 0;
}
.btn {
padding: 12px 25px;
background: rgba(255, 255, 255, 0.2);
color: white;
text-decoration: none;
border-radius: 50px;
transition: all 0.3s;
border: 1px solid rgba(255, 255, 255, 0.3);
display: flex;
align-items: center;
}
.btn i {
margin-right: 8px;
}
.btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.countdown {
font-size: 16px;
margin-top: 20px;
padding: 10px;
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
}
.countdown-number {
font-weight: 700;
color: #FFD700;
}
.error-details {
margin-top: 20px;
padding: 15px;
background: rgba(0, 0, 0, 0.1);
border-radius: 8px;
text-align: left;
font-size: 14px;
}
.nginx-brand {
margin-top: 40px;
opacity: 0.7;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
}
/* 动画效果 */
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.fa-spinner {
animation: spin 1.5s linear infinite;
}
/* 响应式设计 */
@media (max-width: 600px) {
.error-code {
font-size: 80px;
}
.error-title {
font-size: 24px;
}
.error-description, .error-message {
font-size: 16px;
}
.container {
padding: 30px 20px;
}
.action-buttons {
flex-direction: column;
}
.btn {
justify-content: center;
}
}
</style>
</head>
<body>
<div class="container">
<h1 class="error-code" id="dynamic-error-code">500</h1>
<h2 class="error-title" id="error-title">服务器内部错误</h2>
<div class="error-description" id="error-description">
服务器遇到了意外的条件,无法完成您的请求。
</div>
<p class="error-message">
我们的技术团队已收到通知,正在努力解决问题。<br>
请稍后再试或联系技术支持获取帮助。
</p>
<div class="server-status">
<div class="status-title">
<i class="fas fa-server"></i>
<span>服务器状态监控</span>
</div>
<div class="status-item">
<span class="status-label">Web服务器</span>
<span class="status-value up">运行正常 <i class="fas fa-check-circle"></i></span>
</div>
<div class="status-item">
<span class="status-label">应用程序服务</span>
<span class="status-value down" id="app-status">遇到问题 <i class="fas fa-exclamation-circle"></i></span>
</div>
<div class="status-item">
<span class="status-label">数据库连接</span>
<span class="status-value up">连接正常 <i class="fas fa-check-circle"></i></span>
</div>
<div class="status-item">
<span class="status-label">错误发生时间</span>
<span class="status-value" id="current-time"></span>
</div>
</div>
<div class="action-buttons">
<a href="/" class="btn">
<i class="fas fa-home"></i>
<span>返回首页</span>
</a>
<a href="javascript:location.reload()" class="btn">
<i class="fas fa-redo"></i>
<span>重新加载</span>
</a>
<a href="javascript:history.back()" class="btn">
<i class="fas fa-arrow-left"></i>
<span>返回上一页</span>
</a>
<a href="/contact" class="btn">
<i class="fas fa-envelope"></i>
<span>联系支持</span>
</a>
</div>
<div class="countdown">
<p>页面将在 <span class="countdown-number" id="countdown">15</span> 秒后自动重新加载 <i class="fas fa-spinner"></i></p>
</div>
<div class="error-details">
<p><strong>技术信息:</strong></p>
<p>错误代码: <span id="technical-error-code">500</span></p>
<p>请求ID: <span id="request-id">REQ-${Math.random().toString(36).substr(2, 9).toUpperCase()}</span></p>
<p>服务器: <span id="server-name">${window.location.hostname}</span></p>
</div>
<div class="nginx-brand">
<span>Powered by Nginx</span>
</div>
</div>
<script>
function getErrorCodeFromURL() {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get('error') || '500';
}
const errorDescriptions = {
'500': {
title: '服务器内部错误',
description: '服务器遇到了意外的条件,无法完成您的请求。这通常是服务器端代码的问题。'
},
'502': {
title: '错误的网关',
description: '服务器作为网关或代理,从上游服务器收到无效响应。这可能是后端服务无响应或配置错误。'
},
'503': {
title: '服务不可用',
description: '服务器暂时无法处理请求,通常是由于过载或维护。请稍后再试。'
},
'504': {
title: '网关超时',
description: '服务器作为网关或代理,没有及时从上游服务器收到响应。这可能是网络问题或后端服务响应缓慢。'
}
};
function setupErrorPage() {
const errorCode = getErrorCodeFromURL();
const errorInfo = errorDescriptions[errorCode] || errorDescriptions['500'];
document.getElementById('dynamic-error-code').textContent = errorCode;
document.getElementById('error-title').textContent = errorInfo.title;
document.getElementById('error-description').textContent = errorInfo.description;
document.title = `服务器错误 - ${errorCode}`;
document.getElementById('technical-error-code').textContent = errorCode;
}
let seconds = 15;
const countdownElement = document.getElementById('countdown');
const countdown = setInterval(function() {
seconds--;
countdownElement.textContent = seconds;
if (seconds <= 0) {
clearInterval(countdown);
window.location.reload();
}
}, 1000);
function updateCurrentTime() {
const now = new Date();
const timeElement = document.getElementById('current-time');
timeElement.textContent = now.toLocaleString();
}
document.addEventListener('DOMContentLoaded', function() {
setupErrorPage();
updateCurrentTime();
setInterval(updateCurrentTime, 1000);
document.getElementById('server-name').textContent = window.location.hostname;
});
</script>
</body>
</html>

View File

@ -8,27 +8,40 @@ call :log_info SCRIPT_DIR=%SCRIPT_DIR%
cd /d "%SCRIPT_DIR%" cd /d "%SCRIPT_DIR%"
call :Start "Redis" "%SCRIPT_DIR%redis" "redis-server.exe" "redis.conf" call :main
call :Start "MinIO" "%SCRIPT_DIR%io" "minio-server.bat"
call :Start "RocketMQ" "%SCRIPT_DIR%rocketmq\sbin" "rocketmq.bat"
pause && exit /b 0 pause && exit /b 0
:log_info :log_info
call :GetFormattedTime call :GetFormattedTime
echo [%FormattedTime%] - [INFO] - %* if defined LOG_TITLE (
echo.
echo [%FormattedTime%] - [INFO] - ==================== %LOG_TITLE% ====================
set "LOG_TITLE="
) else (
echo [%FormattedTime%] - [INFO] - %*
)
exit /b 0 exit /b 0
:log_warn :log_warn
call :GetFormattedTime call :GetFormattedTime
echo [%FormattedTime%] - [WARN] - %* if defined LOG_TITLE (
echo.
echo [%FormattedTime%] - [WARN] - ==================== %LOG_TITLE% ====================
set "LOG_TITLE="
) else (
echo [%FormattedTime%] - [WARN] - %*
)
exit /b 0 exit /b 0
:log_error :log_error
call :GetFormattedTime call :GetFormattedTime
echo [%FormattedTime%] - [ERROR] - %* if defined LOG_TITLE (
echo.
echo [%FormattedTime%] - [ERROR] - ==================== %LOG_TITLE% ====================
set "LOG_TITLE="
) else (
echo [%FormattedTime%] - [ERROR] - %*
)
exit /b 0 exit /b 0
:rar :rar
@ -56,6 +69,17 @@ call :log_info Password: Password#!CURRENT_DATE!
exit /b 0 exit /b 0
:GetSinglePidByPort
setlocal
call :RandomStr single_pid_tmp
call :log_info netstat -ano ^| grep -E ":%1 " ^| grep "LISTENING" ^| awk "{print $NF}" ^| head -n 1
netstat -ano | grep -E ":%1 " | grep "LISTENING" | awk "{print $NF}" | head -n 1 > %single_pid_tmp%.txt
set /p pid=<%single_pid_tmp%.txt
call :log_info pid: %pid%
del %single_pid_tmp%.txt
endlocal & set pid=%pid%
exit /b 0
:RandomStr :RandomStr
setlocal setlocal
set "len=%~1" set "len=%~1"
@ -114,3 +138,101 @@ exit /b 0
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "datetime=%%a" for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "datetime=%%a"
set "FormattedDate=%datetime:~0,4%%datetime:~4,2%%datetime:~6,2%" set "FormattedDate=%datetime:~0,4%%datetime:~4,2%%datetime:~6,2%"
exit /b 0 exit /b 0
:GetUsageNumberOfPidsByPort
setlocal
set "PORT=%~1"
set /a "UNIQUE_COUNT=0"
if "!PORT!"=="" (
call :log_error ERROR: Port number required
endlocal & exit /b 0
)
set "TEMP_FILE=%TEMP%\port_%PORT%_%RANDOM%_%TIME::=_%.tmp"
set "PID_LIST_FILE=%TEMP%\pids_%PORT%_%RANDOM%.tmp"
call :log_info Checking for processes using port !PORT!...
netstat -ano | grep -E ":!PORT! " > "!TEMP_FILE!"
if !errorlevel! neq 0 (
call :log_info No process found using port !PORT!
del "!TEMP_FILE!" 2>nul
endlocal & exit /b 0
)
echo. > "!PID_LIST_FILE!"
echo.
set "LOG_TITLE=Processes using port !PORT!"
call :log_info ignore
for /f "tokens=5" %%a in (!TEMP_FILE!) do (
set "PID=%%a"
:: grep -E "^^!PID! $" "!PID_LIST_FILE!" >nul
findstr /x "!PID!" "!PID_LIST_FILE!" >nul
if !errorlevel! neq 0 (
echo !PID! >> "!PID_LIST_FILE!"
set /a "UNIQUE_COUNT+=1"
call :log_info [!UNIQUE_COUNT!] PID: !PID!
set "PROCESS_NAME="
set "SESSION_NAME="
set "SESSION_NUM="
set "MEM_USAGE="
for /f "tokens=1,2,3,4,5*" %%b in ('tasklist /fi "PID eq !PID!" /fo table ^| findstr /i "!PID!"') do (
if not "%%b"=="=" if not "%%b"=="Image" (
call :log_info "PROCESS_NAME=%%b"
call :log_info "PID_VALUE=%%c"
call :log_info "SESSION_NAME=%%d"
call :log_info "SESSION_NUM=%%e"
call :log_info "MEM_USAGE=%%f"
)
)
if not "!PROCESS_NAME!"=="" (
call :log_info Process: !PROCESS_NAME!
call :log_info Memory: !MEM_USAGE!
)
echo.
)
)
if !UNIQUE_COUNT! gtr 0 (
set "LOG_TITLE=PIDs using port !PORT!"
call :log_info ignore
:: type "!PID_LIST_FILE!"
call :log_info Total: !UNIQUE_COUNT! process
)
del "!TEMP_FILE!" 2>nul
del "!PID_LIST_FILE!" 2>nul
endlocal & exit /b %UNIQUE_COUNT%
:main
setlocal
call :GetUsageNumberOfPidsByPort 18080
if !ERRORLEVEL! neq 0 (
call :log_info Found !ERRORLEVEL! processes.
call :GetSinglePidByPort 18080
set "LOG_TITLE=Killing Process !pid!"
call :log_info ignore
:: taskkill -f -pid !pid! >nul
taskkill -f -im home-web.exe
)
timeout /t 1 /nobreak >nul
call :Start "Nginx" "%SCRIPT_DIR%nginx" "home-web.exe" "-c" "conf/web.conf"
timeout /t 3 /nobreak >nul
call :Start "Redis" "%SCRIPT_DIR%redis" "redis-server.exe" "redis.conf"
timeout /t 3 /nobreak >nul
call :Start "MinIO" "%SCRIPT_DIR%io" "minio-server.bat"
timeout /t 3 /nobreak >nul
call :Start "RocketMQ" "%SCRIPT_DIR%rocketmq\sbin" "rocketmq.bat"
endlocal
cmd /k

View File

@ -1,7 +1,7 @@
;iss ;iss
#define MyAppName "基础环境" #define MyAppName "基础环境"
#define MyAppVersion "1.0.6" #define MyAppVersion "1.0.7"
#define MyAppPublisher "X" #define MyAppPublisher "X"
#define MyAppURL "~" #define MyAppURL "~"
#define MyAppExeName "command" #define MyAppExeName "command"