Đoạn mã bên dưới trình bày một ví dụ hoàn chỉnh file Caddyfile cho WordPress. Thay $DOMAIN bằng tên miền cụ thể của bạn:
# 1. Chuyen huong www ve non-www
www.$DOMAIN {
redir https://$DOMAIN{uri} permanent
}
# 2. Cau hinh chinh
$DOMAIN {
root * /var/www/$DOMAIN/public_html
encode zstd gzip
# Log: Tu dong xoay vong
log {
output file /var/www/$DOMAIN/logs/access.log {
roll_size 10mb
roll_keep 10
}
}
# --- SECURITY HEADERS ---
# Sau khi HTTPS da chay on dinh, hay bo comment dong Strict-Transport-Security
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
X-XSS-Protection "0"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "camera=(), microphone=(), geolocation=(), browsing-topics=()"
# Strict-Transport-Security "max-age=31536000; includeSubDomains"
-Server
-X-Powered-By
}
# --- CACHE CODE (CSS/JS) ---
# Khong dung immutable de tranh loi khi update code
@code_assets {
file
path *.css *.js
}
header @code_assets Cache-Control "public, max-age=604800"
# --- CACHE MEDIA (ANH/FONT) ---
# Dung immutable vi file anh it khi sua noi dung ma giu nguyen ten
@media_assets {
file
path *.ico *.gif *.jpg *.jpeg *.png *.svg *.woff *.woff2 *.webp *.avif
}
header @media_assets Cache-Control "public, max-age=31536000, immutable"
# --- CHAN FILE NHAY CAM (SECURITY BLOCK) ---
@forbidden {
# 1. Block PHP Uploads
path /wp-content/uploads/*.php
# 2. Block System Files & Directories
path /wp-config.php
path /.htaccess
path /.git
path /.git/*
path *.env
path /readme.html
path /license.txt
# 3. Block xmlrpc
path /xmlrpc.php
# 4. Block Backups & Logs
path *.sql *.bak *.log *.old
# path *.zip *.rar *.tar *.7z
}
# Tra ve 404
respond @forbidden 404
# PHP FastCGI (Check lai duong dan socket neu dung OS khac Ubuntu/Debian)
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
# Tang gioi han upload, can chinh them /etc/php/8.3/fpm/php.ini cho dong bo
request_body {
max_size 50MB
}
}
Nó gồm các phần sau.
a. Xác định địa chỉ truy cập chính của trang
Để minh bạch trang web có dạng truy cập chính là có-www hay không-www, mã bên dưới là dành cho trang có địa chỉ chính là không-www:
www.$DOMAIN {
redir https://$DOMAIN{uri} permanent
}
Link tham khảo thêm: https://kiencang.net/cau-hinh-chuyen-huong-trong-caddyfile/
b. Cấu hình chính của trang
Ngay bên dưới phần chuyển hướng là cấu hình chính. Đối với trang WordPress nó sẽ thế này:
$DOMAIN {
root * /var/www/$DOMAIN/public_html
encode zstd gzip
log {
output file /var/www/$DOMAIN/logs/access.log {
roll_size 10mb
roll_keep 10
}
}
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
}
Nó xác định 5 thành phần quan trọng:
- Vị trí gốc lưu thư mục trang web (root);
- Cách nén dữ liệu văn bản (encode);
- Nơi lưu lại các hoạt động (log);
- Địa chỉ chính xác của PHP-FPM để Caddy trao đổi yêu cầu & kết quả, vì bản thân Caddy không xử lý PHP (php_fastcgi);
- Và cuối cùng chỉ định Caddy xử lý file tĩnh (file_server);
Đây là các chỉ thị bắt buộc phải có để WordPress hoạt động trơn tru trên Caddy Web Server.
Link tham khảo thêm: https://kiencang.net/wordpress-co-ban-caddyfile/
c. Header bảo mật
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
X-XSS-Protection "0"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "camera=(), microphone=(), geolocation=(), browsing-topics=()"
# Strict-Transport-Security "max-age=31536000; includeSubDomains"
-Server
-X-Powered-By
}
Các header này tập trung vào các rủi ro cơ bản. Ngăn các đối tượng có ý đồ xấu lợi dụng hoặc tấn công trực tiếp trang web.
Link tham khảo thêm: https://kiencang.net/header-co-ban-trong-caddyfile/
d. Cache nội dung tĩnh
Cho mục đích tăng cường hiệu suất:
# --- CACHE CODE (CSS/JS) ---
@code_assets {
file
path *.css *.js
}
header @code_assets Cache-Control "public, max-age=604800"
# --- CACHE MEDIA (ANH/FONT) ---
@media_assets {
file
path *.ico *.gif *.jpg *.jpeg *.png *.svg *.woff *.woff2 *.webp *.avif
}
header @media_assets Cache-Control "public, max-age=31536000, immutable"
Các file rất hiếm khi thay đổi như ảnh, font có thời gian cache rất lâu, giúp giảm tải cho trang web.
Các file thi thoảng thay đổi như CSS, JS có thời gian cache ngắn hơn.
Link tham khảo thêm: https://kiencang.net/header-cache-trong-caddyfile/
e. Chặn truy cập vào các file nhạy cảm
Để an toàn hơn, các file chứa mật khẩu, hoặc chứa bất cứ thông tin, phương tiện gì mà kẻ tấn công có khả năng cao lợi dụng sẽ bị chặn không cho truy cập công khai.
@forbidden {
# 1. Block PHP Uploads
path /wp-content/uploads/*.php
# 2. Block System Files & Directories
path /wp-config.php
path /.htaccess
path /.git
path /.git/*
path *.env
path /readme.html
path /license.txt
# 3. Block xmlrpc
path /xmlrpc.php
# 4. Block Backups & Logs
path *.sql *.bak *.log *.old
# path *.zip *.rar *.tar *.7z
}
# Tra ve 404
respond @forbidden 404
Link tham khảo thêm: https://kiencang.net/chan-file-nhay-cam-trong-caddyfile/
f. Điều chỉnh nhỏ liên quan đến giới hạn up lên
Mặc định có các giới hạn vừa phải để up lên Caddy & WordPress, phần này điểu chỉnh tăng lượng dữ liệu lên cao hơn tùy theo ý muốn.
request_body {
max_size 50MB
}
Link tham khảo thêm: https://kiencang.net/request_body-trong-caddyfile/
g. Tổng hợp
Chúng ta có thể tóm tắt thành các tên nhóm mã từ trên xuống dưới như sau:
1. Lệnh chuyển hướng (redir)
2. Chỉ định thư mục web gốc (root)
3. Nén (encode)
4. Ghi lại log (log)
5. Header bảo mật (Referrer-Policy “strict-origin-when-cross-origin”, -Server,…)
6. Cache (Cache-Control) nội dung tĩnh (ảnh, CSS, JS, font,…)
7. Chặn truy cập file nhạy cảm (respond 404)
8. php_fastcgi
9. file_server
10. request_body
Thứ tự này đã khá ổn, đặc biệt là việc chặn truy cập file nhạy cảm phải ở phía trước php_fastcgi. Nghĩa là Caddy sẽ chặn ngay yêu cầu có vấn đề, chỉ cho các yêu cầu hợp lệ đến được bộ phận xử lý PHP.
Riêng request_body cần điều chỉnh vị trí cho lên trên, file khi upload lên cần sớm biết có giới hạn dung lượng phù hợp không. Vị trí tốt hơn của request_body là nằm ngay sau nhóm root, encode.
Lưu ý thú vị là vị trí của khối mã chúng ta viết không ảnh hưởng đến cách Caddy xử lý! (mặc dù ban đầu tôi cũng tưởng như vậy). Caddy có thứ tự xử lý các chỉ thị cứng (tức là dù bạn viết php_fastcgi trước root, thì khối root vẫn được Caddy ngầm xử lý trước), tuy nhiên việc để các khối mã đồng bộ với cách Caddy xử lý ngầm sẽ giúp chúng ta quản lý tốt hơn.