ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ntfy 源码开发指南:从零构建服务端、Web 应用与移动端客户端

ntfy 源码开发指南:从零构建服务端、Web 应用与移动端客户端 ntfy 源码开发指南从零构建服务端、Web 应用与移动端客户端【免费下载链接】ntfySend push notifications to your phone or desktop using PUT/POST项目地址: https://gitcode.com/GitHub_Trending/nt/ntfy本篇开发指南以 ntfy 官方开发文档docs/develop.md为主线面向希望为 ntfy 贡献代码或自建开发环境的开发者系统讲解 ntfy 项目的整体架构、开发环境搭建、make构建体系、服务端/Web App/文档的构建与调试流程以及 Android、iOS 客户端的源码构建方法。读完本文你将掌握 ntfy 从「拉取源码」到「跑通服务端、打包 Web 前端、构建移动端」的完整技术路径并能基于仓库源码理解底层构建机制如go:embed静态资源嵌入、cgo/SQLite 依赖、Vite 前端构建链。说明本文所有路径均以当前仓库根目录为基准涉及的具体实现均可在仓库内对应文件如 Makefile、main.go、server/server.go、web/package.json中核实。ntfy 服务端三大组件的代码结构ntfy 的代码库由三个技术栈截然不同的组件构成它们最终会被打包进同一个二进制文件主服务端 / 命令行客户端Go使用 Go 编写。入口在 main.go核心服务逻辑位于 server/server.go。服务端依赖 go-sqlite3 中确认github.com/mattn/go-sqlite3 v1.14.49。文档Python / MkDocs由 MkDocs构建配置见 mkdocs.yml。Web 应用React / MUI / Vite前端源码位于 web/使用 React 与 MUIMaterial UI。从当前仓库 web/package.json 可以看出生产构建由 Vite 完成build: vite builddevDependencies 中声明了vite与vitejs/plugin-react。如果你要修改 Web 应用需要安装 nodejsnpm及其全部依赖。在构建阶段Web 应用与文档的产物会被复制进服务端源码目录通过 Go 的go:embed嵌入最终二进制——这正是 server/server.go 中的//go:embed site与//go:embed docs所做的事情分别对应 Web 应用目录webSiteDir /site与文档目录。代码导航速查代码相关main.go — CLI 主入口同时承载服务端serve与客户端publish、subscribe等命令。从源码看它基于github.com/urfave/cli/v2组装命令并通过-ldflags注入version、commit、date三个构建期变量main.go。cmd/ — 各类 CLI 命令实现例如servecmd/serve.go、publish、subscribe、user、access、token、webpush等。server/ — 服务端核心逻辑所在包括 server/server.go主服务、server/server.yml服务端配置模板及账号、鉴权、Web Push、Twilio、模板等模块。docs/ — MkDocs 文档源码构建配置见 mkdocs.yml。web/ — React 应用源码依赖与脚本见 web/package.json。构建相关Makefile — 所有构建相关任务的统一入口。.goreleaser.yml — 描述所有构建产物供 GoReleaser 使用。go.mod — Go 模块依赖清单模块名为heckel.io/ntfy/v2Go 版本1.25.8。mkdocs.yml — 文档构建配置site_dir: server/docs即文档产物输出到服务端源码目录以便嵌入。web/package.json — Web 应用的构建与依赖文件npm。其中web/与docs/是 Web 应用和文档的源目录构建过程中生成的产物会被复制到server/siteWeb 应用与落地页和server/docs文档再经go:embed打进二进制。在 Gitpod 中快速开始如果想快速获得一个可用的开发环境可以使用 Gitpod 定义了 Gitpod 环境的初始化配置。当然进行真正的开发时官方建议使用 IntelliJ IDEA 这类完整的 IDE。构建环境要求构建 ntfy 需要以下工具按是否必需区分工具用途必需性Go编译主服务端与客户端必需gccSQLite 的 cgo 绑定需要 C 编译器必需Make便捷构建入口推荐非必需libsqlite3/libsqlite3-devSQLite cgo 绑定的开发头文件必需GoReleaser正式的服务端构建需要make cli系列Python仅构建文档时需要pip可选nodejs仅构建 Web 应用时需要npm可选安装依赖以 Ubuntu 为例以下步骤假设使用Ubuntu不同 Linux 发行版的命令可能有所差异。第一步安装 Go参考 官方安装说明wget https://go.dev/dl/go1.25.8.linux-amd64.tar.gz sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf go1.25.8.linux-amd64.tar.gz export PATH$PATH:/usr/local/go/bin:$HOME/go/bin go version # 验证是否安装成功当前仓库 go.mod 声明的 Go 版本为1.25.8仓库根目录的 .go-version 文件同样固定了该版本make release会校验本地 Go 版本与之一致见 Makefile 的release-checks目标。第二步安装 GoReleaser参考 官方安装说明go install github.com/goreleaser/goreleaserlatest goreleaser -v # 验证是否安装成功第三步安装 nodejs参考 官方安装说明。请使用当前 LTS 版本CI 使用 Node 24 构建由于当前 Web 构建基于 ViteNode 版本低于 20 将无法工作curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - sudo apt-get install -y nodejs npm -v # 验证是否安装成功第四步安装其余依赖sudo apt install \ build-essential \ libsqlite3-dev \ gcc-arm-linux-gnueabi \ gcc-aarch64-linux-gnu \ python3-pip \ git其中gcc-arm-linux-gnueabi与gcc-aarch64-linux-gnu是交叉编译器用于为 armv6/armv7 与 arm64 架构交叉编译对应 Makefile 中cli-deps-gcc-armv6-armv7与cli-deps-gcc-arm64两个依赖检查目标Makefile 中还有build-deps-ubuntu目标可一键安装 Ubuntu 下的大部分构建依赖。拉取源码从官方 GitHub 仓库克隆 ntfy via HTTPSshell git clone https://github.com/binwiederhier/ntfy.git cd ntfy via SSHshell git clone gitgithub.com:binwiederhier/ntfy.git cd ntfy构建一切make 目标总览ntfy 提供了大量make目标。先在仓库根目录直接运行make查看帮助对应 Makefile 中的help目标$ make Typical commands (more see below): make build - Build web app, documentation and server/client (sloowwww) make cli-linux-amd64 - Build server/client binary (amd64, no web app or docs) make install-linux-amd64 - Install ntfy binary to /usr/bin/ntfy (amd64) make web - Build the web app make docs - Build the documentation make check - Run all tests, vetting/formatting checks and linters ...若想构建包含 Web App 与文档、覆盖所有受支持架构amd64、armv7、arm64的 ntfy 二进制直接运行make build$ make build ... # 该命令会依次构建 Web App、文档以及 ntfy 二进制amd64、armv7、arm64 三个架构。 # 首次运行会非常慢在作者的笔记本上耗时 5 分钟以上。可以考虑使用其他更轻量的 make 目标。从 Makefile 可以看到build目标实际是build: web docs cli的组合即「Web 应用 文档 CLI经 GoReleaser」。构建完成后所有产物都在dist/目录下$ find dist dist dist/metadata.json dist/ntfy_arm64_linux_arm64 dist/ntfy_arm64_linux_arm64/ntfy dist/ntfy_armv7_linux_arm_7 dist/ntfy_armv7_linux_arm_7/ntfy dist/ntfy_amd64_linux_amd64 dist/ntfy_amd64_linux_amd64/ntfy dist/config.yaml dist/artifacts.json提示不同 GoReleaser 版本生成的目录命名可能有差异例如 Makefile 中install-linux-amd64目标引用的路径是dist/ntfy_linux_amd64_linux_amd64_v1/ntfy。以实际生成的dist/目录为准。如果你还想构建面向所有受支持架构的 Debian/RPM 软件包和 Docker 镜像使用make release-snapshot目标$ make release-snapshot ... # 这会非常慢在作者的笔记本上有时耗时 5 分钟以上开发期间你可能希望更精细地只构建特定内容详见下文各小节。仅构建 Linux 的 Docker 镜像此方式适合在没有本地依赖的情况下测试包含 Web App、文档与服务端的最终构建产物对应 Makefile 的docker-dev目标构建使用 Dockerfile-build$ make docker-dev $ docker run --rm -p 80:80 binwiederhier/ntfy:dev serve构建 ntfy 二进制不含 Web App 与文档若只需不含 Web App 或文档的ntfy二进制使用make cli-...系列目标。make帮助中列出的相关目标包括$ make Build server client (using GoReleaser, not release version): make cli - Build server client (all architectures) make cli-linux-amd64 - Build server client (Linux, amd64 only) make cli-linux-armv6 - Build server client (Linux, armv6 only) make cli-linux-armv7 - Build server client (Linux, armv7 only) make cli-linux-arm64 - Build server client (Linux, arm64 only) make cli-windows-amd64 - Build client (Windows, amd64 only) make cli-darwin-all - Build client (macOS, arm64amd64 universal binary)因此如果你在 amd64/x86_64 机器上测试阶段通常只需运行make cli-linux-amd64。在现代机器上该命令通常只需 5-10 秒。官方建议将它和install-linux-amd64组合使用以便立即运行二进制$ make cli-linux-amd64 install-linux-amd64 $ ntfy serve除了 GoReleaser 路径Makefile 还提供了不依赖 GoReleaser的手工构建目标cli-linux-server、cli-darwin-server、cli-windows-server、cli-client。它们直接用go build编译例如cli-linux-server使用CGO_ENABLED1 go build并带上sqlite_omit_load_extension,osusergo,netgo等 build tags适合本地开发。开发时直接用 go run开发主应用期间也可以直接使用go run main.go但前提是至少运行过一次make cli-deps-static-sites并设置CGO_ENABLED1$ export CGO_ENABLED1 $ make cli-deps-static-sites $ go run main.go serve 2022/03/18 08:43:55 Listening on :2586[http] ...如果跳过了cli-deps-static-sites可能会看到类似这样的错误$ go run main.go serve server/server.go:85:13: pattern docs: no matching files found这是因为项目使用go:embed嵌入文档与 Web 应用见 server/server.goGo 代码期望server/docs与server/site目录下存在文件。若不存在就会出现上述错误。cli-deps-static-sites目标会创建占位文件touch server/docs/index.html server/site/app.html见 Makefile确保你能正常构建。虽然并未正式支持也未正式发布但服务端也可以在 macOS 上构建和运行运行make cli-darwin-server构建二进制或按上面所述执行go run main.go serve直接运行。构建 Web 应用Web 应用源码位于web/。只要安装了npm见上文构建 Web 应用非常简单——运行make web即可$ make web ...该命令对应 Makefile 的web: web-deps web-build会先安装依赖npm ci然后用 Vite 构建生产产物npm run build并将构建结果复制到server/site目录这样当你执行make cli或make cli-linux-amd64等时Web 应用就会被包含进ntfy二进制中。注意web-build目标中会把index.html改名为app.html并删除config.js因为实际配置由服务端动态生成。如果你正在开发 Web 应用最佳实践是进入web目录手动运行npm start。它会在http://127.0.0.1:3000打开 Web 应用并且每当你编辑源文件浏览器都会自动重新编译并刷新$ cd web $ npm start从 web/package.json 可以看到开发启动脚本为start: NODE_OPTIONS\--enable-source-maps\ vite即直接由 Vite 提供服务。在本地测试 Web Push参考https://stackoverflow.com/questions/34160509/options-for-testing-service-workers-via-http方式一使用开发服务器生成 Web Push 密钥go run main.go webpush keys该命令对应 cmd/webpush.go 中的webpush keys子命令底层调用webpush.GenerateVAPIDKeys()生成 VAPID 密钥对支持通过--output-file参数把密钥写入文件内容为web-push-public-key/web-push-private-key两行配置。启动启用 Web Push 的服务端go run main.go \ --log-level debug \ serve \ --base-url http://localhost \ --web-push-public-key KEY \ --web-push-private-key KEY \ --web-push-email-address email \ --web-push-file/tmp/webpush.db修改 web/public/config.js将base_url设为http://localhost。这是必须的因为 Web Push 只能用于与base_url匹配的服务端。正确设置web_push_public_key。该文件头部注明「仅作示例」构建过程中会被删除实际配置由服务端动态生成并返回给浏览器。开发阶段直接修改此文件即可快速测试。运行npm run start即 Vite 开发服务器。方式二使用已构建的软件包运行make web-build启动服务端同上面方式一的第 2 步打开 http://localhost/Web Push 在服务端配置层面的完整参数web-push-public-key、web-push-private-key、web-push-file、web-push-email-address、过期时间等可参见 server/server.yml 中的 Web Push 配置段。构建文档文档源码位于docs/。与 Web 应用类似直接运行make docs即可构建文档对应 Makefile 的docs: docs-deps docs-build它会创建 Python venv、按 requirements.txt 安装mkdocs-material与mkdocs-minify-plugin再执行mkdocs build$ make docs ...文档构建输出目录由 mkdocs.yml 的site_dir: server/docs指定构建后同样会被嵌入服务端二进制。如果你在修改文档建议直接运行mkdocs serve。它会构建文档、在http://127.0.0.1:8000/提供服务并且每次你保存源文件时自动重新构建$ mkdocs serve INFO - Building documentation... INFO - Cleaning site directory INFO - Documentation built in 5.53 seconds INFO - [16:28:14] Serving on http://127.0.0.1:8000/之后打开 http://127.0.0.1:8000/每当你在编辑器中修改某个 markdown 文件页面都会自动更新。Android 应用开发ntfy Android 应用源码位于独立的 ntfy-android 仓库分为两个 flavor变体Google Playplayflavor包含 Firebase (FCM)需要 Firebase 账户。F-Droidfdroidflavor不包含 Firebase 或任何 Google 依赖。代码导航app/src/main— Android 应用主源码app/src/play— Google Play / Firebase 专属代码app/src/fdroid— F-Droid 的 Firebase 桩stubapp/build.gradle— 主构建文件IDE / 环境建议下载 Android Studio或安装相应 Android 插件的 IntelliJ IDEA。使用其他工具链开发 Android 会比较痛苦。拉取代码先克隆仓库 via HTTPSshell git clone https://github.com/binwiederhier/ntfy-android.git cd ntfy-android via SSHshell git clone gitgithub.com:binwiederhier/ntfy-android.git cd ntfy-android然后按是否使用 Firebase 选择下面的构建方式。构建 F-Droid 变体无 FCM官方提示作者本人使用 IntelliJ IDEAAndroid Studio构建 Android 应用因此不确定下面这些 Gradle 命令能否无碍运行欢迎反馈。如果不使用 Firebase在自托管服务端时你可能仍希望修改app/src/main/res/values/values.xml中的默认app_base_url。然后运行# 构建未签名的 .apk输出到 app/build/outputs/apk/fdroid/*.apk ./gradlew assembleFdroidRelease # 构建 .aab 包输出到 app/fdroid/release/*.aab ./gradlew bundleFdroidReleaseF-Droid 变体会自动排除 Google Services 依赖。构建 Play 变体FCM要构建包含 Firebase 的版本必须创建 Firebase/FCM 账户将账户文件放到app/google-services.json修改app/src/main/res/values/values.xml中的app_base_url然后运行# 构建未签名的 .apk输出到 app/build/outputs/apk/play/release/*.apk ./gradlew assemblePlayRelease # 构建 .aab 包输出到 app/play/release/*.aab ./gradlew bundlePlayReleaseiOS 应用开发构建 iOS 应用相当复杂。以下要求严格基于作者在该应用上的开发经验其他版本的 macOS / XCode 也许也能工作。如遇不一致或问题请反馈。环境要求macOS Monterey 或更高版本XCode 13.2一台实体 iOS 设备推送通知在 XCode 模拟器中无法工作Firebase 也不支持模拟器Firebase 账户Apple Developer 许可作者记不清没有购买许可是否也能进行测试Apple 侧配置注意此步骤与下面的 PLIST 配置 步骤都是必需的二者配合才能让改动在 iOS 应用中生效。在 Apple Developer Member Center 创建一个新密钥选择 Apple Push Notifications service (APNs)下载新创建的密钥文件名形如AuthKey_ZZZZZZ.p8其中ZZZZZZ就是Key ID记下你的Team ID—— 它显示在页面右上角或通过 Account Membership 页面查看然后在 Firebase 控制台进入你的项目 Project Settings选择已创建的 iOS 应用点击左侧边栏的 Cloud Messaging滚动到 APNs Authentication Key 区域点击 Upload Key上传你从 Apple Developer 下载的密钥警告如果不完成上述 APNS 配置通知将无法即时送达甚至有时完全收不到。这是因为缺少 APNs 密钥——它是 Firebase 向 iOS 应用发送通知所必需的。即便没有 APNs 认证密钥你仍然可以向 iOS 设备发送通知但它们不会被即时送达而是等到设备唤醒检查新通知、或应用发送 Firebase 请求去检查时才会送达。检查间隔从几秒到几小时、几天甚至几周不等。启用 APNs 认证密钥可确保通知即时送达强烈建议启用。Firebase 侧配置如果没有先创建 Google / Firebase 账户访问 Firebase 控制台创建新的 Firebase 项目输入项目名禁用 Google Analytics当前 iOS 应用不支持分析在 Project settings 页面添加 iOS 应用Apple bundle ID 填com.copephobia.ntfy-ios可以改成与 XCode 中 ntfy.sh target Bundle Identifier 的值一致注册应用下载配置文件 GoogleInfo.plist需要放进 ntfy-ios 仓库 / XCode为 ntfy 服务端生成服务账户私钥进入 Project settings Service accounts点击 Generate new private key 生成并下载私钥用于通过 ntfy 服务端发送消息ntfy 服务端配置注意ntfy 服务端官方并不支持 macOS但理论上可按下述步骤在 macOS 上运行若尚未创建创建/etc/ntfy/目录并把服务账户私钥移入该目录把 ntfy 仓库中的 server/server.yml 复制到/etc/ntfy/修改/etc/ntfy/server.yml中的firebase-key-file值指向私钥路径安装 Gobrew install go在 ntfy 仓库中运行make cli-darwin-serverXCode 配置按照 Add Firebase to your Apple project 的第 4 步在 XCode 中安装firebase-ios-sdk如果尚未安装——除 Firebase Core / Firebase Messaging 外其他包可按需选择同样在 XCode 中安装 SQLite.swift 包依赖运行 debug 构建时确保 XCode 指向已连接的 iOS 设备——在 iOS 模拟器中无法注册推送通知PLIST 配置要使用 Firebase 获得即时通知/更好的通知送达效果需要把GoogleService-Info.plist文件加入项目步骤如下在 XCode 中找到 NTFY 应用 target注意不是NSE 应用 target在项目导航器中找到 Asset/ 文件夹把从 Firebase 控制台获取的GoogleService-Info.plist文件拖入 Asset/ 文件夹该文件可在 Project settings General Your apps 中找到旁边有标着 GoogleService-Info.plist 的按钮完成以上步骤后iOS 应用的开发配置就绪。开发流程小结与质量检查对于服务端开发推荐的日常循环是首次克隆后先执行make cli-deps-static-sites生成嵌入用占位文件并设置export CGO_ENABLED1用go run main.go serve快速起服务或make cli-linux-amd64 install-linux-amd64得到可安装的二进制改动 Web 前端时进入web/用npm start启动热更新开发服务器改动文档时用mkdocs serve实时预览提交前运行make checkMakefile 定义执行全部测试、go fmt/vet、eslint、prettier、golint 与 staticcheck 等检查或make testGo 测试 Web 测试、make race带竞态检测的 Go 测试。需要了解服务端完整配置项数据库、缓存、鉴权、限流、附件、Web Push、Twilio、Stripe、日志等时可随时查阅 server/server.yml 这个带详尽注释的官方配置模板CLI 与服务端参数解析则分布在 cmd/ 各命令文件中。如果在任何一步遇到问题可以通过 docs/contact.md 中列出的渠道联系社区获取帮助。欢迎为 ntfy 贡献代码。【免费下载链接】ntfySend push notifications to your phone or desktop using PUT/POST项目地址: https://gitcode.com/GitHub_Trending/nt/ntfy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表