Nginx 静态文件服务
Nginx 以其出色的静态文件服务性能而闻名。本章将详细介绍如何配置 Nginx 来高效地服务静态文件。
🎯 基础静态文件配置
简单静态网站
nginx
server {
listen 80;
server_name example.com www.example.com;
# 网站根目录
root /var/www/example.com;
# 默认索引文件
index index.html index.htm;
# 主要位置块
location / {
try_files $uri $uri/ =404;
}
# 访问和错误日志
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
}
多目录配置
nginx
server {
listen 80;
server_name files.example.com;
# 主目录
location / {
root /var/www/html;
index index.html;
}
# 图片目录
location /images/ {
root /var/www;
# 实际路径:/var/www/images/
}
# 下载目录(使用 alias)
location /downloads/ {
alias /var/www/files/;
# 实际路径:/var/www/files/
}
# 文档目录
location /docs/ {
root /var/www;
autoindex on; # 启用目录浏览
}
}
📁 目录浏览配置
启用目录浏览
nginx
server {
listen 80;
server_name files.example.com;
root /var/www/files;
location / {
autoindex on; # 启用目录浏览
autoindex_exact_size off; # 显示文件大小(KB、MB)
autoindex_localtime on; # 显示本地时间
autoindex_format html; # 输出格式:html、xml、json、jsonp
}
}
自定义目录浏览样式
nginx
server {
listen 80;
server_name files.example.com;
root /var/www/files;
location / {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
# 自定义 CSS 样式
add_before_body /autoindex/header.html;
add_after_body /autoindex/footer.html;
}
# 样式文件位置
location /autoindex/ {
alias /var/www/autoindex/;
}
}
html
<!-- /var/www/autoindex/header.html -->
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
background-color: #f5f5f5;
}
h1 {
color: #333;
border-bottom: 2px solid #007acc;
padding-bottom: 10px;
}
a {
color: #007acc;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
pre {
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
</style>
🗜️ 压缩配置
基础压缩设置
nginx
http {
# 启用压缩
gzip on;
# 压缩级别(1-9)
gzip_comp_level 6;
# 最小压缩文件大小
gzip_min_length 1024;
# 压缩类型
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# 为代理请求启用压缩
gzip_proxied any;
# 添加 Vary 头
gzip_vary on;
# 禁用对旧版 IE 的压缩
gzip_disable "msie6";
}
高级压缩配置
nginx
server {
listen 80;
server_name example.com;
root /var/www/html;
# 预压缩文件支持
location ~* \.(css|js)$ {
gzip_static on; # 查找 .gz 预压缩文件
expires 1y;
add_header Cache-Control "public, immutable";
}
# Brotli 压缩(需要模块)
location ~* \.(html|css|js|xml|json)$ {
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
}
💾 缓存控制
基础缓存配置
nginx
server {
listen 80;
server_name example.com;
root /var/www/html;
# 静态资源长期缓存
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept-Encoding;
}
# HTML 文件短期缓存
location ~* \.html$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
}
# 动态内容不缓存
location ~* \.(php|cgi|pl|py)$ {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
}
条件缓存
nginx
server {
listen 80;
server_name example.com;
root /var/www/html;
# 根据文件类型设置缓存
location / {
# 图片文件
location ~* \.(png|jpg|jpeg|gif|webp)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# 字体文件
location ~* \.(woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Access-Control-Allow-Origin "*";
}
# CSS 和 JS 文件
location ~* \.(css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
# 支持版本控制
location ~* \.(css|js)\?v=(.+)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
# 默认处理
try_files $uri $uri/ =404;
}
}
🔒 访问控制
IP 访问限制
nginx
server {
listen 80;
server_name private.example.com;
root /var/www/private;
# 允许特定 IP 访问
location / {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
try_files $uri $uri/ =404;
}
# 管理员目录更严格的限制
location /admin/ {
allow 192.168.1.100;
deny all;
try_files $uri $uri/ =404;
}
}
基本认证
nginx
server {
listen 80;
server_name secure.example.com;
root /var/www/secure;
# 全站认证
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
try_files $uri $uri/ =404;
}
# 公开目录(无需认证)
location /public/ {
auth_basic off;
try_files $uri $uri/ =404;
}
}
bash
# 创建密码文件
sudo htpasswd -c /etc/nginx/.htpasswd username
sudo htpasswd /etc/nginx/.htpasswd another_user
# 或使用 openssl
echo -n 'username:' | sudo tee /etc/nginx/.htpasswd
openssl passwd -apr1 | sudo tee -a /etc/nginx/.htpasswd
文件类型限制
nginx
server {
listen 80;
server_name example.com;
root /var/www/html;
# 禁止访问特定文件类型
location ~* \.(htaccess|htpasswd|ini|log|sh|sql|conf)$ {
deny all;
return 404;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 禁止访问备份文件
location ~* ~$ {
deny all;
access_log off;
log_not_found off;
}
# 只允许特定文件类型
location /uploads/ {
location ~* \.(jpg|jpeg|png|gif|pdf|doc|docx)$ {
try_files $uri =404;
}
# 拒绝其他文件类型
location ~* \.(php|pl|py|jsp|asp|sh)$ {
deny all;
}
}
}
📱 移动端优化
响应式图片服务
nginx
server {
listen 80;
server_name img.example.com;
root /var/www/images;
# 根据设备类型提供不同尺寸的图片
location ~* \.(jpg|jpeg|png)$ {
set $mobile "";
if ($http_user_agent ~* "(mobile|iphone|android|blackberry)") {
set $mobile "_mobile";
}
try_files $uri$mobile $uri =404;
expires 30d;
add_header Cache-Control "public";
}
}
WebP 图片支持
nginx
server {
listen 80;
server_name example.com;
root /var/www/html;
# WebP 图片支持
location ~* \.(png|jpg|jpeg)$ {
set $webp_suffix "";
if ($http_accept ~* "webp") {
set $webp_suffix ".webp";
}
try_files $uri$webp_suffix $uri =404;
expires 30d;
add_header Vary Accept;
}
}
🚀 性能优化
高效文件传输
nginx
http {
# 启用高效文件传输
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 文件缓存
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
server {
listen 80;
server_name example.com;
root /var/www/html;
# 大文件优化
location /downloads/ {
# 限制下载速度
limit_rate 1m;
# 延迟限速(前 10MB 不限速)
limit_rate_after 10m;
# 支持断点续传
add_header Accept-Ranges bytes;
}
}
并发连接优化
nginx
http {
# 连接优化
keepalive_timeout 65;
keepalive_requests 100;
# 客户端缓冲区
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
}
🔧 单页应用 (SPA) 支持
React/Vue/Angular 应用
nginx
server {
listen 80;
server_name app.example.com;
root /var/www/spa;
index index.html;
# SPA 路由支持
location / {
try_files $uri $uri/ /index.html;
}
# API 代理
location /api/ {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 静态资源缓存
location /static/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Service Worker 特殊处理
location /sw.js {
add_header Cache-Control "no-cache";
proxy_cache_bypass $http_pragma;
proxy_cache_revalidate on;
expires off;
access_log off;
}
}
PWA 支持
nginx
server {
listen 80;
server_name pwa.example.com;
root /var/www/pwa;
# Manifest 文件
location /manifest.json {
add_header Content-Type application/manifest+json;
add_header Cache-Control "public, max-age=86400";
}
# Service Worker
location /sw.js {
add_header Content-Type application/javascript;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Service-Worker-Allowed "/";
}
# 离线页面
location /offline.html {
add_header Cache-Control "no-cache";
internal;
}
# 主应用
location / {
try_files $uri $uri/ /index.html;
# PWA 相关头
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
}
}
📊 监控和日志
访问统计
nginx
server {
listen 80;
server_name example.com;
root /var/www/html;
# 详细的访问日志
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/detailed.log detailed;
# 静态文件不记录日志
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
access_log off;
expires 30d;
}
# 特殊文件记录日志
location /important/ {
access_log /var/log/nginx/important.log detailed;
try_files $uri $uri/ =404;
}
}
错误页面
nginx
server {
listen 80;
server_name example.com;
root /var/www/html;
# 自定义错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
internal;
}
location = /50x.html {
internal;
}
# 错误页面样式
location /error-assets/ {
alias /var/www/error-pages/;
expires 1d;
}
}
通过这些配置,您可以构建高性能、安全的静态文件服务。接下来我们将学习反向代理配置。 🚀