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 的文件
--configflag (可选项,带有--adapterflag)- -
-resumeflag (如果先前加载了配置)
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应用宝,关于某款应用的介绍文字,如果介绍文字过长,那么不是全部展现出来,而是显示三四行的开始部分(摘要),预知全部的内容,用户点击展开按钮即可查阅全部内容.这样的 ...
随机推荐
- Ansible 批处理实战
软件简介 Ansible 是一款自动化运维工具,基于 Python 开发,集合了众多运维工具(puppet.chef.func.fabric)的优点,实现了批量系统配置.批量程序部署.批量运行命令等功 ...
- 43.Permission源码解析和自定义权限类
drf的权限类位于permission模块 如何确定权限 认证.限流,权限决定是否应该接收请求或拒绝访问 权限检查在视图的最开始处执行,在继续执行其他代码前 权限检查通常会使用request.us ...
- 【SSM】学习笔记(二)——SpringMVC入门
原视频链接:https://www.bilibili.com/video/BV1Fi4y1S7ix/?p=43&spm_id_from=pageDriver&vd_source=8ae ...
- vue3渲染函数(h函数)的变化
vue3 渲染函数(h函数)的更改 h函数的更改总结 1==>h 现在全局导入,而不是作为参数传递给渲染函数 2==>渲染函数参数更改为在有状态组件和函数组件之间更加一致 3==>v ...
- 三十五、kubernetes NameSpace介绍
Kubernetes NameSpace 介绍 Kubernetes使用命名空间的概念帮助解决集群中在管理对象时的复杂性问题.命名空间允许将对象分组到一起,便于将它们作为一个单元进行筛选和控制.无论是 ...
- 从0到1搭建redis6.0.7
redis集群搭建 一.安装redis 源码安装: 1.下载源码包: wget http://download.redis.io/releases/redis-6.0.7.tar.gz 2.解压到指定 ...
- OpenCvSharp的安装和使用
OpencvSharp是opencv的C#版本,使用习惯了opencv的人学起OpenCvSharp会很容易上手,看了网上很多的安装方式,最后我感觉还是自己去下载安装包的方式最简单,通过Nuget的方 ...
- 【Java并发001】使用级别:线程相关知识
一.前言 本文介绍Java线程相关知识(不包括线程同步+线程通信,这个内容在笔者的另一篇博客中介绍过了),包括:线程生命周期.线程优先级.线程礼让.后台线程.联合线程. 二.线程生命周期 2.1 引子 ...
- i春秋broken
点开一个附带超链接的网页,直接点击file跳转到broken网页 网页里面是一个jsfuck代码 Jsfuck代码的执行方法 ①复制 ②打开firefox浏览器 ③按下F12 ④选择上方的控制台 ⑤在 ...
- dom xss->半自动化
前几天看了两篇文章,觉得很不错,写一笔,就当笔记记录. 第一篇文章:https://jinone.github.io/bugbounty-dom-xss/ 作者写了自己通过自动化挖dom xss,差不 ...