usetrmnl/terminus
GitHub: usetrmnl/terminus
TRMNL 电子墨水屏设备的自托管管理服务器,提供隐私优先的本地化部署方案。
Stars: 381 | Forks: 78
:toc: macro
:toclevels: 5
:figure-caption!:
:chrome_link: link:https://www.google.com/chrome[Google Chrome]
:core_api_link: link:https://trmnl.com/api-docs/index.html[Core API]
:docker_doc_link: link:doc/docker.adoc[Docker]
:docker_link: link:https://www.docker.com[Docker]
:dragonfly_link: link:https://www.dragonflydb.io[Dragonfly]
:esbuild_link: link:https://esbuild.github.io[esbuild]
:firmware_link: link:https://github.com/usetrmnl/trmnl-firmware[Firmware]
:git_link: link:https://git-scm.com[Git]
:hadolint_link: link:https://github.com/hadolint/hadolint[Haskell Dockerfile Linter]
:hanami_link: link:https://hanamirb.org[Hanami]
:htmx_link: link:https://htmx.org[htmx]
:imagemagick_link: link:https://imagemagick.org[ImageMagick]
:jobs_link: link:doc/jobs.adoc[Jobs]
:milestoner_link: link:https://alchemists.io/projects/milestoner[Milestoner]
:node_link: link:https://nodejs.org[Node]
:overmind_link: link:https://github.com/DarthSim/overmind[Overmind]
:postgres_link: link:https://www.postgresql.org[PostgreSQL]
:puma_link: link:https://puma.io[Puma]
:rack_attack_link: link:https://github.com/rack/rack-attack[Rack Attack]
:raspberry_pi_link: link:doc/raspberry_pi.adoc[Raspberry PI]
:redis_link: link:https://redis.io[Redis]
:render_link: link:https://render.com[Render]
:rodauth_link: link:https://rodauth.jeremyevans.net[Rodauth]
:ruby_link: link:https://www.ruby-lang.org[Ruby]
:sidekiq_link: link:https://github.com/sidekiq/sidekiq[Sidekiq]
:trmnl_link: link:https://trmnl.com[TRMNL]
:unbrickable_pledge_link: link:https://trmnl.com/blog/the-unbrickable-pledge[Unbrickable Pledge]
:valkey_link: link:https://valkey.io[Valkey]
:yjit_link: link:https://docs.ruby-lang.org/en/master/jit/yjit_md.html[YJIT]
:youtube_link: link:https://www.youtube.com/@useTRMNL[YouTube]
= Terminus
image:https://dl.circleci.com/status-badge/img/gh/usetrmnl/terminus/tree/main.svg?style=svg[CircleCI, link=https://dl.circleci.com/status-badge/redirect/gh/usetrmnl/terminus/tree/main]
image:https://github.com/usetrmnl/terminus/actions/workflows/docker.yml/badge.svg[Docker, link="https://github.com/usetrmnl/terminus/actions"]
image:https://alchemists.io/images/projects/caliber/coverage.svg[Code Coverage, link=https://dl.circleci.com/status-badge/redirect/gh/usetrmnl/terminus/tree/main, width=139.1, height=20]
image:https://alchemists.io/images/badges/style.svg[Style, link=https://alchemists.io/projects/caliber, width=81, height=20]
Terminus 是一个 {ruby_link}/{hanami_link} Web 服务器,允许您管理运行在本地网络或托管云上的 {trmnl_link} 设备。这是我们的旗舰 BYOS 实现,旨在与我们的 {trmnl_link} Core 服务器兼容,但又_有所不同_,因为这个开源解决方案提供了 Core 应用程序中无法实现的功能。
有关 TRMNL 设备的快速介绍,请查看以下 9to5Mac 概览:
link:https://www.youtube.com/watch?v=BxMRP_ASa-s[image:https://img.youtube.com/vi/BxMRP_ASa-s/maxresdefault.jpg[YouTube Video,width=960,height=540]]
image:https://render.com/images/deploy-to-render-button.svg[Deploy to Render,link=https://render.com/deploy]
⚠️ 这是一个 Beta 软件,因为我们尚未达到 1.0.0 状态。这意味着——虽然我们努力将需要您付出精力的更改数量降至最低——但有时更改是不可避免的。
toc::[]
== 功能
* 提供隐私优先的功能,让您能够运行自己的私人服务器、网络和设备。您拥有整个堆栈和数据。 🎉
* 基于 {ruby_link} 和 {hanami_link} 构建。
* 使用 {esbuild_link} 进行资产管理。
* 使用 {htmx_link} 构建 Hypermedia 驱动的用户界面。
* 使用 {imagemagick_link} 进行图像处理。
* 使用 {overmind_link} 运行多个进程。
* 使用 {postgres_link} 作为数据库。
* 使用 {puma_link} 作为服务器。
* 使用 {rodauth_link} 进行身份验证。
* 使用 {sidekiq_link} 处理后台作业。
* 使用 {valkey_link} 作为键/值缓存。
* 支持 {yjit_link}。
* 支持 {docker_link}。
* 支持 {trmnl_link} 设备。
以下是一个高级概览,您可以用它来比较/对比,以便决定使用这个“自建服务器 (BYOS)”实现还是我们的 link:https://trmnl.com[托管] 解决方案。
*图例*
* ⚪️ 计划中。
* 🟢 支持。
* 🟡 部分支持。
* 🔴 不支持、未实现或不适用。
*矩阵*
以下记录了此实现中支持的功能,这些功能与我们的 {trmnl_link} Core 服务器类似。虽然我们的目标是与 Core 兼容,但在外观、感觉和行为上会略有不同。
[options="header"]
|===
| | Terminus | Hosted
| Dashboard | 🟢 | 🟢
| Auto-Provisioning | 🟢 | 🟢
| Devices | 🟢 | 🟢
| JSON Data API | 🟢 | 🟢
| Image Previews | 🟢 | 🟢
| Playlists | 🟢 | 🟢
| Plugins | 🟡 | 🟢
| Account Management | 🟢 | 🟢
| Docker | 🟢 | 🔴
|===
== 需求
* {git_link}。
* {ruby_link}。
* {hanami_link}。
* {node_link}。
* {postgres_link}。
* {valkey_link}: 如果需要,可以替换为 {redis_link} 或 {dragonfly_link}。
* {hadolint_link}(可选,用于开发):用于 `Dockerfile` lint 检查。
* {chrome_link}(可选,用于开发):用于通过 headless 浏览器生成屏幕。
* {overmind_link}(可选,用于开发):使用您的 `Procfile` 启动进程。
* {docker_link}(仅在仅使用 Ruby 时可选)。
* {trmnl_link} 设备(可选,您可以使用虚拟设备)。
== 快速开始
要使用 {docker_link} 在本地机器上立即启动 Terminus,请运行:
## [source,bash]
## curl https://raw.githubusercontent.com/usetrmnl/terminus/refs/heads/main/scripts/docker/quick.sh | bash
启动后,在浏览器中打开 `http://localhost:2300`,然后点击 _注册_ 链接以注册并登录系统。
⚠️ 此脚本不是幂等的,这意味着您不能多次运行它,因为您的数据库凭据每次都会不同。这仅用于快速启动和运行以探索功能集,而非永久使用。如需永久使用,请参阅 link:doc/docker.adoc[Docker] 文档。
== 设置
要为本地开发设置此项目,请运行:
## [source,bash]
## git clone https://github.com/usetrmnl/terminus
cd terminus
bin/setup
💡 设置脚本是幂等的,因此您可以多次运行它而不会造成损害。要重建由设置脚本管理的文件,请删除所需的文件并重新运行 setup 以重新创建。
== 升级
要为本地开发升级此项目,请运行:
## [source,bash]
## cd terminus
bin/upgrade
注意输出中是否需要解决任何更改。否则,如果没有检测到更改,您就准备就绪了。
== 使用
要启动服务器,请运行:
## [source,bash]
# Development
overmind start --port-step 10 --procfile Procfile.dev --can-die assets,migrate
# Production
## overmind start --port-step 10 --can-die assets,migrate
要查看应用程序,请使用以下任一方式:
* *安全*: https://localhost:2443
* *非安全*: http://localhost:2300
在浏览器中,您可以点击 _注册_ 链接以注册并登录系统。
=== 配置
您可以使用多个环境变量通过更新设置期间为您创建的 `.env` 文件来自定义行为。它们是:
* `API_ACCESS_TOKEN_PERIOD`: 用于设置 JWT 访问令牌在需要刷新之前保持有效的时间量(以秒为单位)。这仅在使用 link:doc/api.adoc[Server APIs] 时是必需的。默认值:1,800 秒(30 分钟)。
* `APP_SECRET`: 用于会话、cookie 和跨站请求伪造 (CSRF) 保护。这在设置期间会自动为您创建,但建议您使用自己的安全值进行更新。
* `APP_SETUP`: 运行设置/更新步骤(即资产编译、数据库迁移等)。仅由 Docker 通过 `entrypoint` 脚本使用。默认值:`nil`,但对于 Web 服务为 `true`。
* `API_URI`: 用于将设备连接到此服务器或通过 link:doc/docker.adoc[Docker]。默认为您主机的 IP 地址和端口。这假设您将设备直接连接到运行 Terminus 的同一服务器。如果情况并非如此,并且您在设备和 Terminus 之间使用反向代理、DNS 或任何服务/层,则需要将此值更新为您的主机。例如,如果您的主机是 `http://demo.io`,则此值必须是 `http://demo.io`。这包括通过 TRMNL 强制门户 WiFi 更新您的设备,以使用 `http://demo.io` 作为您的自定义主机。如何配置 `http://demo.io` 以解析到您运行 Terminus 的服务器取决于您。您的设备(以及此值)关心的只是设备向其发出 API 请求的外部主机(或 IP 和端口)(它们必须相同)。
* `BROWSER`: 用于在为设备创建屏幕时配置 headless 浏览器行为。必须是 JSON 对象。默认值:`'{"js_errors": true, "process_timeout": 10, "timeout": 10}'`。其他键将被忽略。有关更多详细信息,请参阅 link:https://github.com/rubycdp/ferrum#customization[Ferrum Customization Documentation]。
* `CERTIFICATE_URLS`: 定义以逗号分隔的 CA 证书 URL 列表,这些证书将自动安装为受信任的证书。示例:`"https://example.io/ca1.crt,https://example.org/ca2.pem"` 仅由 {docker_doc_link} 使用。
* `DATABASE_NAME`: 定义您的数据库名称。仅由 {docker_doc_link} 使用。默认值:`terminus`。
* `DATABASE_PASSWORD`: 定义您的数据库密码。仅由 {docker_doc_link} 使用。默认值:(设置期间为您自动生成)。
* `DATABASE_PORT`: 定义您的数据库端口。仅由 {docker_doc_link} 使用。默认值:`5432`。
* `DATABASE_URL`: 基于 `+DATABASE_*+` 设置定义完整 URL。这会在设置期间自动为您配置。有关详细信息,请参阅您的 `+.env*+` 文件。
* `DATABASE_URL`: 连接到您的 {postgres_link} 数据库所必需的。可以通过更改您运行 `bin/setup` 时创建的 `.env.development` 或 `.env.test` 文件中的值来自定义。
* `DATABASE_USER`: 定义您的数据库用户。仅由 {docker_doc_link} 使用。默认值:`terminus`。
* `FIRMWARE_POLLER`: 启用/禁用固件轮询。有关详细信息,请参阅 {jobs_link}。默认为启用。
* `HANAMI_PORT`: 在本地或通过 {docker_doc_link} 运行应用程序时的默认端口。使用 Docker 时,这用于内部和外部端口映射。
* `KEYVALUE_DATABASE`: 定义您的数据库 ID。仅由 {docker_doc_link} 使用。默认值:`0`。
* `KEYVALUE_PASSWORD`: 定义您的密码。仅由 {docker_doc_link} 使用。默认值:(设置期间为您自动生成)。
* `KEYVALUE_PORT`: 定义您的端口。仅由 {docker_doc_link} 使用。默认值:`6379`。
* `KEYVALUE_URL`: 基于上述 `+KEYVALUE_*+` 设置定义完整 URL。这会在设置期间自动为您配置。有关详细信息,请参阅您的 `+.env*+` 文件。
* `MODEL_POLLER`: 启用/禁用模型轮询。有关详细信息,请参阅 {jobs_link}。默认为启用。
* `RACK_ATTACK_ALLOWED_SUBNETS`: 定义允许连接到此服务器的 {rack_attack} 子网,这有助于在您的设备与此应用程序之间添加 DNS、反向代理或 VPN 等,以便您可以根据需要使用此环境变量添加更多子网。这接受单个子网/IP 或数组 —— 无空格 —— 作为值的子网/IP。示例:"111.111.111.111,150.120.0.0/16"。或者,您可以通过从 `config/app.rb` 中删除 `config.middleware.use Rack::Attack` 行来完全禁用 Rack Attack,或通过 `config/initializers/rack_attack.rb` 文件自定义 Rack Attack。这些方法中的任何一种都将允许您正确配置服务层,以便您的设备可以与此服务器通信。默认情况下,允许以下子网:`10.0.0.0/8`、`172.16.0.0/12`、`192.168.0.0/16`、`127.0.0.1` 和 `::1`。
* `SENSORS_PATH`: 写入传感器信息的路径。有关详细信息,请参阅 {raspberry_pi_link}。默认值:`public/sensors.json`。
* `SCREEN_POLLER`: 启用/禁用模型轮询。有关详细信息,请参阅 {jobs_link}。默认为启用。
=== 用户
首次启动此应用程序时,将没有用户。第一位注册的用户将自动获得 _已验证_ 身份以及对系统的完全访问权限。所有后续用户将被标记为 _未验证_,并且必须手动 _验证_ 才能访问系统。将来,将为单个用户、角色和权限提供更细粒度的控制。
此外,登录后,您可以按以下方式管理您的设置:
* 访问 `/me/login` 以更新您的电子邮件地址。
* 访问 `/me/password` 以更新您的密码。
* 访问 `/me/remember` 以启用、禁用或忘记是否应该记住您。
=== 设备
连接设备需要在手机上使用 WiFi 强制门户将您的 TRMNL 设备连接到运行此服务器的本地网络。您还可以通过 UI 和/或 API 删除您的设备,当设备下次发出 link:doc/api.adoc#display[Display API] 请求时,它将自动为您重新配置。有关更多信息(包括处理棘手的 WiFi 情况),请查看帮助指南:
* link:https://help.usetrmnl.com/en/articles/12263392-connect-your-device-to-terminus-byos[如何将您的设备连接到 Terminus]。
* link:https://help.usetrmnl.com/en/articles/11663377-setting-up-a-trmnl-on-tricky-wi-fi-situations[处理棘手的 Wi-Fi 情况]。
=== 固件
根据 {unbrickable_pledge_link},最新版本的 Terminus 始终支持最新版本的 {firmware_link}。如果您运行的是较旧的固件,则需要使用较旧版本的 Terminus。以下是应用了更改的固件版本历史的粗略细分,如果您有一段时间没有升级设备,这可能会导致问题:
* *Firmware 1.6.9*(及更低版本):由 Terminus link:https://github.com/usetrmnl/terminus/releases/tag/0.41.0[0.41.0] 及更低版本支持。
* *Firmware 1.6.10*(及更高版本):由 Terminus link:https://github.com/usetrmnl/terminus/releases/tag/0.42.0[0.42.0] 及更高版本支持。
=== 扩展
有关详细信息,请参阅 link:doc/extensions.adoc[Extensions] 文档。
=== 作业
有关 {sidekiq_link} worker 作业的详细信息,请参阅 {jobs_link} 文档。
=== API
有关详细信息,请参阅 link:doc/api.adoc[API] 文档。
=== Docker
有关详细信息,请参阅 link:doc/docker.adoc[Docker] 文档。
=== Raspberry Pi
有关详细信息,请参阅 {raspberry_pi_link} 文档。
=== Kubernetes
有关详细信息,请参阅 link:doc/kubernetes.adoc[Kubernetes] 文档。
=== Render
有关详细信息,请参阅 link:doc/render.adoc[Render] 文档。
== 开发
有关详细信息,请参阅 link:doc/development.adoc[Development] 文档。
== 测试
要测试,请运行:
## [source,bash]
## bin/rake
== 代码质量
代码质量是该项目工作的一个重要且至关重要的方面。以下 Gem 用于确保我们的工作保持一致和高质量:
* link:https://alchemists.io/projects/git-lint[Git Lint]: 确保 Git 提交消息写得良好且一致,以便进行代码审查,但也用于通过 {milestoner_link} 自动生成发行说明。
* link:https://alchemists.io/projects/caliber[Caliber]: 确保代码在风格、布局、性能、最佳实践等方面保持一致。
* link:https://github.com/troessner/reek[Reek]: 通过检测代码异味和反模式来增强 Caliber。
* link:https://rspec.info[RSpec]: 为单元和集成测试提供规范和测试框架。
* link:https://github.com/simplecov-ruby/simplecov[SimpleCov]: 每次构建时生成交互式报告。如果质量降至 95% 以下,将使构建失败。⚠️ 不幸的是,本文档顶部的徽章不是实时更新的,但相当准确。
要查看最新的代码覆盖率详细信息,请按照以下步骤操作:
* 访问 link:https://app.circleci.com/pipelines/github/usetrmnl/terminus?branch=main[Circle CI] 构建页面。
* 点击页面顶部的最新 "Success" 构建。
* 点击 `build`。
* 点击 ARTIFACTS。
* 点击 `coverage/index.html` 文件。
此时,您可以点击页面顶部的选项卡以检查组成此应用程序的各种命名空间。
== 版本
要查看此项目的所有版本和完整发布历史 —— 包括所有更改的详细说明 —— 请运行以下命令:
## [source,bash]
## cd terminus
gem install milestoner
milestoner build --max 1000 --format web
ruby -run -e httpd tmp/milestones --port 3030
open http://127.0.0.1:3030
我们正在努力跨多个项目(不仅仅是 Terminus)实现这一点,因为 {milestoner_link} 也会生成完整的联合发布说明源。这意味着将来,您将能够通过您的订阅源阅读器订阅所有更新。 🎉
💡 您也可以订阅我们的 {youtube_link} 频道,并不定期获取版本发布视频更新。
== 许可证
虽然本项目在宽松的 link:/LICENSE.adoc[MIT 许可证] 下分发,但我们坚信技术应服务于人类的最佳利益。我们创建此软件的初衷是使其用于造福个人和社区,而不是造成伤害。我们鼓励个人和组织考虑道德影响,并以尊重人权、促进公平和积极贡献社会的方式使用本项目。尽管我们无法根据 MIT 许可证在法律上限制使用,但我们请您加入我们,通过避免可能造成伤害、延续歧视或破坏人类尊严的应用,共同培育一个负责任的技术生态系统。技术最好用于丰富生活,让我们确保共同建设一个更美好的世界!
== 致谢
* 使用 link:https://alchemists.io/projects/hanamismith[Hanamismith] 构建。
* 由 {trmnl_link} 设计开发。
标签:BYOS, Docker, Dragonfly, esbuild, Hanami, HTMX, ImageMagick, PostgreSQL, Puma, Raspberry Pi, Redis, Rodauth, Ruby, Ruby on Rails替代方案, Sidekiq, Valkey, 信息仪表盘, 全栈应用, 内存执行, 安全防御评估, 开源硬件, 日程管理, 智能家居, 服务器部署, 测试用例, 物联网, 电子墨水屏, 知识库, 请求拦截