第一步#
本指南带您从新装 Angie 软件包的欢迎页面开始,一步步把它扩展成一台完整的服务器:提供文件、把请求转发给应用、用自行签发的证书提供 HTTPS,并报告自身的统计信息。如果您已经在运行 nginx,请 迁移其配置,而不必手动重新搭建。
每一步都在上一步留下的文件基础上继续扩展,因此请按顺序完成。只有 HTTPS 这一步是可选的:它是唯一需要公网域名的步骤,之后的步骤都不依赖于它。
您需要在基于 systemd 的 Linux 上 从软件包安装 Angie,并拥有一个可以使用 sudo 的账户。在 Alpine 和 FreeBSD 上,安装页面给出了用来替代 systemctl 的 service 命令。 确认已安装的版本: 启动服务器并向它请求一个页面: 该响应来自软件包自带的欢迎页面服务器;下一步会展示它的定义位置。 配置更改通过重新加载生效,而不是重启:主进程重新读取配置并启动新的工作进程,旧的工作进程会先把手头的请求处理完再退出。完整的启动、停止、重新加载和日志轮转命令,以及它们背后的信号和命令行参数,请参阅 运行时控制。 主配置文件是 该文件被划分为若干上下文——把属于同一类流量的指令归为一组的块: 欢迎页面来自 上下文之间的继承、语法规则,以及指令参数中使用的大小和时间单位,
请参阅 配置文件。 从磁盘上的文件开始。创建两个目录,各放入一个文件;文件内容注明了所在目录,这样响应就能显示文件的来源: 第二个文件只是用来代替图片;换成真正的 PNG 文件,行为也一样。 将 测试配置并重新加载: 现在两个文件都可以访问,缺失的文件会返回 404: 这两个 location 都是前缀类型的 location:当请求 URI 以给定的字符串开头时即匹配,且匹配的最长前缀获胜。 root 指令指定的并不是要从中提供服务的目录——而是要将整个请求 URI 拼接到其后的目录,这就是为什么 备注 如果请求的处理结果和您预期的不同,答案几乎总是在访问日志和错误日志里,它们默认
写入 请求如何与虚拟服务器和 location 匹配,包括正则表达式 location 及其检查顺序,
请参阅 连接、会话、请求、日志。把 URI 映射到文件的指令——root、alias、
index、try_files——收录在 HTTP 模块参考中。 Angie 的第二个常见用途,是充当应用前面的一层,转发请求给它。这里由 Angie 自己充当这个应用:第二台服务器只监听回环端口 8080,提供自己的一个目录。之后您可以用真正的应用来替换它。 把这台服务器放进它自己的文件: 在 测试配置并重新加载: 现在请求会到达应用,图片请求除外: 第二个 location 以 proxy_pass 还有大量配套指令——用于请求头、超时、缓冲和缓存——记录在
Proxy 模块中。若要把请求分散到多台应用服务器而不是一台,
请定义 upstream 块并按名称代理到它。 这一步需要一个能解析到本主机公网地址的域名,以及一个可从互联网访问的 80 端口:证书颁发机构会通过 HTTP 获取一个文件来验证所有权。如果两者缺一,请跳到下一步;之后的步骤都不依赖这一步。 Angie 通过
ACME 自行获取并续订证书,无需外部客户端,也无需续订用的 cron 任务。在 server 块上方添加一个 acme_client(这是一个 http 级别的指令),并在 server 中引用该客户端,用您自己的域名替换 默认情况下,Angie 会通过 证书签发给这些域名:所有引用同一客户端的 server,其 server_name 中列出的全部域名;其中不是域名的条目,例如正则表达式和 测试配置并重新加载: 配置一生效,Angie 就会绑定 443 端口,但在证书到位之前它无法完成 TLS 握手,因此在此期间对该端口的请求会在握手阶段失败。证书签发不是即时完成的,具体取决于证书颁发机构。证书到位后: 如果证书始终没有到位,请查看下一步中 API 里 备注 在您还没有把配置调对之前,请将 acme_client 指向证书颁发机构的测试环境目录——对 Let's Encrypt 而言是
https://acme-staging-v02.api.letsencrypt.org/directory——这样失败的尝试就不会计入生产环境的速率限制。等证书成功签发后,
再切换到生产环境的 URL。 DNS 和 TLS-ALPN 验证、通配符证书、外部账户绑定以及从 Certbot 迁移,
都记录在 ACME 配置 中;指令和变量则在 ACME 模块中。 Angie 通过内置的 REST API 报告自身状态。请为它添加一个 location,限制只允许本地请求访问,并为 server 配置一个 status_zone,以便收集其计数器数据: 如果您跳过了 HTTPS 那一步,只需添加高亮的几行。软件包自带的 测试配置并重新加载;随后 API 将以 JSON 格式响应: 完整的 API 结构——上游服务器组、缓存、DNS 解析器、共享内存区、ACME 客户端,
以及 Angie PRO 中的动态配置——记录在 API 模块中。如果比起用 curl
请求,您更愿意直接查看这些数据,Console Light
Web 面板会呈现同样的指标。 针对具体任务的分步指南:SSL、OIDC、集群、监控面板和自定义指标。 按模块分组的全部指令和变量参考。 直接跳转到某条指令文档的短链接。 如果您在别处也在运行 nginx,可以把那些配置一并迁移过来。确认安装#
$ angie -v
Angie version: Angie/1.12.1
$ sudo systemctl start angie
$ curl -I localhost
HTTP/1.1 200 OK
Server: Angie/1.12.1
...
配置结构#
angie.conf;它的位置被编译进了二进制文件中:$ angie -V 2>&1 | tr ' ' '\n' | grep conf-path
--conf-path=/etc/angie/angie.conf
/etc/angie/http.d/ 下的文件被包含在 http 内部,因此其中存放的是 server 块和 http 级别的指令。一个 server 块描述一台虚拟服务器,其内部的 location 块则描述如何处理一类请求 URI。/etc/angie/http.d/default.conf,这是软件包定义的唯一一个服务器。本指南会替换这个文件,并保持 angie.conf 维持安装时的原样。提供静态文件#
$ sudo mkdir -p /data/www /data/images
$ echo 'Hello from /data/www' | sudo tee /data/www/index.html
Hello from /data/www
$ echo 'Hello from /data/images' | sudo tee /data/images/example.png
Hello from /data/images
/etc/angie/http.d/default.conf 的内容替换为:server {
listen 80;
location / {
root /data/www;
}
location /images/ {
root /data;
}
}
$ sudo angie -t && sudo systemctl reload angie
$ curl localhost/index.html
Hello from /data/www
$ curl localhost/images/example.png
Hello from /data/images
$ curl -o /dev/null -w '%{http_code}\n' localhost/images/missing.png
404
/index.html 匹配了 location /,这是可能的最短前缀,用来兜底其他 location 未能匹配的一切请求。location /images/ 需要的是 root /data,而不是 /data/images:把 URI /images/example.png 拼接到 /data 后面,得到的正是 /data/images/example.png。/var/log/angie/。代理到应用#
$ sudo mkdir -p /data/app
$ echo 'Hello from the application' | sudo tee /data/app/index.html
Hello from the application
server {
listen 127.0.0.1:8080;
root /data/app;
}
default.conf 中,把 location / 里的 root 换成 proxy_pass,并改为按扩展名而不是按前缀匹配图片:server {
listen 80;
location / {
proxy_pass http://127.0.0.1:8080;
}
location ~ \.(gif|jpg|png)$ {
root /data;
}
}
$ sudo angie -t && sudo systemctl reload angie
$ curl localhost/
Hello from the application
$ curl localhost/images/example.png
Hello from /data/images
~ 开头,这使它成为正则表达式 location,而不是前缀 location。Angie 会先检查前缀 location 并记住其中最长的匹配,然后按配置中出现的顺序依次尝试正则表达式;一旦其中某一个匹配成功,就会被采用。正因如此,一个简短的模式就能把图片请求从上面的兜底 location 中分离出来,让 Angie 直接从磁盘上应答这些请求,而不必经过应用。自动 HTTPS#
example.com 和 www.example.com:acme_client example https://acme-v02.api.letsencrypt.org/directory;
server {
listen 80;
listen 443 ssl;
server_name example.com www.example.com;
acme example;
ssl_certificate $acme_cert_example;
ssl_certificate_key $acme_cert_key_example;
location / {
proxy_pass http://127.0.0.1:8080;
}
location ~ \.(gif|jpg|png)$ {
root /data;
}
}
/etc/resolv.conf 解析证书颁发机构的名称,因此不需要 resolver 指令。在没有 IPv6 连接的主机上,请在 server 块上方添加 resolver conf ipv6=off;,让它不再请求无法使用的 AAAA 记录。_,会被跳过,并在错误日志中记录一条警告。证书是通过一个变量而不是文件路径传给 ssl_certificate 的,因此无需安装,也无需手动轮换。$ sudo angie -t && sudo systemctl reload angie
$ curl -I https://www.example.com/
HTTP/1.1 200 OK
...
/status/http/acme_clients/example 下的客户端状态,以及 错误日志 中的 ACME 相关消息;如果这些信息还不够,再打开 调试日志。服务器统计信息#
acme_client example https://acme-v02.api.letsencrypt.org/directory;
server {
listen 80;
listen 443 ssl;
server_name example.com www.example.com;
acme example;
ssl_certificate $acme_cert_example;
ssl_certificate_key $acme_cert_key_example;
status_zone site;
location / {
proxy_pass http://127.0.0.1:8080;
}
location ~ \.(gif|jpg|png)$ {
root /data;
}
location /status/ {
api /status/;
allow 127.0.0.1;
deny all;
}
}
default.conf 原本就有这个 /status/ location;替换该文件后它就消失了,因此需要把它加回来。$ sudo angie -t && sudo systemctl reload angie
$ curl localhost/status/angie/
{
"version": "1.12.1",
"build_time": "2026-07-17T06:58:49Z",
"address": "192.0.2.10",
"generation": 1,
"load_time": "2026-07-17T10:23:06.011Z"
}
/status/connections 报告已接受、已丢弃、活跃和空闲的连接数。按 server 和按 location 统计的计数器都是可选启用的:一个 server 只有在自己配置了 status_zone 后,才会出现在 /status/http/server_zones/ 下;一个 location 同理,出现在 /status/http/location_zones/ 下。上面的 server 配置了 status_zone,它的 location 没有:$ curl localhost/status/http/server_zones/site
{
"ssl": {
"handshaked": 3,
"reuses": 0,
"timedout": 0,
"failed": 0
},
"requests": {
"total": 5,
"processing": 1,
"discarded": 0
},
"responses": {
"200": 3,
"404": 1
},
"data": {
"received": 412,
"sent": 1418
}
}
ssl 对象之所以存在,是因为该 server 以 ssl 方式监听;如果没有它,这个区域就会从 requests 开始。后续步骤#