静态资源服务 #
概述 #
Caddy 可以轻松配置静态文件服务,用于托管网站、图片、CSS、JavaScript 等静态资源。
text
┌─────────────────────────────────────────────────────────────┐
│ Caddy 静态文件服务 │
├─────────────────────────────────────────────────────────────┤
│ 📁 文件服务 - 托管静态文件 │
│ 📂 目录浏览 - 列出目录内容 │
│ 🗜️ 压缩传输 - Gzip/Zstd 压缩 │
│ 📦 缓存控制 - 浏览器缓存配置 │
│ 🔗 范围请求 - 断点续传支持 │
└─────────────────────────────────────────────────────────────┘
基本配置 #
最简单的静态站点 #
caddyfile
example.com {
root * /var/www/html
file_server
}
完整配置示例 #
caddyfile
example.com {
# 设置根目录
root * /var/www/html
# 启用静态文件服务
file_server {
# 启用目录浏览
browse
# 预压缩文件
precompressed
# 自定义索引文件
index index.html index.htm
}
# 启用压缩
encode gzip zstd
# 日志
log {
output file /var/log/caddy/access.log
}
}
root 指令 #
基本用法 #
caddyfile
# 设置根目录
root * /var/www/html
# 使用变量
root * /var/www/{host}
动态根目录 #
caddyfile
example.com {
# 根据主机名设置不同目录
@sub host sub.example.com
root @sub /var/www/sub
root * /var/www/main
file_server
}
匹配器使用 #
caddyfile
example.com {
# 不同路径使用不同根目录
root * /var/www/html
handle /static/* {
root * /var/www/static
file_server
}
handle /assets/* {
root * /var/www/assets
file_server
}
handle {
file_server
}
}
file_server 指令 #
基本参数 #
caddyfile
example.com {
root * /var/www/html
file_server {
# 启用目录浏览
browse
# 预压缩文件支持
precompressed
# 自定义索引文件
index index.html index.htm default.html
# 禁用目录浏览的排序
browse {
sort disabled
}
}
}
目录浏览 #
caddyfile
example.com {
root * /var/www/files
file_server browse {
# 自定义模板
template browse.html
}
}
自定义目录浏览模板 #
caddyfile
example.com {
root * /var/www/files
file_server browse {
template {
# 使用内置变量
# {path} - 当前路径
# {files} - 文件列表
# {dirs} - 目录列表
}
}
}
预压缩文件 #
Caddy 支持自动提供预压缩文件:
caddyfile
example.com {
root * /var/www/html
file_server {
# 启用预压缩
# 如果请求 style.css,且存在 style.css.gz
# Caddy 会自动返回 .gz 文件
precompressed
# 指定预压缩格式
precompressed gzip zstd br
}
}
text
# 文件结构
/var/www/html/
├── style.css # 原始文件
├── style.css.gz # Gzip 压缩
├── style.css.br # Brotli 压缩
└── style.css.zst # Zstandard 压缩
压缩配置 #
基本压缩 #
caddyfile
example.com {
root * /var/www/html
file_server
# 启用 Gzip 和 Zstd 压缩
encode gzip zstd
}
压缩选项 #
caddyfile
example.com {
root * /var/www/html
file_server
encode {
# 压缩算法
gzip 6 # Gzip 压缩级别 (1-9)
zstd # Zstandard 压缩
# 排除特定类型
except image/* video/* application/pdf
# 最小压缩大小
minimum_length 256
}
}
条件压缩 #
caddyfile
example.com {
root * /var/www/html
file_server
# 只压缩特定文件
@compressable {
path *.css *.js *.html *.xml *.json
}
encode @compressable gzip zstd
}
缓存控制 #
基本缓存配置 #
caddyfile
example.com {
root * /var/www/html
file_server
# 静态资源长期缓存
@static {
path *.css *.js *.png *.jpg *.jpeg *.gif *.ico *.woff *.woff2
}
header @static Cache-Control "public, max-age=31536000, immutable"
# HTML 文件短期缓存
@html path *.html
header @html Cache-Control "public, max-age=3600"
# 禁用缓存
@nocache path /api/*
header @nocache Cache-Control "no-store, no-cache, must-revalidate"
}
ETag 支持 #
Caddy 自动为静态文件生成 ETag:
caddyfile
example.com {
root * /var/www/html
file_server
# ETag 默认启用
# 无需额外配置
}
Last-Modified 支持 #
Caddy 自动使用文件的修改时间作为 Last-Modified:
caddyfile
example.com {
root * /var/www/html
file_server
# Last-Modified 默认启用
# 无需额外配置
}
范围请求 #
Caddy 自动支持范围请求(断点续传):
caddyfile
example.com {
root * /var/www/files
file_server
# 范围请求默认启用
# 支持 Range 请求头
# 用于视频、大文件下载
}
验证范围请求 #
bash
# 测试范围请求
curl -H "Range: bytes=0-99" https://example.com/video.mp4 -I
# 响应示例
HTTP/2 206 Partial Content
Accept-Ranges: bytes
Content-Range: bytes 0-99/1000000
Content-Length: 100
单页应用(SPA)配置 #
基本配置 #
caddyfile
example.com {
root * /var/www/spa
file_server
# 所有路径回退到 index.html
try_files {path} /index.html
}
完整 SPA 配置 #
caddyfile
example.com {
root * /var/www/spa
# 静态资源缓存
@assets {
path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.woff *.woff2 *.svg
}
header @assets Cache-Control "public, max-age=31536000, immutable"
# 静态文件服务
file_server
# SPA 路由回退
@notStatic {
not path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.woff *.woff2 *.svg
}
try_files @notStatic {path} /index.html
}
Vue/React 应用配置 #
caddyfile
app.example.com {
root * /var/www/app
encode gzip zstd
# API 代理
handle /api/* {
reverse_proxy localhost:3000
}
# 静态资源
handle /assets/* {
file_server
header Cache-Control "public, max-age=31536000, immutable"
}
# SPA 回退
handle {
try_files {path} /index.html
file_server
}
}
虚拟主机配置 #
多站点配置 #
caddyfile
# 站点 1
site1.example.com {
root * /var/www/site1
file_server
encode gzip
}
# 站点 2
site2.example.com {
root * /var/www/site2
file_server
encode gzip
}
# 站点 3 - 带认证
private.example.com {
root * /var/www/private
file_server
basicauth {
admin $2a$14$Zkx...
}
}
子目录配置 #
caddyfile
example.com {
root * /var/www/main
file_server
# 子目录映射到不同目录
handle /blog/* {
root * /var/www/blog
file_server
}
handle /docs/* {
root * /var/www/docs
file_server
}
}
安全配置 #
禁止访问敏感文件 #
caddyfile
example.com {
root * /var/www/html
file_server
# 禁止访问隐藏文件
@hidden path /.*/**
respond @hidden "Access denied" 403
# 禁止访问敏感文件
@sensitive path *.env *.git/* *.htaccess *.htpasswd
respond @sensitive "Access denied" 403
}
安全头部 #
caddyfile
example.com {
root * /var/www/html
file_server
header {
# 防止点击劫持
X-Frame-Options "SAMEORIGIN"
# 防止 MIME 类型嗅探
X-Content-Type-Options "nosniff"
# XSS 保护
X-XSS-Protection "1; mode=block"
# 内容安全策略
Content-Security-Policy "default-src 'self'"
# 引用策略
Referrer-Policy "strict-origin-when-cross-origin"
# 移除服务器标识
-Server
}
}
性能优化 #
连接优化 #
caddyfile
example.com {
root * /var/www/html
file_server
encode gzip zstd
# HTTP/2 推送
push /style.css
push /app.js
# Keep-Alive
header Connection "keep-alive"
}
文件描述符缓存 #
caddyfile
{
# 全局选项
servers {
# 最大文件描述符缓存
max_header_size 16KB
protocols h1 h2 h3
}
}
example.com {
root * /var/www/html
file_server
}
错误页面 #
自定义错误页面 #
caddyfile
example.com {
root * /var/www/html
file_server
# 自定义错误页面
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404.html
file_server
@5xx {
expression {http.error.status_code} >= 500
}
rewrite @5xx /500.html
file_server
}
}
JSON 错误响应 #
caddyfile
api.example.com {
root * /var/www/api
file_server
handle_errors {
respond `{"error": "{http.error.status_text}", "code": {http.error.status_code}}` {http.error.status_code}
}
}
日志配置 #
访问日志 #
caddyfile
example.com {
root * /var/www/html
file_server
log {
output file /var/log/caddy/access.log {
# 日志轮转
roll_size 100mb
roll_keep 10
roll_keep_for 168h
}
format json
}
}
自定义日志格式 #
caddyfile
example.com {
root * /var/www/html
file_server
log {
output file /var/log/caddy/access.log
format console {
time_format "2006-01-02 15:04:05"
}
}
}
完整示例 #
企业网站配置 #
caddyfile
example.com {
root * /var/www/html
encode gzip zstd
# 安全头部
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
# 静态资源缓存
@static {
path *.css *.js *.png *.jpg *.jpeg *.gif *.ico *.woff *.woff2 *.svg
}
header @static Cache-Control "public, max-age=31536000, immutable"
# HTML 缓存
@html path *.html
header @html Cache-Control "public, max-age=3600"
# 禁止访问敏感文件
@hidden path /.*/** *.env *.git/*
respond @hidden "Forbidden" 403
# 文件服务
file_server {
precompressed
index index.html
}
# SPA 回退
try_files {path} /index.html
# 日志
log {
output file /var/log/caddy/access.log {
roll_size 50mb
roll_keep 5
}
format json
}
# 错误页面
handle_errors {
respond "{http.error.status_code} {http.error.status_text}"
}
}
# 带 www 重定向
www.example.com {
redir https://example.com{uri} permanent
}
文件下载服务器 #
caddyfile
files.example.com {
root * /var/www/files
# 目录浏览
file_server browse {
sort name desc
}
# 压缩
encode gzip
# 认证
basicauth {
admin $2a$14$Zkx...
}
# 下载头部
header Content-Disposition "attachment"
# 日志
log {
output file /var/log/caddy/files.log
}
}
下一步 #
现在你已经掌握了静态文件服务配置,接下来学习 反向代理 了解如何配置代理服务!
最后更新:2026-03-28