# ============================================================ # MyBlog Nginx 站点配置 # ------------------------------------------------------------ # 部署位置:/etc/nginx/sites-available/myblog # 启用命令:sudo ln -s /etc/nginx/sites-available/myblog /etc/nginx/sites-enabled/ # 校验命令:sudo nginx -t # 重载命令:sudo systemctl reload nginx # # 目录约定(与全局架构一致): # /var/www/blog/frontend 前端静态文件(index.html / *.js / style.css) # /var/www/blog/uploads 上传文件(avatar / article / project) # /var/www/blog/backend 后端代码 # /var/www/blog/.env 环境变量(应用启动时自动加载) # ============================================================ # ============ HTTP 80:普通访问 + 证书校验 ============ server { listen 80; listen [::]:80; # 改成你的域名(或服务器公网 IP);certbot 会自动填入证书相关配置 server_name your-domain.com; # 允许上传大小上限:头像最大 4MB、文章视频最大 100MB,留出余量(默认 1MB 会拦截上传) client_max_body_size 110m; # ---------- 安全响应头(防点击劫持 / MIME 嗅探 / 泄露来源页) ---------- add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; # 说明:前端 HTML 内已有 CSP meta;如需更强防护(frame-ancestors 等), # 可在此追加:add_header Content-Security-Policy "default-src 'self'; ..." always; # Let's Encrypt 证书签发校验目录(certbot --webroot 模式使用) # 需要先创建:sudo mkdir -p /var/www/blog/.well-known/acme-challenge location /.well-known/acme-challenge/ { root /var/www/blog; } # ---------- /myip 返回客户端公网 IP(SSH 白名单自动更新用) ---------- # 家庭端脚本先请求此地址获取当前公网 IP,变化后再调用 /api/ipwatch/report # 注意:certbot 生成 443 的 server 块时,需要把这一段也复制进去 location = /myip { default_type text/plain; return 200 $remote_addr; } # ---------- /api/* 反向代理到 FastAPI ---------- # FastAPI 只监听 127.0.0.1:8080,公网无法直连,必须走 Nginx 代理 location /api/ { proxy_pass http://127.0.0.1:8080; 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; # WASM 预编译等长任务可能超过 60s,放宽到 180s proxy_read_timeout 180s; } # 说明:服务器 /etc/nginx/mime.types 需追加一行 application/wasm wasm;(已执行) # ---------- /uploads/* 静态文件 ---------- # 头像、文章图片、项目压缩包由 Nginx 直接提供,不经过 Python location /uploads/ { alias /var/www/blog/uploads/; expires 30d; add_header Cache-Control "public"; add_header X-Content-Type-Options "nosniff" always; } # ---------- /demo/* 在线演示(L0 静态托管) ---------- # 上传的项目 zip 若为纯 HTML/CSS/JS,后端解压到 uploads/demos/{项目id}/, # 此处由 Nginx 直接提供(不经过 Python,禁止执行) location /demo/ { alias /var/www/blog/uploads/demos/; index index.html; try_files $uri $uri/ =404; add_header X-Content-Type-Options "nosniff" always; } # ---------- 前端静态文件(SPA) ---------- # root 必须指向 frontend 目录:页面里引用的是 /main.js /style.css 等绝对路径 location / { root /var/www/blog/frontend; index index.html; # SPA 刷新支持: # 先找真实文件($uri),再找目录($uri/), # 都找不到就回退到 index.html,由前端 History API 路由接管 try_files $uri $uri/ /index.html; # 每次重新校验,避免部署后浏览器继续用旧版 JS 导致页面渲染异常 add_header Cache-Control "no-cache"; } } # ============ HTTPS 443:用 certbot 一键开启 ============ # 推荐方式(自动改写本配置文件并管理续期): # sudo apt install certbot python3-certbot-nginx # sudo certbot --nginx -d your-domain.com # 执行成功后,本文件会被自动加入 443 监听与证书路径,无需手写。 # 若要手写,参考下面的骨架(把上面 /api/、/uploads/、/ 三段复制进来即可): # server { # listen 443 ssl; # listen [::]:443 ssl; # server_name your-domain.com; # ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; # ssl_protocols TLSv1.2 TLSv1.3; # # ... 同上三个 location 块 ... # }