Caddy-用Go写的新一代可扩展WebServer
前几天用 Netmaker 的时候发现它用 Caddy 替换掉了 Nginx,用了后发现确实简单好用,就安利一下。
Caddy 是一个强大的、可扩展的平台,用 Go 编写,可以为你的站点、服务和应用程序提供服务。如果你是 Caddy 的新手,你服务网络的方式将会改变。
引言
大多数人使用 Caddy 作为网络服务器或代理,但在其核心,Caddy 是一个服务器的服务器(a server of servers)。通过必要的模块,它可以承担任何长时间运行的进程的角色!
配置是动态的和可通过 Caddy 的 API 导出 。虽然不需要配置文件,但是您仍然可以使用它们; 大多数人最喜欢的配置 Caddy 的方法是使用 Caddyfile。配置文档的格式通过配置适配器采用多种形式,但 Caddy 的本地配置语言是 JSON。
Caddy 为所有主流平台编译,并且没有运行时依赖项。
新手指南
我们建议每个人不管经验如何都要看一下我们的入门指南。它将为你提供一个全面的视角来看待你的新网络服务器,这对你继续学习是无价的。本教程将探索使用 Caddy 的基础知识,并帮助您在更高的层次上熟悉它。
目的:
- 运行守护进程
- 试试 API
- 给 Caddy 一个配置
- 测试配置
- 制作一个 Caddyfile
- 使用配置适配器(config adapter)
- 从一个初始配置开始
- 比较 JSON 和 Caddyfile
- 比较 API 和配置文件
- 在后台运行
- 零停机时间配置重载
先决条件
- 已安装
caddy
及curl
(安装 Caddy 可以参考这里)
要启动 Caddy 作为一个守护程序,使用 run
子命令:
caddy run
默认情况下,Caddy 的配置(“ config”)为空。我们可以使用另一个终端访问管理 API 来验证这一点:
curl localhost:2019/config/
{% note info %}
️ 信息:
上面地址不是你的网站,localhost:2019 是用来控制 Caddy 的管理端点,并被默认限制为本机访问。
我们可以通过给它一个配置来使 Caddy 变得有用。这可以通过多种方式完成,但是我们将在下一节使用 curl
向 /load
端点发出 POST 请求。
你的第一个配置
为了准备我们的请求,我们需要做一个配置。
将其保存到 JSON 文件中(例如 caddy.JSON
) :
{
"apps": {
"http": {
"servers": {
"example": {
"listen": [":2015"],
"routes": [
{
"handle": [{
"handler": "static_response",
"body": "Hello, world!"
}]
}
]
}
}
}
}
}
然后上传:
curl localhost:2019/load \
-X POST \
-H "Content-Type: application/json" \
-d @caddy.json
我们可以通过如下命令验证 Caddy 将我们的新配置应用到另一个 GET 请求:
curl localhost:2019/config/
然后测试新的配置:
$curl localhost:2015
Hello, world!
如果你看到 Hello, world!
那恭喜了,成功了!确保配置按预期的方式工作总是一个好主意,尤其是在部署到生产环境之前。
你的第一个 Caddyfile
另一种配置 Caddy 的方法是 Caddyfile。上面我们在 JSON 编写的配置可以简单地表达为:
:2015
respond "Hello, world!"
将其保存到工作目录文件中名为 Caddyfile (无扩展名)的文件中。
如果 Caddy 已经在运行, (Ctrl + c)停止它,然后运行:
caddy adapt
或者你把 Caddyfile 存储在别的地方,或者给它取了别的名字:
caddy adapt --config /path/to/Caddyfile
您将看到 JSON 输出! 这里发生了什么?
我们只是使用配置适配器将 Caddyfile 转换为 Caddy 的原生 JSON 结构。
虽然我们可以获得这个输出并发出另一个 API 请求,但是我们可以跳过所有这些步骤,因为 caddy
命令可以为我们完成这些操作。如果工作目录中有一个叫 Caddyfile 的文件,并且没有指定其他配置,Caddy 会加载 Caddyfile,为我们改编,然后马上运行。
现在当前文件夹中有一个 Caddyfile,让我们再次运行 caddy:
caddy run
或者如果你的 Caddyfile 在其他地方:
caddy run --config /path/to/Caddyfile
(如果调用的是不以“ Caddyfile”开头的其他名称,则需要指定 --adapter caddyfile
)
正如你所看到的,有几种方法可以让你使用初始配置启动 Caddy:
- 在工作目录一个名为 Caddyfile 的文件
--config
flag (可选项,带有--adapter
flag)- -
-resume
flag (如果先前加载了配置)
JSON vs. Caddyfile
现在您知道了,Caddyfile 刚刚为您转换为 JSON。
Caddyfile 看起来比 JSON 简单,但是你应该一直使用它吗?每种方法都有利有弊。答案取决于您的需求和用例。
JSON | Caddyfile |
---|---|
完整的 Caddy 功能 | 最常见的 Caddy 功能部件 |
易于生成 | 易于手工制作 |
易于编程 | 难以自动化 |
非常有表现力 | 适度的表达 |
允许配置遍历 | 不能在 Caddyfile 间转换 |
部分配置更改 | 只能修改整个配置 |
可以导出 | 无法导出 |
与所有 API 端点兼容 | 与某些 API 端点兼容 |
自动生成的文档 | 文档是手写的 |
无处不在 | 小众 |
更有效率 | 更多的计算 |
有点无聊 | 挺有意思的 |
了解更多:JSON 结构 | 了解更多:Caddyfile 文档 |
您将需要决定哪一个最适合您的用例。
需要注意的是,JSON 和 Caddyfile (以及任何其他支持的配置适配器)都可以与 Caddy 的 API 一起使用。然而,如果您使用 JSON,您将获得 Caddy 的全部功能和 API 特性。如果使用配置适配器,使用 API 加载或更改配置的唯一方法是 /load 端点。
API vs. 配置文件
{% note info %}
️ 信息:
实际上,即使是配置文件也要经过 Caddy 的 API 端点,命令只是为您包装了这些 API 调用。
您还需要决定您的工作流是基于 API 的还是基于 CLI 的。(您可以在同一台服务器上同时使用 API 和配置文件,但我们不推荐这样做: 最好有一个真实的来源。)
API | 配置文件 |
---|---|
使用 HTTP 请求修改配置 | 使用 shell 命令修改配置 |
易于扩大规模 | 难以规模化 |
手工操作难度大 | 易于手工操作 |
真的很有趣 | 也很有趣 |
了解更多:API 教程 | 了解更多:Caddyfile 教程 |
{% note info %}
️ 信息:
使用 API 手动管理服务器配置完全可以通过适当的工具实现,例如: 任何 REST 客户端应用程序
或配置文件工作流的选择与配置适配器的使用是正交的: 你可以使用 JSON,但存储在一个文件中,并使用命令行界面; 相反,你也可以使用 Caddyfile 与 API。
但是大多数人会使用 json + api 或 Caddyfile + CLI 组合。
如您所见,Caddy 非常适合于各种各样的用例和部署!
Start,stop,run
因为 Caddy 是一个服务器,所以它可以无限期地运行。这意味着在执行 caddy run
之后,终端不会解除阻塞,直到进程终止(通常使用 Ctrl + c)。
虽然 caddy run
是最常见的,通常是推荐的(特别是在进行系统服务时!),你也可以选择使用 caddy start
启动 Caddy,并让它在后台运行:
caddy start
这将允许您再次使用您的终端,这在一些交互式无头环境中非常方便。
然后你必须自己停止这个过程,因为 Ctrl + c 不会为你停止:
caddy stop
或者使用 API 的/stop 端点。
重新加载配置
您的服务器可以执行零停机时间配置重载/更改。
加载或更改配置的所有 API 端点都是完美的,并且没有停机时间。
但是,在使用命令行时,可能很容易使用 Ctrl + c 来停止服务器,然后再重新启动服务器以获取新的配置。不要这样做: 停止和启动服务器与配置更改是正交的,并将导致停机。
相反,使用 caddy reload 命令来优雅地修改配置:
caddy reload
这实际上只是在引擎盖下使用了 API。它将加载并在必要时将配置文件调整为 JSON,然后在不停机的情况下优雅地替换活动配置。
如果加载新配置时出现任何错误,Caddy 将回滚到上次工作的配置。
{% note info %}
️ 信息:
从技术上讲,新配置是在停止旧配置之前启动的,因此在很短的时间内,两个配置都在运行!如果新配置失败,它将中止一个错误,而旧配置则根本不会停止
Caddy 常用功能
- 静态文件访问
- 反向代理
- HTTPS
静态文件访问
命令行方式
在终端中,切换到站点的根目录并运行:
caddy file-server
如果你得到一个权限错误,这可能意味着你的操作系统不允许你绑定到低端口---- 所以改用高端口:
caddy file-server --listen :2015
然后在浏览器中打开 (或 localhost:2015)查看您的网站!
如果你没有索引文件,但是你想要显示一个文件列表,可以使用 --browse
选项:
caddy file-server --browse
您可以使用另一个文件夹作为站点根目录:
caddy file-server --root ~/mysite
Caddyfile 方式
在站点的根目录中,创建一个名为 Caddyfile
的文件,其中包含以下内容:
localhost
file_server
或:
localhost
file_server browse
或
localhost
root * /home/me/mysite
file_server
分别对应以上的几个命令。
反向代理
本教程假设您有一个运行在 127.0.0.1:9000
上的后端 HTTP 服务。
命令行方式
很直白,直接能看明白:
caddy reverse-proxy --to 127.0.0.1:9000
如果你没有权限绑定到低端口,你可以从高端口代理:
caddy reverse-proxy --from :2016 --to 127.0.0.1:9000
Caddyfile 方式
直接上配置:
localhost
reverse_proxy 127.0.0.1:9000
caddy run
运行即可
更改代理的地址很容易:
:2016
reverse_proxy 127.0.0.1:9000
更改 Caddyfile 时,请确保重新加载 Caddy (或停止并重新启动它)。
使用反向代理指令以做很多事情。
HTTPS
本指南将向您展示如何立即使用完全自管理的 HTTPS 启动和运行。
{% note info %}
️ 信息:
在默认情况下,Caddy 对所有站点使用 HTTPS,只要在配置中提供了主机名。本教程假设您希望通过 HTTPS 获得一个公共受信任的站点(即不是“ localhost”) ,因此我们将使用一个公共域名和外部端口
先决条件:
- 对 DNS 的基本了解
- 注册的公共域名
- 对端口80和443的外部访问
- 已安装
caddy
和curl
在本教程中,将 example.com
替换为您的实际域名。
设置域名的 A/AAAA 记录指向服务器。您可以通过登录到您的 DNS 提供商和管理您的域名来做到这一点。
在继续之前,用权威 lookup 验证正确的记录。用你的域名替换 example.com
,如果你使用的是 IPv6,把 type=A
替换为 type=AAAA
:
curl "https://cloudflare-dns.com/dns-query?name=example.com&type=A" \
-H "accept: application/dns-json"
{% note info %}
️ 提示:
一切的前提是你是在 cloudflare 上买的这个域名。
如果不是的话,步骤会复杂一些。
参见这篇 域名在 DNSPod 上的证书申请方式
还要确保您的服务器在端口80和443上是可以从公共接口访问的。
{% note info %}
️ 提示:
如果您在您的家庭或其他受限制的网络,您可能需要转发端口或调整防火墙设置
所有我们需要做的是开始用您的域名配置 Caddy。有几种方法可以做到这一点。
Caddyfile
这是获取 HTTPS 的最常用方法。
创建一个名为 Caddyfile (无扩展名)的文件,其中第一行是您的域名,例如:
example.com
respond "Hello, privacy!"
然后从同一个目录中运行:
caddy run
您将看到 Caddy 提供一个 TLS 证书,并通过 HTTPS 服务您的站点。这是可能的,因为你的网站在 Caddyfile 中的地址包含一个域名。
file-server
命令
caddy file-server --domain example.com
可以了。
reverse-proxy
命令
caddy reverse-proxy --from example.com --to localhost:9000
总结
Caddy 吸引我的地方:
- 自动申请续约证书
- 简单命令的 Caddyfile
- Go 编写,Caddy 为所有主流平台编译,并且没有运行时依赖项。
参考资料
- Install — Caddy Documentation (caddyserver.com)
- Build from source — Caddy Documentation (caddyserver.com)
- Getting Started — Caddy Documentation (caddyserver.com)
- Quick-starts — Caddy Documentation (caddyserver.com)
- How to use DNS provider modules in Caddy 2 - Wiki - Caddy Community
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
Caddy-用Go写的新一代可扩展WebServer的更多相关文章
- 哇塞,原来自己写 Google Chrome 浏览器扩展(插件)这么容易!
1. 首先新建一个记事本,命名为 manifest.json,这是写 Google Chrome 浏览器扩展必须的文件 { "manifest_version": 2, " ...
- 多年前写的文本框扩展控件(有ValueChanging事件等),已放github
本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 阅读目录 介绍 起因 代码 使用 GitHub ...
- GoWorld – 用Golang写一个分布式可扩展、可热更的游戏服务器
GoWorld代码:https://github.com/xiaonanln/goworld Golang具有运行效率高.内存安全等优良特性,因此是非常适合用来进行服务器开发.使用Golang开发游戏 ...
- php内核分析(七)-扩展
这里阅读的php版本为PHP-7.1.0 RC3,阅读代码的平台为linux. 我们研究下反射这个扩展. 反射这个扩展目录是存在在:ext/reflection.其实里面的代码很简单.一个.h文件,一 ...
- 利用jQuery来扩展一个瀑布流插件
简单了解jQuery.fn.extend() jQuery.fn.extend()函数用于为jQuery扩展一个或多个实例属性和方法(主要用于扩展方法). (截图来自jQuery文档) 为了更清晰 ...
- 【转发】NPAPI学习(Firefox和Chrome扩展开发 )
NPAPI学习(Firefox和Chrome扩展开发 ) 2011-11-08 14:41:02 by [6yang], 1172 visits, 收藏 | 返回 Firefox和Chrome扩展开发 ...
- FME中Cass扩展属性转Shp的方法
问题:真受不了CAD中的注记,只能方便显示,难于数据交互.好在Cass把属性信息基本写在扩展属性中,但显示又成问题了.此事难两全!我们通过查看实体属性,需要把宗地界线的扩展属性提取出来.即组码为-3, ...
- MVC采用HtmlHelper扩展和Filter封装验证码的功能
最近因为有个项目除了登录还有其他很多地方需要用到验证码的功能,所以想到了采用HtmlHelper和ActionFilter封装一个验证码的功能,以便能够重复调用.封装好以后调用很方便,只需在View中 ...
- 非常好!!!【从头开始写操作系统系列】实现一个-GDT(1)【转】
转自:http://blog.csdn.net/luoyhang003/article/details/47338019 权声明:本文为博主原创文章,未经博主允许不得转载.(文章来源:http://b ...
- (转)可收缩、扩展的TextView
在一些应用中,比如腾讯的应用市场APP应用宝,关于某款应用的介绍文字,如果介绍文字过长,那么不是全部展现出来,而是显示三四行的开始部分(摘要),预知全部的内容,用户点击展开按钮即可查阅全部内容.这样的 ...
随机推荐
- Linux软件安装方式 - Tarball&RPM&YUM
软件安装 简介 概念详解 # 概念详解 - 开放源码: 程序码, 写给人类看的程序语言, 但机器并不认识, 所以无法执行; - 编译器: 将程序码转译成为机器看的懂得语言, 就类似翻译者的角色; - ...
- 题解 UVA439 骑士的移动 Knight Moves
前言 最近板子题刷多了-- 题意 一个 \(8\times 8\) 的棋盘,问马从起点到终点的最短步数为多少. \(\sf Solution\) 要求最短路径嘛,显然 bfs 更优. 读入 这个读入处 ...
- Sublime Text 修改默认语言为Python
Sublime Text 3 修改默认语言为Python 步骤如下 英文:Tools - Developer - New Plugin 中文:工具 - 插件开发 - 新建插件 清空原来内容,用下面的代 ...
- Maven 聚合工程的创建
简单场景举例 聚合工程创建示例 说明: 创建 Maven Project:表示创建 maven 项目,new Project 方式创建 创建 Maven Module:表示创建 maven 项目,ne ...
- 自动化运维?看看Python怎样完成自动任务调度⛵
作者:韩信子@ShowMeAI Python3◉技能提升系列:https://www.showmeai.tech/tutorials/56 本文地址:https://www.showmeai.tech ...
- gorm-sqlite
package mainimport ( "encoding/json" "fmt" "github.com/jinzhu/gorm" &q ...
- NET 6 实现滑动验证码(一)、创建工程
目录 实现滑动验证码的目的 创建.NET 6工程 实现滑动验证码的目的 传统验证码实现起来比较简单,但在OCR技术越来越成熟的情况下,验证码的破解难度越来越低,但如果将验证码难度加高(各种干扰背景,扭 ...
- 在业务逻辑中,经常会有父组件调用子组件方法的情况,vue2.0 和 vue3.0 的使用中有些不一样,在这里总结下。
在业务逻辑中,经常会有父组件调用子组件方法的情况,vue2.0 和 vue3.0 的使用中有些不一样,在这里总结下. vue2.0 中的使用方法 父组件: <template> <d ...
- Java框架--SSM&Oracle&Maven高级
〇.内容介绍 一.MyBatis01:框架概述.环境搭建及入门案例.自定义框架 1.介绍 框架:封装细节,是开发中的解决方案 三层架构与SSM的关系 表示层web:SpringMVC框架 业务层ser ...
- Windows10下python3和python2同时安装(二)python2.exe、python3.exe和pip2、pip3设置
Windows10下python3和python2同时安装(二) python2.exe.python3.exe和pip2.pip3设置 说明:安装安装python3和python2请参考本系列教程( ...