# Photography Portfolio Caddyfile # 前端展示网站和后端API反向代理配置 # 前端展示网站 photography.iriver.top { # 静态文件服务 root * /home/gitea/www/photography # 启用文件服务器 file_server # 启用 gzip 压缩 encode gzip # 设置默认首页 try_files {path} {path}/ /index.html # 设置静态资源缓存 @static { path *.css *.js *.png *.jpg *.jpeg *.gif *.svg *.woff *.woff2 *.ttf *.eot *.ico } header @static Cache-Control "public, max-age=31536000, immutable" # 设置 HTML 文件缓存 @html { path *.html } header @html Cache-Control "public, max-age=3600" # 安全头设置 header { # 防止点击劫持 X-Frame-Options "SAMEORIGIN" # 防止 MIME 类型嗅探 X-Content-Type-Options "nosniff" # XSS 保护 X-XSS-Protection "1; mode=block" # 推荐 HTTPS Strict-Transport-Security "max-age=31536000; includeSubDomains" # 隐藏服务器信息 -Server } # 日志配置 log { output file /var/log/caddy/photography.log { roll_size 10MB roll_keep 5 } format json } # 错误页面处理 handle_errors { @404 { expression {http.error.status_code} == 404 } rewrite @404 /404.html file_server } } # 后端API反向代理 api.photography.iriver.top { # 反向代理到后端服务 reverse_proxy localhost:8080 { # 健康检查 health_uri /health health_interval 30s health_timeout 5s health_status 200 # 故障转移 fail_duration 30s max_fails 3 unhealthy_status 5xx # 请求头设置 header_up Host {upstream_hostport} header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} header_up X-Forwarded-Host {host} # 响应头设置 header_down -Server header_down Access-Control-Allow-Origin "*" header_down Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" header_down Access-Control-Allow-Headers "Content-Type, Authorization" } # 启用 gzip 压缩 encode gzip # 请求日志 log { output file /var/log/caddy/api.photography.log { roll_size 10MB roll_keep 5 } format json } # 限流配置 rate_limit { zone dynamic { key {remote_host} events 100 window 1m } zone static { key {remote_host} events 500 window 1m } } # 安全头设置 header { # 防止点击劫持 X-Frame-Options "DENY" # 防止 MIME 类型嗅探 X-Content-Type-Options "nosniff" # XSS 保护 X-XSS-Protection "1; mode=block" # 推荐 HTTPS Strict-Transport-Security "max-age=31536000; includeSubDomains" # 隐藏服务器信息 -Server } # 错误处理 handle_errors { @5xx { expression {http.error.status_code} >= 500 } respond @5xx `{"error": "服务器内部错误", "code": 500, "message": "API服务暂时不可用,请稍后重试"}` 500 { header Content-Type "application/json" } @4xx { expression {http.error.status_code} >= 400 } respond @4xx `{"error": "请求错误", "code": {http.error.status_code}, "message": "请求无效"}` {http.error.status_code} { header Content-Type "application/json" } } } # 管理后台 admin.photography.iriver.top { # 静态文件服务 root * /home/gitea/www/photography-admin # 启用文件服务器 file_server # 启用 gzip 压缩 encode gzip # 设置默认首页 try_files {path} {path}/ /index.html # 设置静态资源缓存 @static { path *.css *.js *.png *.jpg *.jpeg *.gif *.svg *.woff *.woff2 *.ttf *.eot *.ico } header @static Cache-Control "public, max-age=31536000, immutable" # 设置 HTML 文件缓存 @html { path *.html } header @html Cache-Control "public, max-age=3600" # 安全头设置 header { # 防止点击劫持 X-Frame-Options "SAMEORIGIN" # 防止 MIME 类型嗅探 X-Content-Type-Options "nosniff" # XSS 保护 X-XSS-Protection "1; mode=block" # 推荐 HTTPS Strict-Transport-Security "max-age=31536000; includeSubDomains" # 隐藏服务器信息 -Server } # 日志配置 log { output file /var/log/caddy/admin.photography.log { roll_size 10MB roll_keep 5 } format json } # 错误页面处理 handle_errors { @404 { expression {http.error.status_code} == 404 } rewrite @404 /index.html file_server } }