月份彙整: 2025 年 10 月

Stalwart 開源郵件伺服器即將發佈 1.0 版本,成為第一個實作 JMAP 協議的郵件伺服器

雖然現在已經很少人自架郵件伺服器了,但是一款開源的郵件伺服器軟體 Stalwart 完成了 JMAP 的實作!這篇文章介紹了 Stalwart Labs 一個重大里程碑:完成 JMAP 用於行事曆、聯絡人、地址簿、檔案儲存及分享的完整實作,使 Stalwart 成為首個支援完整 JMAP 協作協議的郵件伺服器。

完整的文章內容: https://stalw.art/blog/jmap-collaboration

  • 新一代協議:JMAP 包括用於行事曆、聯絡人、檔案儲存及分享的新協議,目標取代傳統的 WebDAV 技術如 CalDAV 和 CardDAV,並引入 JSCalendar 和 JSContact 作為 iCalendar 和 vCard 的繼承者。這些新標準提供一致且優雅的生態系統。
  • 舊技術的限制:傳統的 WebDAV 及其延伸技術因 XML 設計的複雜性,導致實施困難且互通性差。iCalendar 和 vCard 的技術負擔也使這些格式難以維護。
  • JMAP 的現代解決方案:JMAP 協議以 JSON 為基礎,透過 HTTPS 提供高效且清晰的 API,用於郵件、行事曆、聯絡人及檔案分享,簡化協作技術實作,提升可讀性與解析效率。這次發佈不僅帶來新功能,更改變了群件協議的設計和實作方式,對開發者和組織而言意味著更簡單、更少的互通性問題,並加速創新。
  • 客戶端支援與生態系統:目前已有幾個專案(如 Mailtemi、Parula 和 OpenCloud)在開發 JMAP 的客戶端實作,預期 JMAP 會快速被採用。
  • 感謝及未來展望:感謝 NLNet 對 JMAP 開發的支持。Stalwart 開發團隊將致力於性能優化和增強功能,目標在未來幾個月內推出正式的 1.0.0 版本,樹立開放且現代化的郵件通信伺服器新標準。

前幾個月有把 Stalwart 架起來,很難想像在此刻架一台郵件伺服器能有多難,但再往前跨一步出去後發現,很多雲端服務如 AWSDigitalOcean 將 25, 465, 587 連線埠給關閉或不提供 IP 反向解析1(PTR/RDNS),即使架好了也無法與其他郵件伺服器溝通,或許當越來越多人使用 Stalwart 後這個問題有可能會被克服,我很期待可以自己架設郵件伺服器!


  1. 設定 IP 反向解析(PTR/RDNS)有助於驗證發信伺服器的真實身份,提高郵件的可信度並減少被標記為垃圾郵件的風險,確保郵件順利地送達收件者的主要信箱,提升整體郵件的可交付性。 ↩︎

開源自架服務 immich 被 Google 安全瀏覽誤判為「危險」網站

Google 提供一項名為「安全瀏覽(Google Safe Browsing)」的服務,用來檢測網站是否存在惡意軟體、不受歡迎的軟體或從事某種社交工程行為。不過,對於如何判斷網站是否「危險」的細節仍然不太清楚。這導致使用 Google 安全瀏覽服務的瀏覽器(如 Chrome 和 Firefox)會自動警告使用者,除非少數人忽視這樣的警告,否則這些網站幾乎無法被訪問。

而近期一款開源自架的照片、影片管理軟體 immich,因為自家的 Demo 網站被標記為危險,影響到整個網域的使用。immich 解釋如何透過 Google 的申訴管道提出恢復,但恢復之後所產生的頁面也再次被標記危險。結論提到目前像是可自架服務的 NextCloud、n8n、Jellyfin …… 等,都會有這樣發生的可能,對於開源、自架環境是一個潛在的阻礙

有興趣可以閱讀完整內容:https://immich.app/blog/google-flags-immich-as-dangerous


查了一下 Google Safe Browsing 沒有公開名單讓人查閱哪些網站被放入,只有一個查詢的網站可以使用,雖然我自己不是用 Chrome,但其他使用者以目前 Chrome 的市占率,其影響不容小覷。

這樣的審查模式與臺灣之前討論 RPZ 類似,一樣也是不公佈名單,但 Google 比較麻煩的部分是評判標準不明,然後又常常誤判,申訴後也不知道何時可以恢復,如果真的遇到誤判,還真的不知道該如何面對。

之前作過一個內部系統,也是遇到這樣的問題,想說臨時換一個網域應該可以解決,但又馬上被判定「危險」,最後只能請使用者關閉「安全瀏覽」檢查的功能,還好不是面對外部的使用者,可以這樣一一通知暫時解法使用。

Signal 服務中斷,僅 AWS 一個資料區域故障

10/20 15:11(UTC+8),AWS 在 N. Virginia(us-east-1)的資料中心的 DynamoDB 服務無法連線,導致該區許多與 DynamoDB 相關連的服務無法使用。Snapchat、Slack、Perplexity、Canva …… 等一些網路服務因此也受到影響,其中 Signal 也因為這個事件而無法使用。

比較讓我意外的是 Signal 沒有其他區域的備援系統,而第一時間也沒有看到官方提出任何公告目前的狀況如何,最後只能到 reddit 上看看有沒有人提到是什麼狀況。才確認是 AWS 的問題,而僅是一個資料中心的問題。

覺得 Signal 在這次事件後應該要好好思考一下服務韌性的問題,Signal 的使用者可能都有其服務在線 100% 的需求,臨時要找一個替代的服務可能還沒辦法那麼快找到。或許要重新思考去中心化的通訊服務如:Matrix,既能達成端到端加密,也能達成服務的可靠性(也不太一定)。

之前,大家會把 Signal 當作注重隱私、安全的替代品,現在是不是要開始幫 Signal 找他的替代品了?

mkdocs-material on Github Actions

Material for MkDocs 網站截圖
Material for MkDocs 是一個專為 MkDocs 設計的主題,都用來生成美觀且易於瀏覽的靜態文件網站。它結合了現代設計美學和豐富的功能,使得技術文檔不僅易於閱讀,還能夠輕鬆地進行導航和查找內容。這個主題提供了多種自訂選項,支援多語言以及進階搜尋功能,讓使用者能夠快速建立專業級的文件網站。對於開發人員和技術作家來說,Material for MkDocs 不僅提升了文件的可讀性,還大大簡化了文件的維護和展示工作。

滿喜歡用 Material for MkDocs 來產生文件網站,嚴格來說,這是一個建構在 MkDocs 之上的一個樣式套件,只是又加入了滿多設計樣式,相對於原始 MkDocs 來說在文件閱讀排版上更清晰。

以前常用 Sphinxrst 格式的純文字內容,後來 Markdown 成為主流,延伸出許多靜態網頁套件或是對應 Markdown 轉換其他文件格式的應用。我記得我是在使用 FastAPIPydantic 的技術文件注意到為什麼有一套很美的文件產生樣板,使用後就決定採用在當時做的專案,建構文件資訊給予其他貢獻者參與、閱讀。

以往所建立 Material for MkDocs 的文件專案,大部分都會將建立好的靜態網頁上傳到 AWS S3 存放,直接透過 AWS S3 的網站設定或是透過 nginx 路徑轉址合併到原有的網站中(如:/docs)。反而發現從來沒嘗試過直接用 Github Pages 來建立 Material for MkDocs 文件專案。

在 Github Actions 中有三種方式可以實現 Github Pages 的發佈,可以參考這份 yaml 檔案的描述。這裡用的套件管理是 uv。

MkDocs 有整合 Github Pages 的發佈,可以透過 mkdocs gh-deploy 來佈署,直接一行指令就可以完成。

- name: Build MkDocs
  run: |
      uv run mkdocs gh-deploy -b gh-pages -d ./docs

直接將產生出來的靜態檔案 ./docs 內的檔案上傳到 gh-pages 分支的頂層位置。

第二種方式是每次都從 main 建立一個新的分支 gh-pages 然後產生靜態文件後,強迫上傳覆蓋遠端原有的 gh-pages,這樣的方式是只會看到最新的文件提交紀錄。

- name: Build MkDocs
  run: |
      uv run mkdocs build -d ./docs
      git checkout -b gh-pages main
      git add -f ./docs
      git commit -m 'Deploy MkDocs to GitHub Pages'
      git push -f origin gh-pages

第三種方式是用 worktree 的方式將 gh-pages 建立在 ./docs,然後把靜態文件產生到 ./docs 中完成提交與推送。

- name: Build Mkdocs
  run: |
      git worktree add ./docs gh-pages
      rm -rf ./docs/*
      uv run mkdocs build -v -d ./docs
      cd ./docs
      if [ -n "$(git status --porcelain)" ]; then
        git add .
        git commit -a -m 'Deploy on ${{ github.ref_name }} ${{ github.sha }}'
        git push origin HEAD
      else
        echo "No changes to commit."
      fi

歷史紀錄

如果有使用 mkdocs-git-revision-date-localized-plugin 套件,應該會發現每次產生出來的文件建立日期與修改日期都會是一樣的,那是因為 Github Actions 在使用 actions/checkout 的時候不會擷取過往的 git 歷史提交,需要指定參數來提示擷取完整的 git 紀錄。

- uses: actions/checkout@v5
  with:
      fetch-depth: 0

以上,透過三種方式來建立 Material for MkDocs 靜態文件,看起來多行的指令是可以保留一些彈性操作的可能,例如在最後更換 og 預覽圖,當使用免費版本,都只能呈現預設的樣式。

Material for MkDocs 是一個很好快速建立靜態文件或是針對專案類型的說明網站,建立在 Github Pages 上也不用擔心主機安全性或流量問題,覺得這是一個值得投入瞭解與應用的靜態文件套件!

轉折點

最近大概遇到一個我覺得可以代表我自己的「轉折點」事件,算是投入 10 多年的認知被顛覆。

先說結論好了,最後我自己決定直接跳脫、離開這樣的領域,有些人或環境雖然看起來都建立很久的聯繫,但立場與所認知的目標差距越來越遠了,可能就不需要再維護這樣的夥伴關係。

我不懂的事情是、還是有很多人很眷戀「頭銜」這件事情,這其實對我來說是一件非常尷尬的情況,當我在發現你是在建立很多「履歷」或是「發起人」、「頭銜」時,這一類型的人我會避而遠之。因為和這一類型的人講話會感覺到非常的空,沒有一個發自內心的遠大目標,只是針對你說的領域隨意附和而已。

當然還有一些人是深怕自己作過什麼大事而別人不知道似的,一直幫別人前情提要或補充敘述,和這些人溝通會非常的累,有得時候會覺得你其實在浪費大家的時間。

曾經為了證實我的假設,刻意花了多年的時間在找夥伴時設定一些觀察指標,以後來的成效是顯著卓越的,只要避開上述所提及類型的人與他們所衍生的團體,其實就可以找到「值得信賴」與「放心託付」的夥伴。

接下來我必須徹底遠離這個已經走偏的「生態系」,可能這 10 年來的假象會在未來的 1 – 2 年浮現出來,我選擇從外圍的方式來參與,重新建立我所認為的樣態與倡議的方式,說真的,我還以為建立一個「社群」會有多困難,當這件事情走了一遍之後,你會開始懷疑有些「組織」的存在是不是只是為了一個狹隘的目標(說不定也只是一個頭銜)而已。

可能吧,說不定,也可能我說錯了。