caddyfile-generation
GitHub生成 Caddyfile 配置,支持静态站点、SPA 路由回退、缓存压缩、重定向及安全头设置,适用于前端部署与反向代理场景。
Trigger Scenarios
Install
npx skills add nixopus/nixopus --skill caddyfile-generation -g -y
SKILL.md
Frontmatter
{
"name": "caddyfile-generation",
"metadata": {
"version": "1.0"
},
"description": "Generate Caddyfile configurations for static sites and reverse proxies — SPA fallback routing, cache headers, compression, redirects, and error pages. Use when deploying a static site that needs custom Caddy configuration, or when the user needs SPA routing, caching, or redirect rules."
}
Caddyfile Generation
When to Generate
- Static sites served by Caddy (from
static-deployor frontend builds) - SPA applications that need fallback routing (React, Vue, Angular, SvelteKit static)
- Sites needing custom cache headers, compression, or redirects
Base Template
Minimal Caddyfile for a static site:
:80 {
root * /srv
file_server
}
SPA Fallback Routing
Single-page apps need all non-file routes to return index.html:
:80 {
root * /srv
try_files {path} /index.html
file_server
}
Frameworks that need this: React (CRA, Vite), Vue, Angular, SvelteKit (static adapter), Remix (SPA mode).
Frameworks that do NOT need this: Next.js (has its own server), Nuxt (SSR), Astro (generates individual HTML files for each route).
Cache Headers for Hashed Assets
Frontend build tools (Vite, Webpack) produce files with content hashes (e.g. main.a1b2c3.js). These can be cached aggressively:
:80 {
root * /srv
@hashed path_regexp hashed \.(js|css|woff2?|ttf|eot|svg|png|jpg|jpeg|gif|ico|webp)$
header @hashed Cache-Control "public, max-age=31536000, immutable"
@html path *.html /
header @html Cache-Control "no-cache, no-store, must-revalidate"
try_files {path} /index.html
file_server
}
HTML files must NOT be cached (they reference the hashed assets).
Compression
Enable gzip and zstd compression:
:80 {
root * /srv
encode zstd gzip
try_files {path} /index.html
file_server
}
Redirects
www to non-www
www.example.com {
redir https://example.com{uri} permanent
}
example.com {
root * /srv
file_server
}
HTTP to HTTPS
Caddy handles this automatically when using domain names. Only needed for explicit port-based configs:
:80 {
redir https://{host}{uri} permanent
}
Note: In Nixopus deployments, the proxy layer already handles TLS termination. Do NOT add HTTPS redirects in the app's Caddyfile — the proxy handles this.
Custom Error Pages
:80 {
root * /srv
handle_errors {
@404 expression {err.status_code} == 404
rewrite @404 /404.html
file_server
}
try_files {path} /index.html
file_server
}
Reverse Proxy (API backend)
When a static frontend needs to proxy API requests to a backend:
:80 {
root * /srv
handle /api/* {
reverse_proxy backend:8080
}
try_files {path} /index.html
file_server
}
Security Headers
:80 {
root * /srv
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
file_server
}
Complete Production Template
Combines SPA routing, caching, compression, and security headers:
:80 {
root * /srv
encode zstd gzip
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
@hashed path_regexp hashed \.(js|css|woff2?|ttf|eot|svg|png|jpg|jpeg|gif|ico|webp)$
header @hashed Cache-Control "public, max-age=31536000, immutable"
@html path *.html /
header @html Cache-Control "no-cache, no-store, must-revalidate"
try_files {path} /index.html
file_server
}
Generation Logic
- Determine if the app is a SPA (needs
try_filesfallback) or multi-page (doesn't) - Start with the base template
- Add
try_files {path} /index.htmlif SPA - Add
encode zstd gzipfor compression - Add hashed asset cache headers if the build tool produces hashed filenames
- Add security headers
- Write to
Caddyfileat the project root
Gotchas
- Caddy listens on
:80inside Docker — the proxy layer handles external port mapping and TLS try_filesmust come BEFOREfile_serverin the Caddyfileroot * /srvmust match the COPY destination in the Dockerfile- Do NOT configure HTTPS/TLS in the Caddyfile for Nixopus deployments — the edge proxy handles TLS termination
- Caddy's
file_serverserves directory listings by default — addfile_server browseonly if intentional
Related Skills
static-deploy— Dockerfile patterns that use Caddy as the web serverdockerfile-generation— Generate the Caddyfile alongside the Dockerfile
Version History
- cf05d97 Current 2026-08-20 14:51


