面向讀者的網站
apps/web-storefront讀者造訪的網站,以出版社自己的品牌對外發布。包括瀏覽、搜尋、排行榜、追蹤、登入,以及翻頁閱讀的閱讀器。
Publira 是一套多租戶 SaaS,讓 IT 資源有限的出版社也能以自有品牌經營漫畫數位發行平台。編輯輸入從作者那裡收到的作品資訊,讀者在網頁或行動裝置上閱讀。
仍在開發中
Publira 仍在積極開發中,最新版本 v0.3.2 也尚不適合用於正式環境。本頁介紹的功能目前都能運作,也可以用每個版本發布的映像檔和一個 Compose 檔案完成部署;但若要實際提供給出版社使用,仍需閱讀程式碼、依自己的環境調整,並跟進每個 0.x 次要版本可能帶來的變更。請把它視為可供評估、二次開發和參與貢獻的專案,而不是成品。

Publira 本身是一個平台。開發過程中做出的部分元件已拆分為獨立的函式庫並公開發布,不必引入平台的其餘部分就能使用。
出版社可以得到面向讀者的網站和應用程式,以及供編輯使用的主控台;負責營運部署的人員另有一個統管全局的平台主控台。
每家出版社都以自己的品牌和網域經營。平台主控台 (未執行它的部署則使用 publiractl) 在此之上統一管理各租戶、租戶的讀者,以及整個部署共用的設定。
作品、頁面和公告都在同一個主控台中編輯,所有待發布的內容都集中在一個佇列裡。讀者的諮詢也在這裡回覆,每位工作人員只會看到其角色有權使用的操作。
顏色、字體、標誌和圖示可以一邊編輯一邊在即時預覽中確認,預覽與公開網站使用同一套元件建構。儲存之前,網站會繼續使用目前的主題。
租戶在網頁上透過 Stripe 或 PAY.JP 販售章節,在應用程式中透過 App Store 和 Google Play 販售。購買不會在頁面重新導向時記錄,而是在收到金流服務的簽章通知後才記錄,讀者隨後會收到電子收據。工作人員可以在主控台為網頁上的購買辦理退款;全額退款或發生爭議時,該章節會恢復為未購買狀態。
付費章節可以在免費閱讀期間向所有讀者開放。免費閱讀期間可以設定在單一章節上,也可以為系列的多個章節一次設定。系列還可以提供「等待即可免費」:已登入的讀者使用等待一段時間後恢復的免費券,每次免費閱讀一話付費章節。
讀者可以用電子郵件地址、網站和應用程式通用的通行金鑰,或各租戶設定的 Apple 和 Google 憑證登入網站和應用程式。租戶的工作人員和平台營運人員可以開啟兩步驟驗證 (工作人員也可以用通行金鑰完成驗證),平台還可以要求所有租戶管理員和營運人員都必須開啟。
系列可以設為只在網站或只在應用程式中顯示,章節還能進一步限定;伺服器會依發出請求的一端傳回相應的作品資料。章節的販售位置也以同樣的方式設定,從租戶預設值一路細分到單一章節。
每位署名作者都依一定比例分得章節的銷售額。每個月可以手動結算,也可以在租戶選定的日期自動結算並產生版稅明細,已結算的明細可以下載為 CSV。連結了讀者帳號的作者不必購買就能閱讀自己的章節,但不能為其評分。
R15 和 R18 作品在所有列表中都會標示,在讀者確認之前保持隱藏,並依帳號中儲存的出生日期、按各租戶選擇的驗證規則限制存取。這些作品另有獨立的排行榜,只有有權觀看的讀者才能開啟。
三個 Next.js 應用程式、一個 Flutter 用戶端以及它們寄出的郵件,各自面向不同的使用者。
讀者造訪的網站,以出版社自己的品牌對外發布。包括瀏覽、搜尋、排行榜、追蹤、登入,以及翻頁閱讀的閱讀器。
編輯的工作台:作品目錄和發布佇列、金流和登入服務、公開網站的主題和頁面、讀者的諮詢、讀者的購買與退款、應支付給每位作者的款項,以及對上述所有內容的變更記錄。
位於各租戶之上,供營運部署的人員使用:部署尚需完成的設定、租戶狀態、跨租戶事件、所有租戶的讀者,以及從物件儲存到安全性政策等所有租戶共用的設定。
在手機上瀏覽同一份作品目錄,用一套 Flutter 程式碼同時支援 Android 和 iOS,並使用租戶自己的名稱和主題。應用程式直接呼叫公開 API,不經過網站;讀者可以用電子郵件地址、通行金鑰、Apple 或 Google 登入,透過應用程式商店或網站結帳購買章節,開啟過或儲存過的章節會保留在裝置上。
帳號相關郵件和工作人員收到的通知,由獨立的轉譯器根據 React 元件產生 HTML,並附上純文字版本一起寄出。寄給租戶讀者和工作人員的郵件使用租戶名稱而不是 Publira,並以租戶的語言撰寫;日文、韓文和中文裡不同文字之間的間距,與網站一樣交由郵件用戶端的文字排版處理。
前端是 Next.js,後端是透過 Connect RPC 提供服務的 Go 伺服器及搭配的 worker,再往下都是你現在就能執行的常見元件。
一個 publira server 處理程序承載公開、管理和平台三個命名空間,並為讀者端和主控台兩個來源傳送圖片。也可以用 --role storefront 再啟動一個處理程序,只讓它承接租戶的網域,並且只持有面向讀者的資料庫登入憑證。同一個執行檔提供的 publira worker 負責寄送郵件和推播通知,並執行所有排程作業:發布到期的章節、處理免費期間的開始和結束、為每個租戶切換日曆日、重建排行榜、結算版稅月份,以及清除超過保留期限的資料。部署所需的排程只靠它就夠了;在單台主機上,也可以用 publira server --with-worker 將兩者合併為一個處理程序執行。選用的 email-renderer 負責產生每封郵件的 HTML 部分,publiractl 負責資料庫遷移、建立資料庫角色和部署的初始設定,也可以手動執行 worker 的任何作業。
每一層都整合了 OpenTelemetry,一次瀏覽器請求就是一條完整的追蹤:Next.js 的根 span、SSR 期間發出的 Connect RPC、Go 端同名的 span,以及其下的 db.query 子 span。可以接到你現有的任何 collector,也可以不啟用追蹤 (預設為關閉)。兩個 Go 處理程序還會匯出 OpenTelemetry 指標,同樣需要啟用後才會匯出。
| 相依項目 | 用途 |
|---|---|
| 反向代理必要 | 將各租戶的主機名稱導向對應的網站和主控台,並將公開 API 和圖片請求導向伺服器。儲存庫附有 Traefik、nginx 和 Caddy 的設定。 |
| PostgreSQL必要 | 作品目錄、租戶、使用者、購買記錄和稽核記錄。每台伺服器以各自的角色連線。 |
| Redis 相容快取必要 | Next.js 的共享快取,讓同一個部署可以在負載平衡器後方執行多個執行個體。 |
| S3 相容物件儲存必要 | 章節頁面、封面圖和其他上傳內容。儲存貯體作為部署設定保存,而不是寫在各處理程序的環境變數中。 |
| SMTP 中繼必要 | 帳號相關郵件、通知以及工作人員收到的通知,可分別依平台和租戶設定。 |
| OpenSearch 或 Elasticsearch選用 | 供需要依相關度排序作品搜尋結果的部署使用,每個節點都需要安裝 analysis-kuromoji 和 analysis-icu 外掛程式。不使用時,搜尋由 PostgreSQL 處理。 |
| 金流服務選用 | 僅販售付費章節時需要,每個租戶一個帳號:網頁使用 Stripe 或 PAY.JP,應用程式使用 App Store 和 Google Play。購買以金流服務傳來的簽章通知為準。 |
| 郵件接收服務選用 | 僅在租戶希望將讀者對回覆的回信記錄到主控台中對應的諮詢下方時需要。每個租戶可使用 SendGrid、Resend、Mailgun、Amazon SES,或能透過 HTTPS 轉送所收郵件的郵件伺服器。 |
| Firebase 專案選用 | 每個租戶應用程式一個。發往行動應用程式的推播通知透過 Firebase Cloud Messaging 傳送,iOS 的通知再由其轉送至 APNs。 |
| OpenTelemetry collector選用 | 接收 Next.js 應用程式和 Go 伺服器的追蹤,以及 Go 伺服器的指標;預設關閉。 |
部署以容器映像檔和一個 Compose 檔案執行,publiractl 負責完成資料庫和第一個租戶的初始化。主機只需安裝 Docker。
PUBLIRA_VERSION=0.3.2
curl -fsSLO \
https://github.com/publira/publira/releases/download/v$PUBLIRA_VERSION/publira-deploy-$PUBLIRA_VERSION.tar.gz
tar -xzf publira-deploy-$PUBLIRA_VERSION.tar.gz
cd publira-deploy-$PUBLIRA_VERSION
# Write .env from .env.example, with every secret generated
docker run --rm --user "$(id -u):$(id -g)" -v "$PWD":/work -w /work \
ghcr.io/publira/publiractl:$PUBLIRA_VERSION env generate封存檔中包含該版本的 Compose 檔案、代理使用的 Caddyfile 和 .env.example。publiractl env generate 會據此產生 .env,並自動產生所有密鑰。
每個版本都會以版本號為標籤,將 linux/amd64 和 linux/arm64 映像檔發布到 GitHub Container Registry,例如 ghcr.io/publira/publiractl:0.3.2。下載映像檔不需登入,因此主機上不必建置任何東西。
.env 中的 PUBLIRA_IMAGE_TAG 已設為該版本號,請勿修改。映像檔必須與 .env 所在目錄中的檔案來自同一版本:publiractl 包含該版本的資料庫遷移,各處理程序依賴該版本的資料庫結構,代理則依封存檔中 Caddyfile 的路由運作。
如果修改了程式碼或在其他平台上執行,請從儲存庫取得原始碼自行建置映像檔,並改為指定這些映像檔。