Một VPS mới toanh, một tên miền đã trỏ vào nó, và chỉ cách một lệnh nữa là có một web server đang chạy. Thứ tiếp theo bạn gõ sẽ cài đặt hoặc Caddy hoặc Nginx, và quyết định duy nhất đó định hình lượng thời gian bạn sẽ dành cho TLS suốt vòng đời của cái máy. Vậy nên: Caddy so với Nginx trên một VPS, bạn cài cái nào?
Tiếp theo đây là cùng ba cấu hình được thiết lập trong cả hai công cụ, đặt cạnh nhau, với các con số bộ nhớ được báo cáo, điểm cần lưu ý về chứng chỉ wildcard, và các ghi chú di chuyển thực tế nếu bạn đang dùng Nginx.
Phiên bản ngắn gọn
- Kết luận: Caddy dành cho hầu hết các khối lượng công việc trên VPS mới, đặc biệt là cho các nhà phát triển đơn lẻ, các nhóm nhỏ, và TLS kiểu cài xong là quên. Hãy chọn Nginx khi bạn cần hệ sinh thái module của nó, khả năng tinh chỉnh tường minh, chuyên môn sẵn có của nhóm, hoặc mức chiếm dụng bộ nhớ nhỏ nhất có thể.
- HTTPS tự động: Caddy tự lấy và gia hạn chứng chỉ. Không cần Certbot, không cần cron, không cần reload hook. Nginx cần Certbot (hoặc một ACME client khác) và cơ chế tự động hóa việc gia hạn xoay quanh nó.
- Bộ nhớ: Nginx gọn nhẹ hơn, nhờ dùng C thay vì Go. Khoảng cách này hiếm khi quyết định điều gì trên một gói hiện đại; các con số nằm trong bảng bên dưới.
- Điểm cần lưu ý: Caddy không phải là không cần cấu hình đối với wildcard. Một tên như *.example.com cần một DNS challenge, tức là cần một plugin và một API token.
Toàn bộ bảng so sánh trên một màn hình:
| Caddy | Nginx | |
|---|---|---|
| Ngôn ngữ | Go | C |
| HTTPS tự động | Tích hợp sẵn (Let's Encrypt + ZeroSSL) | Không có; cần Certbot hoặc một ACME client khác |
| Độ dài dòng của cấu hình | Tối giản (một vài dòng cho mỗi site) | Tường minh và dài dòng |
| HTTP/3 | Bật theo mặc định cùng với HTTPS | Có sẵn từ 1.25.0; nó phải được bật trong cấu hình Nginx. Các bản build từ mã nguồn yêu cầu --with-http_v3_module. |
| Bộ nhớ khi rảnh được báo cáo | 15-25 MB | 2-8 MB |
| Bộ nhớ được báo cáo ở mức 1.000 kết nối | 80-120 MB | 50-80 MB |
| Hệ sinh thái module | Nhỏ hơn, mở rộng thông qua xcaddy | Lớn và trưởng thành |
| Giấy phép | Apache 2.0 | BSD-2-Clause |
Các khoảng bộ nhớ đến từ một bài kiểm thử VPS của bên thứ ba và nên được xem là mang tính định hướng chứ không phải là yêu cầu áp dụng cho mọi trường hợp. Mức sử dụng thực tế tùy thuộc vào phiên bản phần mềm, các module được bật, việc ghi log, lưu lượng, và phương pháp kiểm thử. Thông tin về phiên bản và giấy phép đến từ các kho chính thức của các dự án.
HTTPS tự động của Caddy (và nó thực sự thay thế những gì)
Caddy tự lấy và gia hạn các chứng chỉ TLS. Trỏ một tên miền công khai vào máy, chạy Caddy, và nó sẽ lấy một chứng chỉ từ Let's Encrypt hoặc ZeroSSL, rồi gia hạn nó ở chế độ nền. Không cần Certbot, không cần cron job, không cần reload hook sau khi gia hạn. Đó là HTTPS tự động của Caddy gói gọn trong một câu, và đó chính là toàn bộ lý do người ta chuyển sang.
Ở bên trong, Caddy dùng challenge HTTP-01 (port 80) hoặc TLS-ALPN-01 (port 443) để chứng minh quyền sở hữu tên miền, rồi giữ cho chứng chỉ luôn mới mà không cần đến bất kỳ công cụ thứ hai nào.
Cách tương đương ở Nginx dùng một ACME client riêng. Với quy trình certbot --nginx phổ biến, Certbot có thể lấy và cài đặt chứng chỉ, rồi tái sử dụng cùng plugin và các tùy chọn đã lưu trong lúc gia hạn. Hầu hết các bản cài đặt Certbot cũng bao gồm một tác vụ được lên lịch chạy certbot renew tự động.
Nếu bạn dùng certbot certonly hoặc một ACME client khác chỉ ghi các tập tin đã gia hạn ra đĩa, hãy thêm một deploy hook để tải lại Nginx sau khi gia hạn thành công. Cách thiết lập đó hoạt động, nhưng nó vẫn để lại nhiều bộ phận hơn so với Caddy: web server, ACME client, bộ lên lịch gia hạn, và bất kỳ deployment hook nào đều vẫn là những thành phần riêng biệt.
Lợi thế vận hành của Caddy là việc cấp phát chứng chỉ, triển khai, gia hạn, và chuyển hướng HTTP sang HTTPS đều được tích hợp vào chính server. Theo mặc định, Caddy bắt đầu cố gắng gia hạn khi còn khoảng một phần ba vòng đời của chứng chỉ, tức 30 ngày đối với một chứng chỉ 90 ngày, trừ khi tổ chức cấp chứng chỉ chỉ định một khoảng gia hạn khác.
Mẹo hay: Các ACME challenge mặc định của Caddy cần có khả năng truy cập công khai trên port 80 hoặc 443: HTTP-01 dùng port 80, trong khi TLS-ALPN-01 dùng port 443. Nếu port 80 bị chặn nhưng 443 mở, TLS-ALPN vẫn có thể hoạt động; nếu máy không hướng ra internet, hãy dùng DNS-01, giống như chứng chỉ wildcard bên dưới.
Các tập tin cấu hình, đặt cạnh nhau
Đây là ba cấu hình VPS phổ biến, một reverse proxy HTTPS, phục vụ tập tin tĩnh, và xác thực cơ bản, được viết cho cả hai công cụ. Các ví dụ Caddy bao gồm HTTPS tự động. Các ví dụ Nginx giả định rằng một chứng chỉ đã được cấp sẵn, và các ví dụ về tập tin tĩnh và xác thực cơ bản chỉ hiển thị server block HTTPS. Hãy tái sử dụng khối chuyển hướng port-80 từ ví dụ đầu tiên nếu bạn muốn hành vi chuyển hướng HTTP sang HTTPS tương đương.
Một reverse proxy tới một ứng dụng cục bộ trên port 3000:
Caddyfile
example.com {
reverse_proxy localhost:3000
}
nginx.conf
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
Các dòng TLS trong khối Nginx giả định rằng Certbot đã chạy. Đối với một upstream HTTP như cái ở trên, Caddy chuyển tiếp header Host đến ở đầu vào và đặt X-Forwarded-For, X-Forwarded-Proto, và X-Forwarded-Host theo mặc định. Với Nginx, bạn thường thêm các proxy header một cách tường minh khi upstream cần host gốc, scheme, và chuỗi địa chỉ client. Đó là sự đánh đổi thu nhỏ: Caddy đi kèm các giá trị proxy mặc định thiết thực, trong khi Nginx làm cho phần lớn hành vi đó trở nên tường minh.
Phục vụ tập tin tĩnh:
Caddyfile
example.com {
root * /var/www
file_server
}
nginx.conf
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Xác thực cơ bản, bảo vệ mọi thứ đằng sau một tên người dùng và mật khẩu:
Caddyfile
example.com {
basic_auth {
Bob $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvG
}
reverse_proxy localhost:3000
}
nginx.conf
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Cả hai công cụ đều băm mật khẩu bên ngoài (out of band). Caddy dùng caddy hash-password; Nginx dùng htpasswd để dựng tập tin .htpasswd. Directive này là basic_auth trong Caddy hiện tại, nhân tiện nói thêm. Nó từng là basicauth cho đến khi v2.8.0 đổi tên nó, như được ghi chú trong tài liệu basic_auth của Caddyvà các hướng dẫn cũ vẫn khiến người ta vấp phải chỗ này.
Mẹo hay: Cái hash trong Caddyfile đó không phải là mật khẩu. Nó là kết quả bcrypt từ
caddy hash-password. Chạy lệnh, dán ra những gì nó in ra. Caddy từ chối mật khẩu dạng văn bản thuần trong cấu hình, đây là mặc định đúng đắn và là một điều bất ngờ nho nhỏ trong lần đầu.
Các cấu hình tự nói lên lập luận của chúng. Caddy gói gọn TLS, các proxy header hợp lý, và một chuyển hướng vào chỉ vài dòng; Nginx thì tường minh, dài dòng, và trao cho bạn từng cái nút điều chỉnh. Nếu bạn đã dành nhiều năm với Nginx, sự dài dòng là phản xạ ăn vào tay và khả năng kiểm soát chính là điều cốt lõi. Nếu bạn chưa từng, Caddyfile là một cấu hình bạn có thể nắm gọn trong đầu. Điểm thực tế thì đơn giản: cấu hình của Caddy dễ đọc lướt qua hơn, trong khi Nginx cho bạn khả năng kiểm soát tường minh hơn.
Hiệu năng và bộ nhớ: Đọc kỹ các bài benchmark
Các bài kiểm thử đã công bố đều chỉ về cùng một hướng chung: Nginx thường dùng ít bộ nhớ hơn và thường dẫn đầu về thông lượng thô, nhưng mức độ của lợi thế đó phụ thuộc rất nhiều vào môi trường.
In một bài kiểm thử của bên thứ ba trên VM bốn nhân, Nginx đạt xấp xỉ 48.000 request mỗi giây, so với khoảng 42.000 của Caddy. Cùng bài kiểm thử đó báo cáo độ trễ HTTPS p99 là 2,1 ms đối với Nginx và 2,4 ms đối với Caddy. Hãy xem chúng là kết quả từ một cấu hình duy nhất chứ không phải một biên độ hiệu năng áp dụng cho mọi trường hợp.
Các khoảng bộ nhớ trong bảng so sánh đến từ một bài kiểm thử VPS riêng biệt. Một bài kiểm thử tổng hợp khác ở mức 50.000 kết nối đồng thời báo cáo 145 MB đối với Nginx và 520 MB đối với Caddy, nhưng bài kiểm thử đó dùng phần cứng và điều kiện khối lượng công việc khác biệt đáng kể. Các con số tuyệt đối của nó không nên được so sánh trực tiếp với các con số VPS ở trên.
Kết luận đáng tin cậy thì hẹp hơn: Nginx nhìn chung chiếm dụng bộ nhớ nhỏ hơn và có xu hướng dẫn đầu dưới các khối lượng công việc thông lượng cao hoặc đồng thời cao. Đối với một reverse proxy VPS nhỏ đến trung bình thông thường, cả hai thường đều đủ nhanh, nên sự đơn giản trong vận hành thường là yếu tố quyết định hữu ích hơn.
Điểm rút ra của phần này: hãy chọn dựa trên vận hành trừ khi máy chủ của bạn bị hạn chế bộ nhớ hoặc các bài kiểm thử tải của chính bạn cho thấy thông lượng proxy là điểm nghẽn.
Điểm cần lưu ý về chứng chỉ wildcard (Caddy không phải lúc nào cũng không cần cấu hình)
Caddy có thể tự động hóa các chứng chỉ wildcard, nhưng không phải với các challenge HTTP-01 hoặc TLS-ALPN-01 mặc định của nó. Một chứng chỉ cho *.example.com yêu cầu xác thực DNS-01, điều mà Let's Encrypt bắt buộc đối với các chứng chỉ wildcard. Điều đó có nghĩa là một plugin nhà cung cấp DNS (được tích hợp vào binary Caddy của bạn qua xcaddy) cộng với một API token cho DNS host của bạn, được cấu hình trong khối tls. Nó không phải là câu chuyện gõ-một-dòng-rồi-bỏ-đó mà Caddy quảng bá.
Điều này gây khó cho những người dùng homelab đặt nhiều dịch vụ dưới một tên miền thật mà họ kiểm soát, chẳng hạn như *.home.example.com, và cho rằng việc cấp phát wildcard cũng tự động như app.example.com. Đối với các tên hoàn toàn nội bộ như *.homelab.internal, hãy xem đó là địa hạt của PKI cục bộ/nội bộ, không phải một wildcard Let's Encrypt công khai. Nói cho chính xác: Caddy làm wildcard tốt, nó chỉ không làm chúng với các challenge mặc định, và việc thiết lập là một bước phức tạp hơn so với trường hợp một tên miền đơn. Nginx cũng ở trong cùng hoàn cảnh tại đây, vì yêu cầu DNS-01 đến từ Let's Encrypt, không phải từ server.
Nếu bạn muốn một GUI: Nginx Proxy Manager (một ghi chú ngắn ngoài lề)
Nginx Proxy Manager là một thứ hoàn toàn khác so với hai công cụ ở trên, và nó đáng được dành một đoạn vì cái tên khiến người ta nhầm lẫn. NPM là một lớp bọc GUI trên Nginx: nó quản lý các luật reverse-proxy và chứng chỉ Let's Encrypt thông qua một giao diện web trên port 81. Nó không phải là Nginx core, và nó không được cấu hình theo cách mà Nginx core được cấu hình.
Sự đánh đổi là cái quen thuộc giữa nhấp chuột và cấu hình. NPM là nút bấm dễ dàng cho đến khi bạn bước ra khỏi con đường suôn sẻ. Cấu hình của nó được quản lý thông qua một cơ sở dữ liệu ứng dụng chứ không phải một tập tin cấu hình đơn lẻ chỉnh bằng tay. Bản cấu hình Docker mặc định dùng SQLite, trong khi MySQL/MariaDB và PostgreSQL là các tùy chọn cơ sở dữ liệu bên ngoài được hỗ trợ. Sự khác biệt đó cũng ảnh hưởng đến khả năng di chuyển: một cấu hình Caddy thường có thể được di chuyển bằng cách sao chép một Caddyfile duy nhất, trong khi một triển khai Nginx Proxy Manager đòi hỏi phải bảo toàn dữ liệu ứng dụng và cơ sở dữ liệu của nó. NPM là một lựa chọn tốt nếu bạn thực sự thích nhấp chuột hơn là chỉnh sửa và cấu hình của bạn luôn đơn giản. Nó là lựa chọn sai cho một quy trình infrastructure-as-code.
Di chuyển từ Nginx sang Caddy (Cái gì chuyển đổi được và cái gì không)
Nếu bạn đang dùng Nginx và cân nhắc chuyển đổi, hãy bắt đầu bằng cách hạ thấp kỳ vọng của bạn về tự động hóa: có một adapter cấu hình NGINX cho Caddy, nhưng nó chưa hoàn thiện và không nên được xem là một con đường di chuyển một phát ăn ngay đáng tin cậy. Một cuộc di chuyển từ Nginx sang Caddy chủ yếu là viết lại thủ công, và phần lớn nó trở nên ngắn gọn hơn.
Cái gì chuyển đổi được và trở nên đơn giản hơn, theo hướng dẫn chuyển đổi của cộng đồng Caddy:
- Đối với các upstream HTTP,
reverse_proxychuyển tiếp headerHostđến ở đầu vào và đặt các header X-Forwarded-* tiêu chuẩn theo mặc định, nên phần lớn các dòngproxy_set_headerđó biến mất. - PHP thu gọn từ một location block với
try_filescộngfastcgi_passcộng với một đống param thành mộtphp_fastcgidirective duy nhất. - Việc xử lý WebSocket là tự động trong Caddy v2. Nếu một hướng dẫn bảo bạn thêm một
websocketdirective riêng, thì đó là di tích của Caddy v1. Hãy bỏ qua nó.
Cái gì không chuyển đổi được một cách tự động: bất cứ thứ gì gắn với một module Nginx cụ thể mà Caddy không có, logic rewrite và location phức tạp mà bạn sẽ cần nghĩ lại thay vì chuyển thẳng, và các cấu hình chứng chỉ wildcard, thứ đưa bạn quay lại với cấu hình DNS-challenge từ phần ở trên. Hãy dự trù cho các module và các phần rewrite; phần còn lại thường là một sự giảm bớt số dòng ròng.
Bạn nên cài cái nào? (Quyết định)
Bạn đã thấy các cấu hình, các con số, điểm cần lưu ý về wildcard, và cái giá của việc di chuyển, nên đây là kết luận. Hãy cài Caddy nếu bạn là một nhà phát triển đơn lẻ hoặc một nhóm nhỏ, đây là một triển khai VPS mới, bạn muốn TLS kiểu cài xong là quên, bạn đang chạy Docker với định tuyến đơn giản, hoặc bạn chỉ muốn một cấu hình vừa với phản xạ ăn vào tay. Đó là hầu hết những người đang đọc bài này.
Hãy cài Nginx nếu bạn cần khả năng kiểm soát chi tiết hoặc một module cụ thể từ hệ sinh thái trưởng thành của nó, bạn đang vắt kiệt hiệu năng từ một máy chủ bị hạn chế bộ nhớ, bạn đang phục vụ tập tin tĩnh với mức đồng thời cao, hoặc nhóm của bạn đã có chuyên môn Nginx sâu và một đống cấu hình đang chạy tốt. Đó là những lý do vững chắc, và nếu một trong số đó là của bạn, Nginx là lựa chọn đúng. Đây không phải là trường hợp mà công cụ cũ hơn là công cụ sai.
Dù bạn chọn cái nào, bước tiếp theo là đưa nó lên máy. Cả hai Caddy và Nginx đều có sẵn dưới dạng triển khai một cú nhấp trong marketplace của chúng tôi, nên bạn có thể bỏ qua công đoạn cài đặt và đi thẳng đến Caddyfile hoặc server block. Một VPS 1 GB là điểm khởi đầu hợp lý cho một triển khai một site với lưu lượng thấp, nhưng hãy định cỡ máy chủ cho ứng dụng và lưu lượng đằng sau proxy chứ không phải chỉ riêng proxy. Nếu bạn đang dùng Caddy làm cửa ngõ cho các dịch vụ tự lưu trữ, nó có thể đứng trước một stack giám sát Prometheus và Grafana hoặc một triển khai Uptime Kuma mà không cần đến công cụ TLS riêng.
Điểm rút ra của phần này: hãy chọn Caddy trừ khi bạn có một lý do cụ thể chỉ về phía Nginx.
Câu hỏi thường gặp
Caddy có thay thế Certbot không?
Có. Caddy có thể tự lấy và gia hạn các chứng chỉ công khai, bao gồm cả chứng chỉ wildcard, nên không cần Certbot. Wildcard cần xác thực DNS-01, tức là phải cấu hình một module nhà cung cấp DNS tương thích và thông tin xác thực API.
Caddy có dùng ít bộ nhớ hơn Nginx không?
Không. Nginx nhìn chung chiếm dụng bộ nhớ nhỏ hơn. Một bài kiểm thử VPS của bên thứ ba báo cáo 2-8 MB khi rảnh đối với Nginx và 15-25 MB đối với Caddy, nhưng những con số đó đặc thù theo khối lượng công việc chứ không phải là yêu cầu bộ nhớ cố định. Sự khác biệt này quan trọng nhất trên các máy chủ bị hạn chế bộ nhớ đang chạy nhiều dịch vụ.
Caddy có nhanh hơn Nginx không?
Điều đó tùy thuộc vào khối lượng công việc. Cả hai thường đủ nhanh cho lưu lượng reverse-proxy VPS thông thường. Trong các bài kiểm thử được trích dẫn, Nginx dẫn đầu về thông lượng thô và hiệu quả bộ nhớ, nhưng mức độ khác biệt thay đổi đáng kể theo phần cứng, kiểu lưu lượng, và mức độ đồng thời. Không có một tỷ lệ phần trăm duy nhất nào áp dụng cho mọi triển khai.
Caddy có hỗ trợ chứng chỉ SSL wildcard không?
Có. Một wildcard chẳng hạn như *.example.com yêu cầu xác thực DNS-01. Một khi Caddy có một module nhà cung cấp DNS tương thích và thông tin xác thực API, nó có thể tự lấy và gia hạn chứng chỉ wildcard một cách tự động.
Nginx Proxy Manager có giống Nginx không?
Không. Nginx Proxy Manager là một lớp bọc GUI trên Nginx, lưu cấu hình của nó trong một cơ sở dữ liệu ứng dụng, dùng một web UI trên port 81, và quản lý các host reverse-proxy cùng các chứng chỉ thông qua giao diện đó. Nginx core được cấu hình bằng các tập tin văn bản và không có GUI riêng của mình.
Khi nào tôi nên dùng Nginx thay vì Caddy?
Hãy chọn Nginx khi bạn cần khả năng kiểm soát chi tiết, một module cụ thể từ hệ sinh thái trưởng thành của nó, từng MB cuối cùng trên một máy chủ bị hạn chế bộ nhớ, phục vụ tập tin tĩnh với mức đồng thời cao, hoặc nhóm của bạn đã có sẵn chuyên môn Nginx sâu.