前几天用 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 和配置文件
  • 在后台运行
  • 零停机时间配置重载

先决条件

  • 已安装 caddycurl(安装 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 常用功能

  1. 静态文件访问
  2. 反向代理
  3. 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的外部访问
  • 已安装 caddycurl

在本教程中,将 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 吸引我的地方:

  1. 自动申请续约证书
  2. 简单命令的 Caddyfile
  3. Go 编写,Caddy 为所有主流平台编译,并且没有运行时依赖项。

参考资料

三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.

Caddy-用Go写的新一代可扩展WebServer的更多相关文章

  1. 哇塞,原来自己写 Google Chrome 浏览器扩展(插件)这么容易!

    1. 首先新建一个记事本,命名为 manifest.json,这是写 Google Chrome 浏览器扩展必须的文件 { "manifest_version": 2, " ...

  2. 多年前写的文本框扩展控件(有ValueChanging事件等),已放github

    本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 阅读目录 介绍 起因 代码 使用 GitHub ...

  3. GoWorld – 用Golang写一个分布式可扩展、可热更的游戏服务器

    GoWorld代码:https://github.com/xiaonanln/goworld Golang具有运行效率高.内存安全等优良特性,因此是非常适合用来进行服务器开发.使用Golang开发游戏 ...

  4. php内核分析(七)-扩展

    这里阅读的php版本为PHP-7.1.0 RC3,阅读代码的平台为linux. 我们研究下反射这个扩展. 反射这个扩展目录是存在在:ext/reflection.其实里面的代码很简单.一个.h文件,一 ...

  5. 利用jQuery来扩展一个瀑布流插件

      简单了解jQuery.fn.extend() jQuery.fn.extend()函数用于为jQuery扩展一个或多个实例属性和方法(主要用于扩展方法). (截图来自jQuery文档) 为了更清晰 ...

  6. 【转发】NPAPI学习(Firefox和Chrome扩展开发 )

    NPAPI学习(Firefox和Chrome扩展开发 ) 2011-11-08 14:41:02 by [6yang], 1172 visits, 收藏 | 返回 Firefox和Chrome扩展开发 ...

  7. FME中Cass扩展属性转Shp的方法

    问题:真受不了CAD中的注记,只能方便显示,难于数据交互.好在Cass把属性信息基本写在扩展属性中,但显示又成问题了.此事难两全!我们通过查看实体属性,需要把宗地界线的扩展属性提取出来.即组码为-3, ...

  8. MVC采用HtmlHelper扩展和Filter封装验证码的功能

    最近因为有个项目除了登录还有其他很多地方需要用到验证码的功能,所以想到了采用HtmlHelper和ActionFilter封装一个验证码的功能,以便能够重复调用.封装好以后调用很方便,只需在View中 ...

  9. 非常好!!!【从头开始写操作系统系列】实现一个-GDT(1)【转】

    转自:http://blog.csdn.net/luoyhang003/article/details/47338019 权声明:本文为博主原创文章,未经博主允许不得转载.(文章来源:http://b ...

  10. (转)可收缩、扩展的TextView

    在一些应用中,比如腾讯的应用市场APP应用宝,关于某款应用的介绍文字,如果介绍文字过长,那么不是全部展现出来,而是显示三四行的开始部分(摘要),预知全部的内容,用户点击展开按钮即可查阅全部内容.这样的 ...

随机推荐

  1. 用昇腾AI护航“井下安全”

    摘要:基于CANN(异构计算架构)打造的"智能矿山安全生产管理平台",能够更便捷和更高效地服务于更多矿山安全生产建设. 本文分享自华为云社区<华为携手云话科技助力矿山智能化, ...

  2. 物理服务器做系统盘centos

    linux系统跟windows系统都是操作系统的一种,安装的方法也较多,一样可以通过制作u盘启动盘给linux系统安装.那么具体是如何安装linux?下面就给大家演示下u盘启动盘安装linux系统教程 ...

  3. 如何解读Linux Kernel OOPS信息

    OOPS信息解读 root@firefly:~/mnt/module# insmod oops_module.ko [ 867.140514] Unable to handle kernel NULL ...

  4. VUE3系列---nvm环境搭建

    nvm node version manager:node版本管理工具 可以用来管理多个node版本 1.下载 下载地址:https://github.com/coreybutler/nvm-wind ...

  5. i春秋Fuzz

    点开只有三个单词plz fuzz parameter 大概意思就是让我们疯狂尝试参数... 我们通过url尝试传入参数 ?user=123 ?name=123 ?username=123 ?id=12 ...

  6. Android网络请求(终) 网络请求框架Retrofit

    Android网络请求(终) 网络请求框架Retrofit Retrofit底层是由OkHttp封装的,Retrofit对于注解的使用十分频繁,所以不了解注解的同学们可以去查查资料什么的. 这里有一个 ...

  7. 修改Listen 1源码的一点心得

    注:本文只作为技术交流 首先感谢听1的作者写出这么强大的音乐播放器!! 软件首页地址:点击打开链接 软件的github上上上地址:点击打开链接 软件唯一让我美中不足的就是不能下载,这可能是作者考虑到了 ...

  8. MySQL DATE_SUB查询工龄大于35的员工信息

    #(11) 查询工龄大于或等于35年的员工信息.SELECT * FROM emp e WHERE e.HIREDATE<=DATE_SUB(SYSDATE(),INTERVAL 35 YEAR ...

  9. day22 存储过程 & 游标 & 事务

    存储过程 是一种在数据库中存储复杂程序(复杂sql语句),以便外部程序调用的一种数据库对象 存储过程是为了完成特定功能的sql语句集,经编译创建并保存在数据库中,用户可以通过指定存储过程的名字并给定参 ...

  10. JavaScript笔记之面向对象

    面向对象 了解构造函数原型对象的语法特征,掌握 JavaScript 中面向对象编程的实现方式,基于面向对象编程思想实现 DOM 操作的封装. 了解面向对象编程的一般特征 掌握基于构造函数原型对象的逻 ...