5 个不稳定版本

0.3.0 2023年10月28日
0.2.0 2023年9月25日
0.1.2 2023年6月18日
0.1.1 2023年6月15日
0.1.0 2023年6月14日

#4#example

每月 23 次下载

MIT 许可证

760KB
1.5K SLoC

包含 (WOFF 字体, 150KB) static/webfonts/fa-solid-900.woff2, (WOFF 字体, 110KB) static/webfonts/fa-brands-400.woff2, (WOFF 字体, 25KB) static/webfonts/fa-regular-400.woff2, (WOFF 字体, 5KB) static/webfonts/fa-v4compatibility.woff2

Terracotta

该仓库提供了一个基于Axum的样板Web服务器应用程序,旨在作为构建Web应用程序和API的基础和跳板。目的是将其用作新项目的模板。

选择Teracotta这个名字是因为它的颜色是锈色的,而粘土代表可以塑造成不同形状的东西。

它旨在易于使用和理解,易于设置和扩展,易于部署。

Terracotta存在于crates.io上的crate中,以建立存在感并提高可见性和知名度,因为计划添加命令行功能以帮助设置。它不打算用作库,也没有以库的形式发布。(有关更多信息,请参阅使用部分。)在使用它作为新项目的基础之前,运行它并查看它的工作情况可能也很有用。

Terracotta是在Axum的完整示例不足的情况下创建的,许多教程过时,缺少重要元素,或者只是完全错误。您可能不需要提供的一切——您也可能不赞成某些部分的实现方式——但如果您想节省时间,这是一个不错的起点!

本README中的主要部分包括

其他值得注意的文档包括

功能

值得注意的主要高层次要点包括

  • 简单的代码库布局
  • 开箱即用的完整且最小化Web应用程序
  • 易于扩展和构建
  • 使用Tokio Hyper的高性能异步HTTP服务器
  • 基于强大且易于使用的Web框架Axum
  • 从配置文件和环境变量中配置使用Figment
  • 使用Tokio Tracing记录HTTP请求和事件
  • 使用Tera模板引擎实现的模板
  • 静态文件处理
  • 可以以受保护或公开的方式提供静态文件
  • 除了预编译的二进制文件外,还可以使用本地文件补充和覆盖静态资源(可配置)
  • 为了内存效率,流式传输大型静态文件
  • 单文件部署——所有资源集成(可选和可配置)
  • 使用Bulma CSS框架构建CSS基础
  • 使用Font Awesome图标
  • 使用会话和基于配置的用户列表进行简单认证
  • 登录页面、公开和受保护的路由、登出功能
  • 健康检查API端点
  • 收集全面的应用程序统计数据,并提供API端点进行报告
  • 优雅地处理404和500 HTTP错误
  • 优雅地处理运行时应用程序错误
  • 完整的OpenAPI文档

认证

Terracotta拥有一个自定义的认证系统,以展示如何实现基于会话的基本设置。虽然将用户列表以纯文本形式存储在服务器上对小项目或实验来说是可行的,但强烈建议将凭据安全地存储在数据库中。这目前不在项目的范围内,有多个原因。

在实际系统中,您可能还希望将会话存储在数据库中而不是内存中。

值得注意的是,实施的模式是最理想、最适合为浏览器提供HTML的应用程序。如果您正在创建API,则可能需要更改一些行为,以便返回HTTP状态代码来告知客户端请求未授权,而不是发送登录页面。同样,您可能还希望实现JWT或类似功能。这目前不在项目的范围内,部分原因是因为有各种选项可供选择。

认证系统已设置,以便轻松配置路由为公开或受保护,并完全实现了包括登录页面、登出操作以及处理认证旅程的每个部分和可能的情况。

统计数据

Terracotta收集了关于应用程序的广泛统计数据,并提供了一些API端点来访问它们。这些数据旨在由监控系统使用,并为查看应用程序的活动提供简单的方式。

尽管收集了全面的测量数据,但这种方法性能极高,并且旨在尽可能高效。它还旨在易于扩展,可以向系统中添加新的统计数据。有一个中央统计数据队列和广播系统,以及用于间隔历史的循环缓冲区和一个时钟来保持一切更新。

统计数据数据以摘要形式、按测量历史记录的形式以及实时WebSocket事件流的形式提供。

错误处理

Terracotta对处理错误有意见,包括HTTP错误和“真实”(Rust)错误。这可以作为建立或更改的基础。

数据库

Terracotta有意识地不包括任何类型的数据库集成。有如此多的选择,以及如此多的crates可以选择,因此最好由应用程序开发者来决定。数据库交互非常直接,因此这是一个简单的添加。

模板

Tera的选择不太可能引起任何人的不满,但如果有一个首选选项,则很容易更改或删除。Tera以略微有意见的方式实现,但应该清楚已经更改了哪些默认设置以及如何更改。

使用方法

Terracotta仓库被设计为可以作为新项目的模板使用,然后进行定制和扩展。您自然会重命名项目并按需调整,随着您实现自己的功能,合并任何上游更改将变得越来越困难。因此,最好将其视为仅作为一个起点和一个升级参考,而不是一个持续的贡献来源。

请注意,Terracotta并非设计为库使用,它存在于crates.io上作为二进制文件。这是为了建立存在感,同时也有计划添加命令行工具。

有关基于Terracotta开发项目的信息,请参阅开发者文档

设置

设置Terracotta项目的步骤简单且标准。您需要一个合理更新的Rust环境,在一台Linux机器上。目前没有特殊要求,除了解决构建标准Rust项目所需的要求外。

请注意,以下说明是用于自己构建应用程序,这通常是在使用Terracotta作为新项目的模板的情况下。在这种情况下,这些步骤也适用于您的项目。您还可以使用以下命令下载crate:cargo install terracotta,这将从crates.io安装最新版本的Terracotta,但目前这并不特别有用,除了让您能够查看默认运行的程序,而无需克隆存储库并自行构建,以查看您是否喜欢它。有关使用Terracotta作为模板创建项目的更多信息,请参阅入门部分。

环境

关于您选择的环境,有一些要点需要注意

  • Debian和Ubuntu是首选的Linux发行版,尽管其他发行版也应该工作得很好,因为没有特殊要求。
  • 在Windows上本地运行不是目标或测试对象,也没有计划支持它,因此尽管它可能工作,但也可能不工作。在WSL上运行没问题,并且是Windows上推荐的方式。
  • 在MacOS上本地运行未经测试,尽管没有已知的技术原因说明它为什么不能工作。

通常,您将使用rustup设置Rust,这是推荐安装Rust的方式。目标是stable工具链,因为重点是稳定性和正确性,而不是尖端特性。

安装Rust后,您可以使用cargo build来构建项目。这将下载并编译所有依赖项,并构建项目。然后您可以使用cargo run运行项目。

配置

使用TOML文件配置Terracotta。默认配置文件是Config.toml,应放置在二进制文件相同的目录中。配置设置(和文件)是可选的,如果没有提供,Terracotta将为所有配置选项使用默认值。

还可以从命令行以环境变量的形式传递配置参数。环境变量优先于配置文件选项。

一般选项

以下选项应指定,不带任何标题

  • host - 要监听的宿主。默认为127.0.0.1
  • port - 要监听的端口。默认为 8000
  • logdir - 存储日志文件的目录。默认为 log
  • title - 应用的标题。默认为 Terracotta

如下所示

host   = "127.0.0.1"
port   = 8000
logdir = "log"
title  = "Terracotta"

本地加载选项

默认情况下,所有资源都嵌入到二进制文件中,并从那里提供服务。这是运行应用的最有效方式,但也可以从本地文件系统加载资源,这在开发和测试以及存在大型内容文件时非常有用。

可以补充或覆盖静态资产。静态资产分为受保护和公开两类。

以下选项应在 [local_loading] 节下指定

  • protected_assets - 受保护静态资产的加载行为。
  • public_assets - 公开静态资产的加载行为。

每个选项可以是以下值之一

  • Deny - 禁止从本地文件系统加载。这是所有选项的默认值。
  • Supplement - 如果嵌入的资源不存在,则从本地文件系统加载。
  • Override - 如果本地文件系统中存在,则从本地文件系统加载,否则从嵌入的资源加载。

如下所示

[local_loading]
protected_assets = "Override"   # default is "Deny"
public_assets    = "Override"   # default is "Deny"

对于允许从本地文件系统加载的选项,以下选项可以在 [local_paths] 节下指定

  • protected_assets - 受保护静态资产的路由。默认为 content
  • public_assets - 公开静态资产的路由。默认为 static

如下所示

[local_paths]
protected_assets = "content"
public_assets    = "static"

以下是一个示例,rustacean-flat-happy.png,如果使用示例配置文件中的设置,可以通过 https://127.0.0.1:8000/rustacean-flat-happy.png 访问。这是一个受保护资产,因此只会提供给已登录用户。

静态文件选项

当请求静态文件时,它们被服务的方式取决于它们的来源和大小。所有嵌入到二进制文件中的文件都直接从内存中服务,因此这些选项不适用于它们。从本地文件系统加载的文件,如果足够小,则一次性加载到内存并服务,但超过一定(可配置)大小后,会流式传输到客户端。

流缓冲区和读取缓冲区的大小对性能至关重要,较小的缓冲区会极大地影响下载速度。默认值已经根据广泛的测试精心选择,通常不需要更改。然而,在用户众多而大型文件很少的系统上,可能 值得减小缓冲区大小以减少请求这些文件时的内存使用,而在用户很少而大型文件众多的系统上,可能 值得增加缓冲区大小以提高吞吐量。然而,选择的价值已经在最佳速度的5-10%以内,因此任何增加都应谨慎进行。更有可能的是,在用户众多且大型文件众多的繁忙系统上,可能需要稍微减小一些,因为内存使用可能会成为问题,而每个下载的原始速度则成为次要考虑因素。

以下选项应在 [static_files] 节下指定

  • stream_threshold - 文件大小,以KB为单位,超过此大小将会被流式传输到客户端。默认为 1000 (1MiB)。
  • stream_buffer - 流式传输文件时使用的流缓冲区大小,以KB为单位。默认为 256 (256KB)。
  • read_buffer - 流式传输文件时使用的读取缓冲区大小,以KB为单位。默认为 128 (128KB)。

这些选项都接受一个整数值。

如下所示

[static_files]
stream_threshold = 1000 # 1MiB — files above this size will be streamed
stream_buffer    = 256  # 256KB
read_buffer      = 128  # 128KB

用户列表

可以在 [users] 标题下指定用户凭据列表

  • username: password - 用户名作为键,密码作为值。

如下所示

[users]
joe = "1a2b3c"

这是一个简单的用户名/密码对列表,其中用户名是键,密码是值。密码以纯文本形式存储,因此请考虑其安全影响(理想情况下,您会实施与您首选数据库的集成)。用户名和密码均为大小写敏感。

运行

可以使用 cargo run 命令运行Terracotta,或者直接运行编译的二进制文件。服务器默认监听8000端口,并从 static 目录提供内容,以及您定义的任何请求处理器。static 目录包含要提供的服务器静态文件。

测试

您可以使用 cargo test 运行测试套件。这将运行所有单元和集成测试。

请注意,目前针对此项目专门编写的测试非常少,因为它主要是由Rust生态系统中的其他crate组合而成的。现有测试旨在作为方法的示例,并不全面。在项目更加成熟且已明确识别出可测试的内容后,可能会添加更多测试。

文档

这是第一个版本,所以目前还没有太多文档。当Axum 0.7发布时,可能会有些变化,因此文档将在Terracotta更新以兼容后编写。

您可以使用 cargo doc 构建开发者文档。这将生成HTML文件,并将它们放置在 target/doc。您可以通过在浏览器中打开 target/doc/terracotta/index.html 来查看文档。

为本地开发构建文档还将为您提供源代码的链接。

部署

构建

您可以使用 cargo build --release 在发布模式下构建项目。所需的所有部署内容都将包含在生成的单个二进制文件中。建议在部署之前在可执行文件上运行 upx,以减小文件大小。

您可以选择使用本地文件系统中的额外文件补充编译的系统,如上 本地加载选项 部分所述。

生成的二进制文件然后可以复制到部署环境,并直接运行。这通常是在 Docker 或 Kubernetes 容器中。

示例

典型的构建脚本可能看起来像这样

cargo build --release
upx --best target/release/terracotta
scp target/release/terracotta you@yourserver:/path/to/deployment/directory

Docker

常见的部署场景是使用Docker。Terracotta 仓库包含一个Dockerfile,可用于构建 Docker 镜像。这个镜像基于Alpine,因此非常小。它还使用了多阶段构建,所以最终的镜像更小。

值得注意的是,Alpine 构建使用的是musl C 库,与大多数其他 Linux 发行版和 Docker 镜像使用的glibc C 库不兼容。使用 Alpine 的优点是生成的镜像非常小,且所有内容都是静态编译的。如果您遇到任何兼容性问题,则可能需要使用基于glibcdistroless构建。

可以使用以下命令构建 Docker 镜像

docker build -t terracotta .

默认情况下,这将构建一个发布镜像,并使用upx压缩二进制文件。该设置优化了可执行速度、构建速度和镜像大小。

配置文件

您可以通过向docker build命令传递--build-arg profile=dev选项来指定开发配置文件。这将构建一个未压缩的镜像,优化构建速度但不是镜像大小。

构建参数

此外,还有两个其他构建参数可以传递

  • upx - 是否使用upx压缩二进制文件。默认为1。指定0以禁用压缩。
  • cargo-opts - 传递给cargo build的附加选项,例如--build-arg cargo_opts="--config opt-level=z"

运行

需要注意的是,需要将服务的主机 IP 设置为0.0.0.0以允许外部流量连接。换句话说,在 Docker 设置中,Config.toml 文件中的host条目应设置为"0.0.0.0"

host   = "0.0.0.0"
port   = 8000

默认情况下,Terracotta 将在端口8000上运行,并且这是由Dockerfile所期望的。因此,建议在Config.toml文件中保持此配置(或省略),而不是使用端口映射将容器端口映射到主机端口。这可以通过调用docker run命令时指定-p选项来实现,例如

docker run -p 8000:8000 terracotta

这将在主机上使 Terracotta 服务器在端口8000上可用,因此,在该机器上,您可以通过浏览器访问https://127.0.0.1:8000http://127.0.0.1:8000

如果您在不同的端口上运行 Terracotta,则需要在该Dockerfile中指定该端口。

可以将卷挂载到Docker容器中,以便访问本地文件。这有助于开发,也适用于提供额外内容和静态资源。以下卷可用:

  • /usr/src/content - 受保护的静态资源。
  • /usr/src/static - 公共静态资源。

可以通过上述描述的本地加载选项覆盖这些路径和它们的选项。

要挂载卷,请在调用docker run命令时使用-v选项,例如:

docker run -v /path/to/content:/usr/src/content:ro terracotta

建议指定ro(只读)选项,如上所示,因为没有理由让Terracotta需要写入内容文件。

示例

默认构建,生成压缩的发布镜像

docker build -t terracotta .

默认构建,生成未压缩的发布镜像

docker build -t terracotta --build-arg upx=0 .

开发构建,生成未压缩的开发镜像

docker build -t terracotta --build-arg profile=dev .

调整发布构建的opt-level

docker build -t terracotta --build-arg cargo_opts="--config opt-level=z" .

运行镜像

docker run terracotta

运行镜像并暴露默认端口

docker run -p 8000:8000 terracotta

挂载卷

docker run \
  -v /path/to/content:/usr/src/content:ro \
  -v /path/to/assets:/usr/src/static:ro \
  terracotta

致谢

由于该项目是用Rust编写的,因此使用Rust标志作为默认标志。此标志在CC-BY (Creative Commons Attribution)许可免费使用

使用螃蟹费里斯的图像(Rust吉祥物)作为受保护内容的示例。此图像来源于rustacean.net,属于公共领域,因此可以自由使用。

该项目使用Bulma CSS框架,该框架在发布MIT许可下,并且可以无限制地使用。

Font Awesome图标在发布CC-BY (Creative Commons Attribution)许可下,以及SIL OFL (Open Font License)下的网络字体。它们可以免费使用,包括用于显示它们的CSS代码,该代码在MIT许可下发布。

依赖项

~33–48MB
~883K SLoC